AstroBaaS

Content & editorial

Image Lazy-Loading

Free — GPL coresize Splanned, not built

Generated from docs/plan/core/image-lazy-loading/PLAN.md in the AstroBaaS repository. Nothing described below is implemented — it is the written plan for it.

Image Lazy-Loading defers loading off-screen images until they scroll into view. Product pages load only visible images; as users scroll, images load on-demand. This is core GPL functionality: performance infrastructure, honest lazy-load implementation, no per-country obligation.

The problem

Merchants’ pages load off-screen images unnecessarily; bandwidth wastes and checkout performance suffers. Pages with 20+ product images load all images at page load, wasting data for users who scroll halfway and abandon. Lazy-load improves Core Web Vitals (LCP, CLS) and checkout speed dramatically.

What it does

  • Lazy-load attribute: mark images with loading=‘lazy’ (native browser support)
  • Intersection Observer fallback: for older browsers, use JS to defer off-screen image loading
  • Placeholder: show low-res placeholder or blur-up effect while loading
  • Track metric: measure LCP (Largest Contentful Paint) to show lazy-load impact
  • Responsive images: lazy-load srcset variants only when needed
  • CSS background images: defer loading of CSS background-image until visible (via JS)

What it deliberately does NOT do

Each boundary carries its reason. A boundary without a reason gets crossed by the next person who reads this.

  • Lazy-load for all assets (CSS, fonts, scripts) — scope is images only; other assets are separate
  • Smart preload (anticipate scroll, preload next image) — scope is on-demand loading only; prediction is separate

Data model

No new schema; existing asset/image model extended with lazy_load flag (default true).

API

  • No API changes; lazy-load is rendering behavior, not data

Every route added here must also appear in src/pages/openapi.json.ts — a test fails the build if it does not.

Admin

Collection settings: Image settings shows checkbox ‘Enable lazy-load’ (default on). Analytics dashboard shows LCP metric before/after enabling lazy-load.

The seam — why this is core

Core owns: lazy-load implementation (HTML attribute, Intersection Observer polyfill). Storefront (Next.js) renders with lazy-load attributes.

Core owns the interface + honest lazy-load implementation; image loading is infrastructure, not a per-country obligation or credential.

Dependencies

  • image-optimization (lazy-load works with optimized image variants)

Acceptance checks

Each of these must be able to fail. Before claiming this is done, break the code deliberately and watch each one go red.

  • Product page with 20 images loads only first 3 visible images (LCP ~1.2s)
  • Scroll down: image 4 loads when scrolled 50% into view
  • LCP metric improves 30%+ after enabling lazy-load
  • Older browser without native lazy-load support: Intersection Observer polyfill enables lazy-load in JS

Risks

Incorrect LCP calculation (image marked as lazy is actually in viewport); breaks Core Web Vitals metrics. CLS (Cumulative Layout Shift) if lazy-load placeholder not sized correctly. Scroll performance impact if Intersection Observer fired too frequently; must throttle.

Commercial context

Suggested pricefree (core)
Rival anchorShopify: included; Magento: included

The anchor is what the nearest equivalent charges on Shopify or Magento today. It is context for a pricing decision, not the decision.


Generated from the commerce plan. See docs/COMMERCE-PLAN.md for the full catalogue and ../../AI-GUIDE.md for how to work on this repository.