Performance & Accessibility
Image & Media Optimization Standard
This standard makes pages fast, clear, and accessible. It defines file naming rules, export formats, aspect ratios, responsive srcset and sizes, lazy loading, captions, and alt text. Guidance aligns with web.dev performance, MDN HTML, and W3C WCAG.
File naming rules
Names should be human readable and consistent. They help with asset management and accessibility tooling.
| Rule | Example | Why |
|---|---|---|
| lowercase, hyphen separated | feature-dashboard-hero-w1600.avif | Portable across systems |
| entity prefix | blog-onpage-checklist-table-w1200.webp | Group by area |
| include width token | …-w800.webp | Easier to audit srcset |
| no spaces, no dates in URL | pricing-hero.avif | Evergreen paths |
| color profile noted if non sRGB | diagram-srgb-w1200.png | Predictable rendering |
Use consistent slugs for assets just like pages. See general URL guidance in Google’s Starter Guide.
Formats and when to use them
AVIF and WebP
- Default to AVIF for photos and mixed content
- Fallback to WebP for wider compatibility
- Provide JPEG as a final fallback if needed
See next-gen formats and AVIF on web.dev.
PNG and SVG
- Use PNG for sharp UI screenshots and transparency
- Use SVG for icons, logos, simple diagrams
- Prefer vector over raster for scalability
MDN has SVG guidance at MDN SVG.
GIF replacement
- Replace animated GIF with MP4 or WebM
- Autoplay muted and loop only for short UI demos
Large GIFs hurt performance. See replace GIFs with video.
Picture element pattern
<picture>
<source type="image/avif"
srcset="/img/hero-w800.avif 800w, /img/hero-w1200.avif 1200w, /img/hero-w1600.avif 1600w"
sizes="(min-width: 1024px) 1000px, 90vw">
<source type="image/webp"
srcset="/img/hero-w800.webp 800w, /img/hero-w1200.webp 1200w, /img/hero-w1600.webp 1600w"
sizes="(min-width: 1024px) 1000px, 90vw">
<img src="/img/hero-w1200.jpg" width="1600" height="900"
alt="Dashboard showing weekly pipeline with three trend lines"
loading="eager" fetchpriority="high" decoding="async">
</picture>Picture, srcset, and sizes are covered on MDN.
Aspect ratios and sizes
Lock aspect ratios to avoid layout shift and messy crops. Use the CSS aspect-ratio property and include width and height attributes on <img> for CLS control.
| Use case | Aspect ratio | Target widths | Notes |
|---|---|---|---|
| Hero image | 16:9 or 3:2 | 1600, 1200, 800 | Largest Contentful Paint, keep file small. See LCP. |
| In-article image | 4:3 or 3:2 | 1200, 800, 480 | Fits common content widths |
| Thumbnail or card | 1:1 | 640, 320 | Square previews |
| OG image | 1200 x 630 | 1200 | Meta preview size |
.card-thumb { aspect-ratio: 1 / 1; object-fit: cover; border-radius: 12px; }Core Web Vitals guidance lives at web.dev. Always set intrinsic width and height to reserve space.
Responsive images: srcset and sizes
Use width descriptors with a realistic sizes value so the browser picks the right file. Avoid device pixel ratio descriptors unless you must serve 1x and 2x pairs.
Width descriptor pattern
<img
src="/img/chart-w800.avif"
srcset="/img/chart-w480.avif 480w, /img/chart-w800.avif 800w, /img/chart-w1200.avif 1200w"
sizes="(min-width: 1100px) 700px, (min-width: 640px) 90vw, 95vw"
width="1200" height="900" alt="Comparison chart of three pricing plans"
loading="lazy" decoding="async">See MDN on responsive images.
Art direction with picture
<picture>
<source media="(min-width: 900px)" srcset="/img/hero-wide-w1600.avif 1600w, /img/hero-wide-w1200.avif 1200w" sizes="900px">
<source media="(max-width: 899px)" srcset="/img/hero-tall-w800.avif 800w, /img/hero-tall-w600.avif 600w" sizes="90vw">
<img src="/img/hero-wide-w1200.jpg" width="1600" height="900" alt="Team collaborating on analytics dashboard">
</picture>Lazy load, priority, and preloading
Lazy loading
Use loading=”lazy” for below the fold images. Keep the hero image eager. Lazy loading is documented on MDN.
Priority hints
Mark the LCP image with fetchpriority=”high”. Use decoding=”async” for better interactivity. See priority hints.
Preload the hero
<link rel="preload" as="image"
imagesrcset="/img/hero-w1200.avif 1200w, /img/hero-w1600.avif 1600w"
imagesizes="(min-width: 1024px) 1000px, 90vw"
href="/img/hero-w1600.avif">Use preload carefully. See preload guidance.
Alt text and decorative images
Write alt text that communicates the same purpose. If the image is decorative, use empty alt and hide from assistive tech. WCAG gives the baseline, and WAI has practical tutorials.
| Case | Rule | Example |
|---|---|---|
| Informative image | Describe what the user needs to know, not pixels | alt: “Pipeline grew 18 percent quarter over quarter chart” |
| Functional image | Describe the action | alt: “Download PDF” |
| Decorative image | Empty alt, mark as presentational | alt: “” and role=“presentation” |
| Complex diagram | Short alt plus nearby text or details | Use figcaption or a linked long description |
See WAI alt decision tree and image tutorials.
Captions and figure semantics
Use <figure> and <figcaption> to tie images to their context. Captions help users scan and help models extract meaning.
<figure>
<img src="/img/case-study-chart-w1200.avif" alt="Activation rate by cohort after onboarding redesign" width="1200" height="800">
<figcaption>Activation improved across three cohorts after we simplified setup.</figcaption>
</figure>HTML semantics on MDN.
Video and audio standards
Export and codecs
- MP4 H.264 for widest support, WebM VP9 or AV1 when available
- Resolution matched to container, use a poster image
Tracks and controls
<video controls preload="metadata" width="960" height="540" poster="/img/overview-poster.jpg">
<source src="/vid/overview.av1.webm" type="video/webm">
<source src="/vid/overview.mp4" type="video/mp4">
<track kind="captions" src="/captions/overview-en.vtt" srclang="en" label="English" default>
</video>Caption tracks are required for accessibility. See WAI media accessibility.
Autoplay and performance
- Autoplay only when muted and short
- Lazy load embeds with placeholder and consent where required
Performance implications are covered on web.dev.
SVG icons and logos
- Inline SVG for icons so you can style with CSS
- Add <title> for accessible name if the icon is meaningful
- Use aria-hidden=”true” for decorative icons
<svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
<path d="M12 2v20M2 12h20" />
</svg>See MDN ARIA roles.
CDN, caching, and EXIF
HTTP caching
- Immutable fingerprinted assets: Cache-Control: public, max-age=31536000, immutable
- Editable originals: set reasonable max age and revalidate
- Serve compressed files over HTTPS
HTTP caching basics on MDN.
Metadata and color
- Strip unnecessary EXIF to reduce bytes
- Export in sRGB for consistent color on the web
Image processing concepts on web.dev Learn Images.
Implementation checklist
- Pick formats per type: AVIF default, WebP fallback, SVG for icons, PNG for sharp UI
- Export at fixed aspect ratios and create 2 to 4 width variants
- Add width and height to every <img> to prevent CLS
- Use srcset and realistic sizes values
- Lazy load non critical media, keep hero eager with priority hints
- Write meaningful alt text or use empty alt for decorative images
- Wrap important images in <figure> with <figcaption>
- Provide captions for video with VTT tracks
- Serve from a CDN with long cache for fingerprinted files, strip EXIF
- Monitor LCP and CLS in field data and adjust sizes or compression
Track Core Web Vitals in web.dev and check coverage in Rich Results Test when using media related schema.
FAQ
How small should files be
There is no single limit. Start with AVIF 50 to 70 quality, then check LCP and visual quality. Optimize for perceptual quality first. See AVIF quality notes.
Do I still need JPEG
Use JPEG only as a safety net if you have legacy browsers. Most modern browsers support AVIF or WebP. See Can I use AVIF and WebP.
Should I host fonts and images on the same CDN
Yes, when possible. Fewer hosts reduce connection overhead. If you must use multiple, add rel=”preconnect” for critical hosts. See preconnect.
What tools should I use
For quick exports try Squoosh. For pipelines use ImageMagick, cwebp, and avifenc. Validate with Lighthouse in Chrome DevTools.
