← 블로그

Responsive Images: Stop Serving Desktop Photos to Phone Screens

A photography portfolio can look great on a desktop, where the connection is fast and the screen is wide, and still take over ten seconds to load on a phone. The usual cause is a plain <img> tag serving one high-resolution file to every device, regardless of screen size. The browser ends up downloading several times more data than the device will ever render.

The Problem

A large image exported for a desktop monitor is usually around 2000px wide and 500KB. A mobile device with a 375px screen only requires an image roughly 750px wide, even when accounting for high-resolution retina displays. That smaller version ranges from 60 to 80KB. Using the desktop version forces mobile users to download eight times more data than necessary. These costs compound across a full page. A homepage with five large photos can reach 2.5MB when 400KB would suffice. On a standard 3G connection, this is the difference between a 3-second load and an 18-second load.

Responsive image sizing

Web browsers can't see how an image will render until the CSS is parsed and the layout is calculated. By then, the preload scanner has already fired off a request for whatever URL it found in the src attribute. HTML must provide the browser with enough information upfront to make a smart choice. This is the role of srcset and sizes.

The srcset Attribute: Giving the Browser Options

The srcset attribute gives the browser a menu of image files at different widths. The browser then picks the most appropriate one for the screen.

<img
  src="hero-800.jpg"
  srcset="
    hero-400.jpg   400w,
    hero-800.jpg   800w,
    hero-1200.jpg 1200w,
    hero-1600.jpg 1600w,
    hero-2000.jpg 2000w
  "
  sizes="100vw"
  alt="Mountain landscape at sunset"
>

The w descriptor tells the browser the actual pixel width of each file. The src attribute is the fallback for older browsers that don't support srcset—basically just IE11, which we can finally let go. But srcset alone isn’t enough. The browser knows the viewport width and the device pixel ratio, but it doesn't know how wide the image will actually render on the page. That's what sizes is for.

The sizes Attribute: Telling the Browser How Big the Image Will Be

The sizes attribute pairs media conditions with the display width of the image. This acts as a guide for the browser to understand the image layout before the CSS is parsed.

<img
  src="hero-800.jpg"
  srcset="
    hero-400.jpg   400w,
    hero-800.jpg   800w,
    hero-1200.jpg 1200w,
    hero-1600.jpg 1600w,
    hero-2000.jpg 2000w
  "
  sizes="
    (max-width: 600px) 100vw,
    (max-width: 1200px) 50vw,
    33vw
  "
  alt="Mountain landscape at sunset"
>

Based on these rules, the image takes up the full screen on devices up to 600px wide. Between 600px and 1200px, it takes up half. Above that, it only takes up a third. The browser uses this info along with the device pixel ratio to grab the smallest file that still looks sharp.

Getting sizes wrong is a common way to accidentally bloat a site. If the attribute says 100vw but the image is actually tucked into a sidebar at 33vw, the browser downloads a file three times larger than it needs to. It's a simple mistake that can undo all your hard work with srcset.

Generating Multiple Sizes

Creating all these image variants is the tedious part. There are three realistic ways to handle it:

How Many Breakpoints Is Enough?

Developers often lean toward two extremes: generating fifteen variants every 100 pixels or serving only two versions labeled "small" and "large." Neither approach is ideal for real-world performance.

A practical target is four to six sizes for a given image. Using widths like 400, 800, 1200, 1600, and 2000 covers phones, tablets, laptops, and large desktops with enough detail. Going smaller than that offers diminishing returns. The tiny file size difference between a 900px and a 1000px image rarely justifies the extra storage and cache bloat.

Different sizes

Common Mistakes Worth Avoiding

Example: 4.2MB to 680KB on Mobile

In the photography portfolio scenario from the opening, implementing srcset with proper sizes and WebP sources changed everything. By generating five width variants per image, the homepage size dropped from 4.2MB to 680KB on mobile. Load times fell from 11 seconds to under 3. These are the same images with the same visual quality, just delivered intelligently.

The srcset and sizes syntax is awkward, and getting sizes right requires thinking about the layout at each breakpoint. The payoff is that the browser can choose the smallest file that still looks sharp, rather than always downloading the biggest one.