Optimising the Critical Rendering Path, and Loading CSS Asynchronously and Conditionally
20 June, 2014
Optimising the Critical Rendering Path
I’ve recently been looking into frontend optimisation, or as clients like to refer to it, “can you fix our slow site?” - in my defence I mainly work with Magento sites, so this is not a straightforward task.
Ilya Gregorik at Google has done some great work educating others in optimising the critical rendering path, and one of his recommendations is to inline critical CSS in the head and defer the loading of other CSS files until after the initial paint.
So can you load CSS at the bottom of the page?
What was Ilya Gregorik’s advice?
It contains an example script that enables you to load a CSS file asynchronously, after the "initial painting of the page. Its styles are applied to the page once it finishes loading, without blocking the initial render of the critical content."
Taking the Google CSS loading script a bit further
This was exactly the kind of thing I was looking for, but I needed to take it a step further. I wanted to be able to detect what page I was on and then load multiple CSS files if necessary - there’s no need to load Product Page styles on the Home Page for example.
Part of the optimisation process I’ve been working on is the modularisation of CSS - creating ‘page type’ or function specific stylesheets rather than lumping everything into one big ‘main.css’. Case in point - I did a test on one of my sites and discovered that 85% percent of the selectors in my `main.css` file were unused on the homepage. While I’m not surprised by this, it bugged me that there was so much redundancy.
Sass and Less have modularisation covered from a preprocessor point of view - if you follow a modular, component based Sass codebase for your projects (which I do) it’s pretty easy to create specific CSS files such as critical.css (which I inline in the head), base.css, category-page.css, product-page.css etc. - but what to do with these new CSS files, especially if the pages are built dynamically on a CMS? How do you load them only when needed?
In a nutshell I modified the script on the Google Developers page, allowing me to pass in page specific classes (in my case the classes the CMS was adding to the body tag), and then filter the loading of CSS files based on that information.
Get your hands on the asynchronous and conditional CSS loading script here →
What about other script loaders?
But can’t you just use an existing script loader for this, something like YepNope? I did think of that and I tried it out. However, I still saw a FOUC. I’m not sure why - maybe it has to do with me having the YepNope tests at the bottom of the page, which slows the down the processing and hence the loading/rendering of the CSS files?
I’m still in the early stages of using and testing this script, but at first glance it seems to be effective. Let me know if you try it and how you get on?
I was also recently pointed to this CSS loading script by Scot Yehl.
It is very similar to the Google script (and hence, mine), but it doesn’t seem to have the ability to test for Page Type, or to load multiple files - I may be wrong about that though, I haven’t tried it out.