skill:responsive-images - Performant Responsive Images
Version: 1.0.0
Purpose
Implement performant responsive images that load the right size and format for every device. This skill covers srcset /sizes attributes, modern formats (WebP, AVIF), lazy loading, CLS prevention with aspect-ratio , the <picture> element for art direction, fetchpriority for LCP images, and framework-specific image components (Next.js Image , Astro Image ). Use when adding images to any web project, optimizing existing images for performance, or fixing Core Web Vitals (CLS, LCP) issues related to images.
File Structure
skills/responsive-images/ ├── SKILL.md (this file) └── examples.md
Interface References
-
Context: Loaded via ContextProvider Interface
-
Memory: Accessed via MemoryStore Interface
-
Shared Patterns: Shared Loading Patterns
-
Schemas: Validated against context_metadata.schema.json and memory_entry.schema.json
Image Optimization Focus Areas
-
Resolution Switching: srcset with width descriptors (w ) and sizes attribute for viewport-based selection
-
Format Selection: <picture> with <source> for AVIF → WebP → JPEG/PNG fallback chain
-
Art Direction: <picture> with media queries for different crops at different breakpoints
-
Lazy Loading: loading="lazy" for below-fold images, loading="eager" for LCP images
-
Fetch Priority: fetchpriority="high" on LCP image, fetchpriority="low" on non-critical
-
CLS Prevention: Explicit width /height or aspect-ratio CSS to reserve space before load
-
Decoding: decoding="async" for non-critical images to avoid blocking main thread
-
Framework Components: next/image , Astro <Image> , Nuxt <NuxtImg> — automatic optimization
Common Pitfalls Prevented
-
Missing width and height attributes causing CLS (Cumulative Layout Shift)
-
Using loading="lazy" on the LCP (Largest Contentful Paint) image — slows it down
-
srcset without sizes — browser defaults to 100vw , downloading oversized images
-
sizes="100vw" on images that are never full-width (sidebar images, cards)
-
Missing AVIF/WebP sources — serving large JPEG/PNG to modern browsers
-
fetchpriority="high" on too many images — defeats the purpose
-
Lazy loading images that are in the initial viewport
-
Missing alt text on informational images (accessibility violation)
-
Using CSS background-image for content images (not accessible, not optimizable)
-
Serving retina images to non-retina screens (wasted bandwidth)
MANDATORY WORKFLOW (MUST FOLLOW EXACTLY)
Step 1: Initial Analysis
YOU MUST:
-
Identify the image context:
-
Hero/banner images (LCP candidates)
-
Content images (articles, products)
-
Thumbnails/avatars
-
Decorative/background images
-
Detect the framework and any image optimization tooling
-
Identify the image source (local files, CMS, CDN, user uploads)
-
Determine target breakpoints from the project's responsive design
-
Ask clarifying questions:
-
What image formats are available?
-
Is there an image CDN (Cloudinary, imgix, Vercel Image Optimization)?
-
What are the Core Web Vitals targets?
Step 2: Load Memory
Follow Standard Memory Loading with skill="responsive-images" and domain="engineering" .
YOU MUST:
-
Use memoryStore.getSkillMemory("responsive-images", "{project-name}") to load project patterns
-
Use memoryStore.getByProject("{project-name}") for cross-skill context (breakpoints, design system)
-
Review previously documented image patterns, CDN config, and format support
Step 3: Load Context
Follow Standard Context Loading for the engineering domain. Stay within the file budget declared in frontmatter.
Step 4: Implement Responsive Images
YOU MUST apply these patterns:
LCP Hero Image (above-fold, critical):
<img src="hero-800.jpg" srcset="hero-400.jpg 400w, hero-800.jpg 800w, hero-1200.jpg 1200w, hero-1600.jpg 1600w" sizes="100vw" alt="Descriptive alt text for the hero image" width="1600" height="900" fetchpriority="high" decoding="async" />
Content Image (below-fold):
<img src="photo-800.jpg" srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1200.jpg 1200w" sizes="(min-width: 768px) 50vw, 100vw" alt="Description of the image content" width="1200" height="800" loading="lazy" decoding="async" />
Modern Format Chain:
<picture> <source type="image/avif" srcset="photo.avif" /> <source type="image/webp" srcset="photo.webp" /> <img src="photo.jpg" alt="Description" width="800" height="600" loading="lazy" /> </picture>
CLS Prevention:
.image-container { aspect-ratio: 16 / 9; width: 100%; overflow: hidden; } .image-container img { width: 100%; height: 100%; object-fit: cover; }
Rules:
-
LCP image: fetchpriority="high" , loading="eager" (or omit loading), no lazy loading
-
Below-fold images: loading="lazy" , decoding="async"
-
Always provide width and height OR CSS aspect-ratio
-
sizes must reflect the actual rendered width at each breakpoint
-
Every <img> with content meaning must have descriptive alt text
-
Decorative images: alt="" and role="presentation"
DO NOT use loading="lazy" on LCP images
Step 5: Generate Output
-
Save to /claudedocs/responsive-images_{project}_{YYYY-MM-DD}.md
-
Follow naming conventions in ../OUTPUT_CONVENTIONS.md
-
Include HTML/JSX code, CSS, and any configuration changes
Step 6: Update Memory
Follow Standard Memory Update for skill="responsive-images" .
Store image conventions, breakpoints used, CDN configuration, format support, and component patterns.
Compliance Checklist
Before completing, verify:
-
Step 1: Image context and optimization scope identified
-
Step 2: Standard Memory Loading pattern followed
-
Step 3: Standard Context Loading pattern followed
-
Step 4: Responsive images implemented with correct srcset/sizes, lazy loading, and CLS prevention
-
Step 5: Output saved with standard naming convention
-
Step 6: Standard Memory Update pattern followed
Further Reading
-
Responsive Images MDN: https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images
-
web.dev Image Optimization: https://web.dev/fast/#optimize-your-images
-
fetchpriority: https://web.dev/articles/fetch-priority
-
CLS Debug: https://web.dev/articles/optimize-cls
Version History
Version Date Changes
1.0.0 2026-02-12 Initial release with interface-based architecture