feat: add product image download pipeline for PageSpeed 100%

Downloads Printify CDN images via ImageDownloadWorker, processes
through Media pipeline (WebP conversion, AVIF/WebP variant generation),
and links to ProductImage via new image_id FK.

- Add image_id to product_images table
- ImageDownloadWorker downloads and processes external images
- sync_product_images preserves image_id when URL unchanged
- PreviewData uses local images for responsive <picture> elements
- VariantCache enqueues pending downloads on startup
- mix simpleshop.download_images backfill task

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
jamey
2026-02-01 00:26:19 +00:00
parent c818d0399c
commit 1b49b470f2
12 changed files with 381 additions and 33 deletions

View File

@@ -34,13 +34,11 @@ defmodule SimpleshopThemeWeb.ShopLive.ProductShow do
|> Enum.reject(fn p -> p.id == product.id end)
|> Enum.take(4)
# Build gallery images (filter out nils)
# Build gallery images from local image_id or external URL
gallery_images =
[
product.image_url,
product.hover_image_url,
product.image_url,
product.hover_image_url
image_src(product[:image_id], product[:image_url]),
image_src(product[:hover_image_id], product[:hover_image_url])
]
|> Enum.reject(&is_nil/1)
@@ -70,6 +68,14 @@ defmodule SimpleshopThemeWeb.ShopLive.ProductShow do
List.first(products)
end
# Build image source URL - prefer local image_id, fall back to external URL
defp image_src(image_id, _url) when is_binary(image_id) do
"/images/#{image_id}/variant/1200.webp"
end
defp image_src(_, url) when is_binary(url), do: url
defp image_src(_, _), do: nil
@impl true
def render(assigns) do
~H"""