Files
astro-website/openspec/changes/archive/2026-02-10-lazy-loading/proposal.md
Santhosh Janardhanan ac3de3e142
Some checks failed
ci / site (push) Has been cancelled
publish-image / publish (push) Has been cancelled
lazy-loading done
2026-02-10 15:59:03 -05:00

2.2 KiB

Why

All images on the site use loading="lazy" but render as blank space until the browser finishes downloading them. On slower connections or pages with many cards (homepage has 20+ cards), the user sees empty grey rectangles that pop into view abruptly. Adding a shimmer/skeleton placeholder while images load gives the perception of a faster, more polished page — the same pattern used by LinkedIn, YouTube, and AMP pages.

What Changes

  • Shimmer placeholder for card thumbnails. The .card-media area displays an animated skeleton shimmer while the <img> is loading. Once the image loads, it fades in over the shimmer. If the image fails to load, the placeholder remains visible (graceful degradation).
  • Shimmer placeholder for blog featured images. Blog post and page detail pages show the same shimmer treatment on the hero/featured image while it loads.
  • Reduced-motion support. The shimmer animation is suppressed when prefers-reduced-motion: reduce is active — the placeholder shows as a static block instead of animating.

Capabilities

New Capabilities

  • image-lazy-loading: Shimmer/skeleton placeholder system for images that displays an animated loading state while images download, fades in the image on load, and handles load failures gracefully.

Modified Capabilities

  • card-layout-system: Card image area gains shimmer placeholder behavior during image loading (visual enhancement, no layout changes).

Impact

  • Components: StandardCard.astro — the <img> element needs a wrapper or sibling element for the shimmer, plus a script to detect load/error events.
  • Pages: blog/post/[slug].astro, blog/page/[slug].astro — featured images get the same shimmer treatment.
  • CSS: global.css — new shimmer animation keyframes and placeholder styles.
  • JS: Small inline script to listen for image load/error events and toggle visibility classes.
  • No backend changes. No data model, ingestion, or caching changes.
  • No new dependencies. Pure CSS animation + vanilla JS event listeners.
  • Accessibility: Shimmer respects prefers-reduced-motion (existing global rule covers animation suppression). No content or semantic changes.