Should you always care about your website size?

TLDR

If you reduce your critical path size from 90 to 60 KB, it’s good, but not all that great from a networking perspective. But going from 42 to 40 (especially on slow connections) will be more impactful.

It is all about getting down to the smallest round trip size. If you can slip under the treshold of next RTT (round trip time), go for it, it is a very nice bonus on top of having smaller website. Refer to cheat sheet below to know where are the tresholds.

Cheat sheet

Round tripWindow Size (KB)Total size (KB)
11414
22842
35698
4112210
5224434

Round trip rules

Recently I read a couple of useful articles on how TCP works and especially how it snowballs (or slow-starts) with small packages into bigger chunks of data over the life of a connection. It is a little known fact that if your webpage critical path [1] can fit into the first round trip within a TCP connection (14KB), it is the best-case scenario because the browser will not ask the server again for anything. This rarely happens as webpages often use CSS frameworks, inline JavaScript, have a lot of text on them, have a lot of metadata. But there is also the second-best thing. Return your webpage within two round trips. Or three.

The first round-trip has a size of 14 KB.
The second one is the double of that - 28. At the end of the second round trip, your webpage will be loaded if it’s below 28 + 14 = 42 KB
The third round trip is double the previous one, which is 2 * 28 = 56. 56 + 42 = 98. For quick reference look at the cheat sheet at the top of the article.

Real world use case

I adjusted the homepage of a website to fit in the first round trip. It was around 18 KBs, but had a lot of inlined stuff, and was optimized pretty well (already had 100 in Lighthouse).

To go below 14 KB, I had to un-inline some things (mostly SVG images, favicon, which was another experiment in the making), clean up some unused SVG symbols (for icons), and at the end of the day, I landed at 12.17KB. 5.29KB for HTML and 6.88KB for CSS.

Did it work?

Well, it’s hard to tell. SSL handshakes take more time than the actual transfer of the critical data, so it is not bad from the frontend point of view.
This is the waterfall before I managed to get below 14 KB

Waterfall before

And this is after going below 14 KB: (+ addition of preconnect in HTTP header to hopefully speed up connection initialization to our CDN):

Waterfall after

Tests were made on the 1.5Mbps setting of WebPageTest.

After the tests, I discovered that SSL handshakes can be optimized, so this will be our target very soon to make global improvements. I detected that SSL handshake data weighs around 6KB, and it might account for the 14 KB TCP packets. I need more investigation in that area because there might be more to gain.

The nature of testing on live websites with real devices is that you can’t really predict exact numbers. Network conditions on both sides change. Device load matters. Many things can vary, and I could run the test a couple more times to prove my point, but I prefer to prove a different point: Just because something is better, it does not mean you will be able to show it on a chart every time. This is real life, not a laboratory.

Inlining CSS — an experiment

Just for the sake of testing, I inlined the main CSS on the homepage to see what kind of results this will give. In the critical path it removed one SSL handshake, so in theory, it should move everything left on the waterfall chart.

Waterfall with inlining
Request timing with inlining

It did very well - HTML and CSS were loaded just after 722ms, within first request. This is the best I could hoped for from this experiment. Combining small size with inlining CSS is a great way to make your Web Core Vitals score great.

From that day I’m looking at inlining CSS as a viable strategy, not only a theory. Thanks to TailwindCSS, and Webpagetest.org.

Answering the question

Yes. You should care. It’s always better to have a smaller website than a bigger one. Even if you cannot get spectacular results today, remember that good results come from a lot of smaller changes. So go for it, one step at a time.

And no. Caring does not mean you should fight for every KB, especially if it makes your (and your team’s) life much more difficult. If you are cutting 100KB from your 2MB React app, don’t stress about it. In that case there are more effective ways of spending your time, for example:

All of those have proven to be very effective in improving user experience and ultimately business KPIs.

You might think performance is all about squeezing every last drop from every part of the stack. The longer I work within frontend and performance space the more I think it is, like with everythin else in life, art of compromise.

Footnotes

  1. For static pages HTML + CSS, for SPAs you need to think about JS as well ↩︎