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:
@@ -185,7 +185,11 @@ defmodule SimpleshopTheme.Theme.PreviewData do
|
||||
end
|
||||
|
||||
defp get_real_products do
|
||||
Products.list_products(visible: true, status: "active", preload: [:images, :variants])
|
||||
Products.list_products(
|
||||
visible: true,
|
||||
status: "active",
|
||||
preload: [images: :image, variants: []]
|
||||
)
|
||||
|> Enum.map(&product_to_map/1)
|
||||
end
|
||||
|
||||
@@ -228,16 +232,22 @@ defmodule SimpleshopTheme.Theme.PreviewData do
|
||||
in_stock = Enum.any?(available_variants)
|
||||
on_sale = Enum.any?(product.variants, &SimpleshopTheme.Products.ProductVariant.on_sale?/1)
|
||||
|
||||
# Use local image if available, fall back to CDN URL
|
||||
{image_url, image_id, source_width} = image_attrs(first_image)
|
||||
{hover_image_url, hover_image_id, hover_source_width} = image_attrs(second_image)
|
||||
|
||||
%{
|
||||
id: product.slug,
|
||||
name: product.title,
|
||||
description: product.description,
|
||||
price: if(cheapest_variant, do: cheapest_variant.price, else: 0),
|
||||
compare_at_price: if(cheapest_variant, do: cheapest_variant.compare_at_price, else: nil),
|
||||
image_url: if(first_image, do: first_image.src, else: nil),
|
||||
hover_image_url: if(second_image, do: second_image.src, else: nil),
|
||||
source_width: nil,
|
||||
hover_source_width: nil,
|
||||
image_url: image_url,
|
||||
image_id: image_id,
|
||||
hover_image_url: hover_image_url,
|
||||
hover_image_id: hover_image_id,
|
||||
source_width: source_width,
|
||||
hover_source_width: hover_source_width,
|
||||
category: product.category,
|
||||
slug: product.slug,
|
||||
in_stock: in_stock,
|
||||
@@ -246,6 +256,20 @@ defmodule SimpleshopTheme.Theme.PreviewData do
|
||||
}
|
||||
end
|
||||
|
||||
# Extract image attributes, preferring local Media.Image when available
|
||||
defp image_attrs(nil), do: {nil, nil, nil}
|
||||
|
||||
defp image_attrs(%{image_id: image_id, image: %{source_width: source_width}})
|
||||
when not is_nil(image_id) do
|
||||
# Local image available - use image_id for responsive <picture> element
|
||||
{nil, image_id, source_width}
|
||||
end
|
||||
|
||||
defp image_attrs(%{src: src}) do
|
||||
# Fall back to CDN URL
|
||||
{src, nil, nil}
|
||||
end
|
||||
|
||||
# Default source width for mockup variants (max generated size)
|
||||
@mockup_source_width 1200
|
||||
|
||||
|
||||
Reference in New Issue
Block a user