Serving 2x Images to Everyone Is a Performance Tax Most Users Didn't Agree To
Somewhere along the way, high-DPI became the default assumption. Retina displays showed up, designers fell in love with crisp assets, and a lot of dev teams quietly started treating 2x — and sometimes 3x — images as the universal safe choice. Better safe than blurry, right?
Except that logic has a hidden cost, and it's being paid by everyone who isn't sitting in front of a Retina display on a fast connection.
Let's talk about what actually happens when you over-provision for high-DPI without thinking about who's on the other end.
What "High-DPI" Actually Means for File Size
A standard 400×300 image at 1x is a manageable file. Push that to 2x — which means 800×600 pixels to render at the same visual size — and you've roughly quadrupled the pixel count. At 3x, you're at nine times the pixels of the original.
Even with aggressive compression, that math doesn't disappear. A WebP image that weighs in at 35KB at 1x might hit 110–130KB at 2x and push past 250KB at 3x. Multiply that across a page with a hero image, a product grid, a few editorial photos, and a handful of UI assets, and you're looking at a meaningful chunk of payload that a significant portion of your audience has no way to benefit from.
They're downloading all those extra pixels. Their browser is decoding them. And then they're displaying the image at exactly the same visual quality they would have gotten from the 1x version.
Who's Actually Getting Hurt
The assumption baked into aggressive high-DPI delivery is that most users have retina or near-retina displays. And sure, if your audience skews heavily toward Mac users or flagship Android phones, that assumption isn't crazy. But it's still an assumption.
According to various device usage breakdowns, a substantial portion of web traffic still comes from mid-range Android devices, older Windows laptops, and budget hardware where standard 1x pixel density is the norm. In the US, that includes a lot of users in rural areas, lower-income households, and anyone still running hardware that's more than three or four years old.
For those users, your 3x hero image isn't a gift. It's a bandwidth drain they didn't ask for. On a throttled connection or a capped mobile data plan, that extra payload shows up as a longer load time and, sometimes, a site they decide to leave before it finishes.
The "Just Use srcset" Trap
The standard answer here is srcset. And yes, srcset is the right tool — in theory. You define multiple image sources at different resolutions, the browser picks the right one based on the device, done.
In practice, a lot of implementations get this wrong in ways that quietly undo the benefit.
One common pattern: teams define 1x, 2x, and 3x variants but set the default — the fallback — to the 2x version. Browsers that don't fully support srcset or that fall through to the default for any reason end up loading the heavier asset. That's not a hypothetical edge case; it happens.
Another issue is the sizes attribute. Without accurate sizes hints, browsers have to make educated guesses about how large the image will actually render. Those guesses are often wrong, and a browser that thinks an image is going to fill the viewport might pull a much larger asset than necessary for a thumbnail that ends up being 200px wide.
Then there's the CMS problem. A lot of content management systems either don't generate proper srcset markup automatically, or they do but only output 2x variants — skipping the 1x entirely because someone assumed it was unnecessary.
Network Conditions Don't Care About Your Design System
Here's the part that's easy to miss when you're developing on a MacBook connected to gigabit Wi-Fi: network conditions vary wildly, and device pixel ratio doesn't correlate with connection quality the way you might hope.
A user on a 2022 mid-range Android phone might have a 2x display and a 3G connection. They qualify for the high-DPI asset by display, but they're going to wait significantly longer to get it. The Network Information API exists to help with this — you can use it to serve lighter assets to users on slow connections regardless of their display density — but most teams aren't using it.
The <picture> element with media queries can help here too, letting you serve different sources based on conditions beyond just resolution. But again, this requires intentional implementation. It doesn't happen automatically.
A More Honest Approach to DPI Delivery
So what does a better strategy actually look like?
Start with real analytics. Before you commit to a delivery strategy, check what percentage of your actual users are on high-DPI displays. Your analytics platform can often surface device pixel ratio data. If 60% of your traffic is coming from standard-density displays, that should inform your default assumptions.
Make 1x a real, optimized asset — not an afterthought. A lot of teams put effort into making 2x images look great and treat 1x as a downscaled version. That's backwards. Your 1x asset should be as carefully optimized as any other version.
Use srcset correctly, with real sizes values. Don't guess. Measure how large your images actually render at different breakpoints and write sizes attributes that reflect reality. It's tedious, but it's what makes srcset work as intended.
Consider client hints if your stack supports them. The DPR client hint lets servers respond with the right asset for the requesting device without requiring all the client-side logic. It's not universally supported, but for teams with control over their CDN and server configuration, it's worth exploring.
Don't serve 3x assets unless you have a clear reason to. The visual difference between 2x and 3x is marginal for most content at most sizes. The file size difference is not. Unless you're delivering high-end photography or design work where pixel-level sharpness genuinely matters, 3x is probably overkill.
The Bigger Picture
High-DPI delivery isn't inherently bad. Crisp images on retina displays genuinely do improve the visual experience, and there are contexts where it's absolutely worth the payload cost.
The problem is treating it as a universal default rather than a deliberate choice. When you ship 2x assets to everyone without checking who's actually going to benefit, you're making a tradeoff — you're just making it on behalf of your users without asking them.
The good news is that serving the right asset to the right device is a solved problem. The tools exist. The techniques are well-documented. What's missing, in a lot of codebases, is the intentionality to actually implement them properly — and the habit of questioning whether the retina-first assumption still makes sense for your specific audience.
Your high-DPI assets look great. Make sure they're not costing everyone else something they didn't agree to pay.