DEV Community

Artur Smirnov
Artur Smirnov

Posted on

A 4 MB logo drawn at 36 pixels: the two files that skipped the image optimiser

A landing page I measured last week sends 11.7 MB to a phone. Two files account for 11.2 MB of it:

file weight how it appears
how_it_works.png 6.9 MB one enormous raster image
logo.png 4.1 MB a 2048 px file, drawn on screen at 36 px

Four megabytes of logo to paint an icon the size of a fingernail.

The part that makes this worth writing about is not the number. It is that the rest of the page was done correctly. The before/after sample images on the same page go through the framework's image component and arrive on mobile at 71 KB and 54 KB, properly narrowed to w=640. Someone set that up, and it works.

So the site does not have a person who doesn't care about images. It has two <img> tags.

The optimiser is opt-in, and nothing tells you when you opted out

Every modern framework ships an image pipeline — next/image, Nuxt Image, Astro's <Image>, Gatsby, whatever your stack calls it. Point it at a file and you get resizing, format negotiation, a srcset, lazy loading, the lot.

Point nothing at it and you get the original file, at original size, forever.

That is the whole bug. The two heavy files were plain <img> tags. They render identically to the optimised ones. Same layout, same crop, same visual result at every breakpoint. There is no warning, no build error, no lint rule firing by default, and no visual difference to catch in review — because at 36 px on screen, a 2048 px source and a 72 px source look exactly the same.

It usually happens the same way, too. The optimised images are the ones that arrived in the content pipeline — product shots, gallery items, anything in a loop. The unoptimised ones are the furniture: a logo dropped in during the first hour of the project, a diagram exported from Figma and dragged into the hero. They get placed once, early, by someone who is not yet thinking about performance, and then they are never touched again because they are never wrong.

How to check yours in about a minute

Open DevTools, Network, filter to Img, disable cache, reload. Sort by size, largest first.

Then look at the URLs, not the file names. Optimised assets carry the pipeline's signature — /_next/image?url=…&w=640&q=75, /_ipx/, /_vercel/image, a CDN transform path, something with dimensions in the query string. Unoptimised ones are just /logo.png.

Anything at the top of that list without a transform in its URL is a file that skipped the pipeline. That's your answer, and it takes longer to read this paragraph than to run it.

Two follow-ups worth thirty seconds each:

  • Compare rendered size to natural size. In the Elements panel, hover the image: Chrome shows both. A 2048 px file in a 36 px box is a 57× overshoot in each dimension.
  • A logo almost never needs to be a raster at all. Ours is an icon: SVG, or a 72 px PNG at 2× if the mark is too painterly to vectorise. Either one is measured in kilobytes.

The honest part: quote weight, not time

I ran the first cold visit at 32 seconds. The second, with a warm cache, was under two.

Both are real, and quoting either one alone is misleading. So the correct thing to say is either both numbers with the conditions attached, or neither — and to build the argument on weight, which does not move: 11.7 MB stays 11.7 MB regardless of whose connection measures it.

This matters more than it sounds when you're telling someone else about their site. Load time is a property of the path between two machines; you measured your own network, not their customer's. Weight is a property of the page itself. One of those you own, the other you're borrowing.

Why this is worth an hour of anyone's time

The site I measured belongs to someone about to buy TikTok and Instagram ads. That traffic is phones on cellular with no patience, and every ad dollar was going to buy a visitor who leaves before the page assembles.

Routing two files through the pipeline that was already set up, giving the logo an SVG, and slicing the tall diagram into sections turns 11.7 MB into under a megabyte — without a single change to the design. Nothing moves, nothing is redrawn, nothing needs approval from whoever owns the brand.

That's the shape of the best performance work: not a redesign, not a rewrite, just finding the things that quietly bypassed a system you already built.


I build browser tools where measurement is the job — parametric product configurators and engineering calculators, where the geometry and the costing come from the same parameters so they can't quietly disagree. Work at smirnov-artur.github.io/webgl, and I'm on Telegram at @smirnovarturr or at paladei702@gmail.com.

If you run the URL check above and find something at the top of the list without a transform in it, I'd be curious what it was. My money is on a logo.

Top comments (0)