dark mode

Eliminate render-blocking CSS in above-the-fold content, Part 3/3

Eliminate render-blocking CSS in above-the-fold content, Part 3/3

This is an error that can take 30+ points from your score, but it could be surprisingly easy to fix even on a mature website.

This is the third installment of my series of blog posts on Google PageSpeed Insights optimizations and recommendations. This time we are going to focus on what is render-blocking CSS and how to eliminate it.

Part 1: Google PageSpeed Insights optimizations and recommendations
Part 2: Eliminate render-blocking JavaScript in above-the-fold content

I like the SMACSS methodology it is an impressive set of rules in one place to follow when writing your styles. However, whatever your method of writing CSS is, there is one rule to follow:

Move all your critical CSS rules within <style> tag and place it in the <head>.

You might have heard the term Critical Path before. Page start rendering when browser downloads all CSS. A critical path is the minimum amount of styles the page needs to start showing its above-the-fold (upper half of the page) content.

There is no async attribute like in the <script> tag and if you have a large CSS file that has nothing to do with the upper half of the page you are obviously not on the critical path. To simulate asynchronous <link rel=”stylesheet” href=”styles.css” /> tag, Google recommends using JavaScript.

<script>
  var loadDeferredStyles = function() {
    var addStylesNode = document.getElementById('deferred-styles');
    var replacement = document.createElement('div');
    replacement.innerHTML = addStylesNode.textContent;
    document.body.appendChild(replacement);
    addStylesNode.parentElement.removeChild(addStylesNode);
  };
  var raf = requestAnimationFrame || mozRequestAnimationFrame || webkitRequestAnimationFrame || msRequestAnimationFrame;
  if (raf)
    raf(function() {
      window.setTimeout(loadDeferredStyles, 0);
    });
  else window.addEventListener('load', loadDeferredStyles);
</script>

If we take a closer look at Google's JavaScript snippet, we can see that it is adding CSS file after the browser parsed HTML.

Important: If you load all your CSS files this way, some of them will still be flagged as render-blocking, because their rules will modify above-the-fold elements.

We split styles into two, first are the CSS rules that target above-the-fold elements. Second are for the rest.

First CSS rules are in the internal stylesheet in the head (between <style> tag). Second CSS rules will add with JavaScript.

It is easy to do that on paper and a nightmare to implement on a real project. Most guides and tutorials, don’t dive deep or show only the theory on single page or project without any sophisticated frameworks.

The next steps should help you make the CSS modifications on any project/website.

For the cases lets have the following CSS files:

<link href="bootstrap.css" rel="stylesheet" type="text/css" />
<link href="styles.css" rel="stylesheet" type="text/css" />

Case 1: Using Bootstrap or similar framework/library.

Solution: Most of the frameworks let you choose the components you want to use. In the case of Bootstrap, for instance, you can download only their Grid system from the Customize page.

I have chosen all the components that are used throughout the site and generated custom-bootstrap.css then left a comment with the list of packages I have checked. In the future, if I want to add or remove components will create another file and update the comment.

Important: Every custom bootstrap comes with normalize.css. It means that if you have two generated files, the second will probably reset the first one.

There are steps of how to identify critical CSS in Case 2. With this method, you can see which Bootstrap components you are using.

Case 2: How to identify which styles are critical.

Solution: This one can be a real pain when the website is unfamiliar.

I found that for me the easiest way to identify and extract critical CSS rules is with Critical Path CSS Generator web tool. However, there are many options like browser extensions, web tools or JavaScript module.

These are the most simple steps in my opinion:

  1. Place the webpage of interest into the PageSpeed Insights.
  2. Check which CSS files are render-blocking.
  3. Go to the Critical Path CSS Generator and place the same page URL into the 1. URL box.
  4. On the second 2. FULL CSS box place one of the render-blocking CSS. You must place the content, not the URL itself.
  5. Click on the button 3. Create Critical Path CSS.
  6. A box will appear on the right called Critical Path CSS with all CSS that is blocking out the page from rendering. (This is the CSS you must remove and place it in the <head>)
  7. The same steps from (2) must be repeated for the other render-blocking (if any) CSS files.

With trial and error from step 6, you can identify all CSS rules that need to be removed and placed it in the <head>.

These steps helped me identify critical styles in all my projects.

Example: How I organized styles on our website.

Using CSS preprocessors like Less or Sass can make your life easier. Usually I create less/scss file, let’s call it critical.less, that combines all my critical CSS and place it in the <head> between <style> tag, for example:

@import './custom-bootstrap.less';
@import './font-awesome.custom.less';
@import './variables.less';
@import './shared.above-the-fold.less';

The custom-bootstrap.less file as mentioned in Case 1 is from Bootstrap Customize page with checked only the needed components.

I love Font Awesome, but do not need to use the whole CSS package. For font-awesome.custom.less I have added only classes that we need on our website, and the font-face rules shrank from 3000 lines of code to less than 100.

From the name variables.less you can conclude that it is for global variables like fonts, colors, sizes, etc.

Finally shared.above-the-fold.less is with all critical CSS rules needed to render pages throughout the website. The file is containing not only all general styles but and the unique ones for the specific pages. You can separate all CSS rules and load only on the needed pages. I prefer it simple.

Combining different pieces with @import into one file makes the afterward support more manageable than creating other files manually. And this general approach to render-blocking CSS will work on your projects too.

Update 11.2019

One of my readers shared with me a great article with 70+ commercial free fonts that might be useful to you, thanks Laurie.

Related articles

© 2021 All rights reserved.