DEV Community

Artur Smirnov
Artur Smirnov

Posted on

Chrome is downloading your 22 MB mp4 while the 3.8 MB webm sits one line below

Here is a <video> tag I found on a live production site. Read it and see if anything looks wrong:

<video autoplay loop muted preload="auto">
  <source src="/videos/bg-loop.mp4"  type="video/mp4">
  <source src="/videos/bg-loop.webm" type="video/webm">
</video>
Enter fullscreen mode Exit fullscreen mode

Nothing looks wrong. That is the shape everyone writes. It is also shipping 22,730,246 bytes to every Chrome visitor when the file on the next line is 3,807,102 bytes of the same clip.

Six times heavier. One line apart.

Why

The rule is one sentence, and it is not "pick the best one":

The browser plays the first <source> whose type it can decode. It never looks at the rest.

Chrome decodes mp4. So Chrome reads line one, says yes, and stops. The webm underneath is never evaluated — not compared, not considered, not even fetched. It exists purely to make the markup look thorough.

The habit comes from a real era: for years webm support was patchy and mp4 was the safe fallback, so mp4-first was correct defensive markup. That era ended. The habit didn't, and nothing in the page complains, because nothing is broken. The video plays. The layout is fine. There is no console error, no failed request, no red anything. The only symptom is the bandwidth bill and the phone that gets warm.

And preload="auto" on that tag means it isn't even deferred — the browser starts pulling all 22 MB immediately, before the visitor has decided to stay.

The fix is to swap two lines.

It travels in packs

I found the same shape on a second, unrelated site the same week, with an extra layer:

<source src="/videos/banner-logo.mov"  type="video/mp4">
<source src="/videos/banner-logo.webm" type="video/webm">
Enter fullscreen mode Exit fullscreen mode

Look at the first line twice. The file is .mov, the declared type is video/mp4, and the server answers with Content-Type: video/quicktime. Three different opinions about one file, in one line.

That site also served two other QuickTime files — 3,374,781 and roughly 1,267 KB — with no alternative source at all. Not mis-ordered; simply the only option, in a container that has no business being a web delivery format.

Two independent sites, one week. This isn't an anecdote about one careless team, it's a default that survives review because it reads as correct.

Check your own in thirty seconds

Don't read your markup — markup is what you meant. Open devtools, Network tab, filter to Media, hard-reload, and read which file the browser actually fetched and how many bytes it took.

Then compare that against what's in the HTML. If the fetched file is not the smallest one you offered, your <source> order is upside down.

How to not overstate this, which matters if you're telling someone else

I audit other people's sites and write to the owners, so a wrong number costs me the entire conversation. Three ways I have watched video-weight claims fall apart under checking — all three are mistakes I had to catch in my own measurements:

Never sum the sources. The browser fetches exactly one. Adding the mp4 and the webm together to produce a scary total describes a download that has never happened to anyone.

preload="metadata" without autoplay means the body is never fetched. You can curl that file and get 30 MB, and the number is real and completely irrelevant — no visitor downloads it until they press play. Before quoting a video's weight, check the tag: it counts if there's autoplay, or preload="auto". Not otherwise. I had ten weight findings once and lost six to this check and its image equivalent.

The image version is srcset. Fetch an <img>'s src with a script and you get the full-size original; the browser, meanwhile, picked a 400px variant. If the tag has srcset, your measured weight is fiction.

What survives all three is the good stuff: a single <source> with autoplay, an image with no srcset, and any JS or CSS file — those have no responsive negotiation at all, which is exactly why findings in code are the most reliable ones you can make.

The general shape

The interesting bugs in a page are rarely errors. An error announces itself; someone eventually fixes it. What persists for years is markup that is syntactically perfect and semantically backwards — a correct list in the wrong order, a correct type attribute on the wrong file, a correct preload hint on something that shouldn't preload.

Nothing in your toolchain flags any of it. A linter sees valid HTML. A build sees valid HTML. Lighthouse will tell you the page is heavy but not that the lighter file was sitting right there, unused, one line below.

The only thing that catches this class of bug is opening the network panel and comparing what you offered with what was taken.


I build browser tools where this kind of 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 check your own and the order was backwards, I'd like to know — I have two cases and I suspect the true rate is embarrassing.

Top comments (0)