All rules

Sheath rule

perf-responsive-images

Images should use srcset for responsive loading.
Package
Core
Category
Performance
Default severity
info by default
Auto-fix
Manual fix

#Why

A single src sends every visitor the same file. Sized for a desktop hero, a phone on a mobile connection downloads several times the pixels it can display; sized for the phone, a high-density screen renders it soft.

srcset lets the browser pick, using the viewport and pixel density it alone knows at request time.

#Examples

#Bad

<!-- Single image for all devices: a phone on a mobile connection downloads the 1920px file for a 320px viewport -->
<img src="/images/hero-1920.jpg" alt="Hero Image" width="800" height="600">

#Good

<!-- Responsive with srcset (width descriptors) -->
<img src="/images/hero-800.jpg"
srcset="/images/hero-400.jpg 400w,
/images/hero-800.jpg 800w,
/images/hero-1200.jpg 1200w,
/images/hero-1920.jpg 1920w"
sizes="(max-width: 600px) 100vw,
(max-width: 1200px) 50vw,
800px"
alt="Hero Image">
<!-- Retina with srcset (pixel density descriptors) -->
<img src="/images/logo.png"
srcset="/images/logo.png 1x,
/images/logo@2x.png 2x,
/images/logo@3x.png 3x"
alt="Logo">
<!-- SVG images don't need srcset -->
<img src="/images/icon.svg" alt="Icon">
<!-- Decorative images are skipped -->
<img src="/images/decoration.jpg" alt="">

#srcset Syntax

#Width Descriptors (w)

srcset="small.jpg 400w, medium.jpg 800w, large.jpg 1600w"

Browser selects based on viewport width and pixel density.

#Pixel Density Descriptors (x)

srcset="normal.jpg 1x, retina.jpg 2x, super-retina.jpg 3x"

Browser selects based on device pixel ratio.

#sizes Attribute

Tells the browser how large the image will display:

sizes="(max-width: 600px) 100vw,
(max-width: 1200px) 50vw,
800px"

Meaning:

  • Below 600px viewport: image is 100% of viewport width
  • Below 1200px viewport: image is 50% of viewport width
  • Above 1200px: image is 800px wide

#Options

Use these options to set the minimum checked width and exclude selected URLs.

Option Type Default Description
minWidth int 300 Skip images smaller than this
excludePatterns array [] URL patterns to exclude
excludeClasses array ['icon', 'favicon', 'logo-small', 'badge', 'avatar-sm'] Exact, case-insensitive class tokens to exclude
<?php
'perf-responsive-images' => ['warning', [
'minWidth' => 400,
'excludePatterns' => ['icons/', 'logos/'],
'excludeClasses' => ['thumbnail', 'product-swatch'],
]],

Each list replaces its default. Set excludeClasses to [] to evaluate images regardless of their CSS classes.

#What's Skipped

  • Images with at least one valid static srcset candidate, or a dynamic srcset whose runtime value cannot be determined
  • SVG images (vector, resolution-independent)
  • Data URIs
  • Small images (below minWidth)
  • Images whose class list contains an excludeClasses token
  • Decorative images (role="presentation" or empty alt)

#Notes

  • Use width descriptors (w) for most responsive images
  • Use pixel density descriptors (x) for fixed-size images like logos
  • Width, height, and density descriptors must be positive; duplicate or mixed width/density descriptors do not form a usable candidate
  • Consider <picture> for art direction (different crops per viewport)
  • Missing srcset is not reported when image attributes are generated dynamically, such as with {{ $attributes }} or @if

#References

#Related Rules