In his latest piece What’s with putting the CSS in the head? @schizdazzle describes the advantages of placing CSS in the head of an HTML file. What he describes in his article is quite true: A page loads faster if you don’t load external CSS files — even if they are located at the next server of a CDN within your country. He describes how this works in his article: The Critical Rendering Path.
[…] CSS is not only on the critical path, it is the critical path.
On the other hand there is a thing that bothers me about this article: It misses out on an important part: When to use this technique and when not.
There are some arguments that stand against including the CSS directly in your head and there are use cases where you don’t want to load your CSS within your HTML.
There are two takes on caching.
First is browser caching: You miss out on caching of files in the browser’s storage. This is an essential point if we talk about old-school websites. Sure, your HTML page (with the containing CSS) might be cached within the browser but this does not work great if you generate dynamic pages.
As a general advice: A stylesheet loaded from the same domain as your web-page avoids extra DNS look-ups, while a file from a CDN might be served faster. Just test these issues and look for information relevant to your project.
On the other hand caching the static resources on a CDN edge is not available if you don’t use external files which means the HTTP request has to get all the way from your server to the user’s browser. This will most likely take longer if your user is some thousand kilometers away from your server.
An insight view is provided by Guy Podjarny in his article Why Inlining Everything Is NOT The Answer. Another article you might be interested in is Inline <script> and <style> vs. external .js and .css — what’s the size threshold? by Mathias Bynens who interviews Kyle Simpson and Billy Hoffman on this very topic.
Use cases of embedded CSS
Let’s talk about the cases where it makes sense to place your CSS within the head of your HTML.
Mostly one can say that micro sites or single page applications are perfect for this technique since users don’t visit more than one page of your application — they stay on the same page for all of their visit and thus don’t need the advantage of client-side caching – up to a certain extend. This becomes a negative example if you have high traffic from returning visitors.
Another use case are pages that need to be served very very fast as for example home pages or landing pages. You want to avoid the Critical Rendering Path in this case more than in others. Users will wait a few more seconds if you got their attention in the first place.
How to do inlining
This section is only important if you are really really sure you want to embed your CSS in the HTML head. As per my own front-end workflow here is an example on how to integrate this feature with a Grunt build-flow.
There are a couple of Grunt modules out there that do this kind of task and nothing more. For example grunt-inline-css which is basically targeted at HTML mailings but can be easily used for embedded CSS on any web project. Done!
The configuration is easy and an example can be found within the README file of the repo.
Another alternative would be to read the content from a generated minified CSS file with Node’s `fs` API and than use grunt-replace within your build workflow. Also straightforward if you are used to Grunt.
One more thing though: Combined with other techniques to save loading time the idea of inlining CSS in the HTML head might be a good solution.
If you load the content of your “classic” website asynchronously you can leave out the head and scripts for new pages which makes loading pages faster in general but introduces a couple of other problems you have to work around (ie. browser history). There are services optimized for this kind of task. You get the idea…
Apart from that there are several techniques which combine some of the ideas together. I don’t want to go into detail.
A conclusion Guy Podjarny makes is that the “HTTP overhead of a request & response is often ~1 KB, so files smaller than that should definitely be inlined” which leads him to the statement that “testing shows you should almost never inline files bigger than 4 KB”.
More general advice comes from Stoyan Stefanov:
If your CSS is not puny enough to be all inline […] it should at least be a single file, way at the top of the document, with the first flush. Just get it over with.
In general: It makes sense for sites like google.com, SPA’s or micro sites but middle to large scale web pages do not profit from the benefits.
This is just my two cents to the problem with embedded CSS which I wanted to add to @schizdazzle’s article.