I like to serve this site in a fast way, not doing anything hugely dumb.

When you’re writing a site by hand, hand-editing each HTML file, it’s crazy to maintain the same pieces of CSS across dozens, hundreds of .html files.

So it made a lot of sense to just <link rel="stylesheet" type="text/css" href="/style.css"> and keep all your CSS in that file.

What I dislike about this approach is the round-trip time. It seems like bandwidth is very cheap these days, but latency hasn’t really improved by the same order of magnitude. So why spend time fetching the /style.css? It’s absolutely critical for a fast render/paint that the browser has the stylesheet loaded. Waiting for that really hurts time to draw.

A measured decision

I don’t want to bloat pages unnecessarily, though.

Factoring in compression, what’s the difference in size between inlining the CSS in a <style type="text/css">..</style> and writing it into a separate style.css and <link ..>ing it?

Tested locally, what’s the difference in timing? What about when it’s hosted at the real domain / pushed to production?

I read a good blog post by Frank Goossens about inlining, and I wouldn’t be surprised to find the same result, that inlining is not too bad.

Test procedure

I’m going to copy the CSS out of the partial style.css.html that it’s in now, in its compact notation, and paste it into a static style.css. I remove the inline reference to style.css.html and I replace it with a <link..> to my stylesheet. Run in development, pull up /about, write down network / load timings. Push to production, write down network / load timings. Then I want to go back to inlining, repeat observations in dev & prod.

I was having trouble “benchmarking” the table below. The “load” event timing I was reading off Firefox’s dev console was waiting for the favicon.ico request to come back.

I couldn’t figure out how to disable it: commenting out the <link> doesn’t prevent the GET!

I was about to look to see if I could temporarily disable Firefox’s favicon fetching, but I stumbled upon an even better idea: just inline the icon as base64!

<link rel="icon" type="image/x-icon" href="data:;base64,AA....AA=">

Et voila. I got the base64 straight from the command

$ base64 static/favicon.ico

Results

Against /about/, cache disabled

Strategy env A B C
<link> dev 41~55ms 57~105ms 61~108ms
inlined dev 2~9ms 62~69ms 65~71ms
<link> prod 198~206ms 214~234ms 217~240ms
inlined prod 62~65ms 143~163ms 145~167ms

where

A = Finish: total time needed to load all requests

B = DOMContentLoaded: time when ‘DOMContentLoad’ event occurred

C = Load: time when ‘load’ event occurred

dev = served from localhost

prod = served from FastMail

Thoughts

I like one-request performance. It feels instantaneous.