We’re obsessed with speed – how to make websites load faster. As they often say about cars “you can go as fast as you want – how much do you want to spend?” In that way, cars and web design are similar – speed costs time and money. We’ve found that one of the best ways to increase a website’s speed for an affordable cost is implementing Critical CSS. We do it for all custom web design projects. A lot of people don’t know about Critical CSS, though – it’s a bit of a mystery. Let’s get into what it is and how to use it so you can speed up your website’s loading time and PageSpeed Score. As a side benefit, you’ll turn coffee into beer. Promise.

What is Critical CSS?

If you’ve tested a website’s speed and gotten a message like Eliminate render-blocking JavaScript and CSS in above-the-fold content or Eliminate render blocking CSS then you know what Critical CSS isn’t. The full message usually reads something like

Your page has 2 blocking CSS resources. This causes a delay in rendering your page.

None of the above-the-fold content on your page could be rendered without waiting for the following resources to load. Try to defer or asynchronously load blocking resources, or inline the critical portions of those resources directly in the HTML.

Optimize CSS Delivery of the following:

https://yourdomain.com/some/path/to/some/file.css
https://yourdomain.com/some/path/to/some/other/file.css

And when you follow that Optimize CSS Delivery link, you get some helpful information from Google like

Before the browser can render content it must process all the style and layout information for the current page. As a result, the browser will block rendering until external stylesheets are downloaded and processed, which may require multiple roundtrips and delay the time to first render. See render-tree construction, layout, and paint to learn more about the critical rendering path, and render blocking CSS for tips on how to unblock rendering and improve CSS delivery.

But then it gets into a lot of pretty heavy stuff, which gets kind of depressing. So you go get some coffee and probably a snack and maybe put on that new N.E.R.D. album (Lemon is pretty hot) and try to forget about it all. Been there.

It doesn’t have to be depressing. Let’s break it down. Google is saying what is true. A browser has to load up and parse all of the markup (HTML) and styling (CSS) before it can render a page. It also has to do the same for all the Javascript, though that’s a subject for another discussion. View source on your page and go from top to bottom and open all those CSS stylesheets. You won’t get very far before you go get more coffee. By the time you get back, the browser is probably still not showing anything because it’s busy going through all those stylesheets. All joking aside, there’s gotta be a better way.

This is where Critical CSS comes in – take all that CSS, strip out only what is needed to show the above-the-fold content, put that CSS directly into the <head> section, defer the rest of the CSS into the footer of the page with Filament Group’s loadCSS or by outright moving the <link rel="stylesheet" type="text/css" href="path/to/your/css/style.css"> right into the bottom of the page (argh, I know, CSS isn’t supposed to go there), and then go get a beer because you just sped everything up and got rid of those Eliminate render blocking CSS messages. Drink that beer and send your client a nice invoice.

Why Use Critical CSS?

Because speed. Because awesome. Because you can. But really, it’s important. So here’s how you justify the beer you just drank and the invoice you just sent. There’s a zillion online statistics from famous people like Amazon and Intuit and Google and whatnot that can tell you how much page speed affects everything. The truth is, you’re reading this because you want to figure out how to eliminate render blocking CSS and speed up your website. So let’s get on with it.

Above the fold is a super ancient graphic design term that comes from newspaper printing days. It refers to the part of the newspaper that was visible above the part that got folded in half. Paper – remember that?

What is Above The Fold?

Above the fold is all the content a viewer sees before scrolling. In other words, it is the most important part of a website – the stuff an impatient viewer is sitting there (still?) waiting for. There is no universally defined pixel height of what is considered above the fold content – the web is fluid and there are many devices out there like your phone, your fridge, your new car.

External CSS – any CSS loaded up via an external stylesheet – that is required to render this top section of the page is considered render blocking because it does just that – blocks the rendering of the page until it can be loaded up and parsed.

Critical CSS is kind of like the opposite of render blocking CSS – the minimum, most critical part of the styling needed to show the top of a page. It usually contains all the styling for the grid framework, the navigation and basic font styling. In order to generate Critcial CSS, you will need to pick a point on the page above which you consider the CSS to be Critical. That point is arbitrary and up to you. We use a safe number around 1,300 pixels.

If you want to know exactly what *Google* thinks is above the fold, insert viewportsizes.com/mine/ into Google’s PageSpeed Insights and squint to see the results

This is all great, but how do I generate and add Critical CSS?

Okay – enough beating around the bush. Let’s get to business. Here’s how to do it.

The best free resource for generating Critical CSS is the awesome Critical Path CSS Generator by Jonas Ohlsson Aden. You’ll see more about him later, as he’s taken this great resource to even better places.

  1. Paste the url for your page
  2. Copy and paste *all* the css for your page – even the Bootstrap or Foundation framework styling
  3. Sit back and enjoy that beer
  4. Copy the generated Critical CSS into a <style> tag way up high in the <head> of your page
  5. Move that <link rel="stylesheet" type="text/css" href="../path/to/your/style.css"> down to the bottom of your page above the </body> tag, down with all the <script>...</script> tags
  6. Load up that new Critical CSS powered page in Google’s PageSpeed Insights and rejoice at not seeing those peksy Eliminate render-blocking CSS in above-the-fold content messages
  7. Sit back and enjoy that beer

Your minified Critical CSS in a <style> tag in the <head> should look something like this (with a whole lot more CSS)

<!DOCTYPE html>
<html lang="en-US" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#" itemscope itemtype="https://schema.org/LocalBusiness">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <style>@charset "UTF-8";*,::after,::before{-webkit-box-sizing:border-box;box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;
    nav{display:block}body{margin:0;font-family:proxima-nova,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:1rem;font-weight:300;line-height:1.5;color:#222;text-align:left;background-color:#fff}</style>
    <meta name="mobile-web-app-capable" content="yes">

Challenges

If you’re hand coding websites, then you’re off to the races. Follow the above steps, rinse and repeat. You’re done.

Most people aren’t hand coding websites. You’re probably using some kind of Content Management System like WordPress. In that case, you have a couple problems to deal with

  1. You’re dealing with a lot of pages
  2. You can’t efficiently add different Critical CSS to every page
  3. Your website may load a ton of different CSS stylesheets

Solutions

Here’s how we deal with these challenges

  1. You’re dealing with a lot of pages – Lots of pages get generated from some form of templating. Focus on breaking out your templates into groups and figure out what pages could use the same Critical CSS
  2. You can’t efficiently add different Critical CSS to every page – Computers are good at batching. Let the machines do the work
  3. Your website may load a ton of different CSS stylesheets – Try not to do this. It slows down your website and that’s bad for business. If you’re using a Sass workflow, combine all these CSS files into one. Then you have only one main CSS file to pull your Critical CSS out of and only one CSS file to move to the bottom of the page

Our Workflow – Gulp + Penthouse = Kapow!

We use Gulp – a JavaScript toolkit – to automate a lot of the pesky tasks involved with web development. Generating Critical CSS over and over each time there’s a style change that affects above the fold content can be pesky to say the least. So Gulp is an ideal tool to automate the process.

To actually generate the Critical CSS, we initially used Filament Group’s CriticalCSS generator, which is awesome. I’m not a historian but Filament Group seemed to be one of the first on the scene. However the repository isn’t updated very often.

Jonas Ohlsson Aden (remember him, he developed the awesome + free Critical Path CSS Generator) pointed us towards the Critical CSS generator Penthouse that he’s the creator of. It’s faster more frequently updated. We switched over to use Penthouse to do the heavy lifting of generating the Critical CSS. Penthouse has a ton of great documentation with examples from simple implementation to batching up lots of pages at a time.

This setup has been working like a gem to do lots and lots of Critical CSS generating:

  1. Add Penthouse via npm to the package.json dependencies:
    "dependencies": {
        "penthouse": "^1.4.0"
      }
    
  2. Add the following to the gulpfile.js requirements:
    var penthouse = require("penthouse");
    var fs = require('fs');
    var urlList = require('./criticalcss-pagelist.json')
  3. Add a variant of the following to the gulpfile.js. We’re writing the output as PHP files wrapping around the CSS, as we’re going to be inserting the Critical CSS for each page into the <head> section via PHP but you can adjust the fs.writeFileSync() to your needs. The below includes all options but you of course don’t need to include them all
    // Run:
    // gulp criticalcss
    // Generates CriticalCSS for above-the-fold content - look to criticalcss-pagelist.json for list of input pages and output files
    gulp.task('criticalcss',function(){
      urlList.urls.forEach(function(item,i){
        penthouse({
          url: item.link,  // can also use file:/// protocol for local files
          css: './css/style.min.css',  // path to original css file on disk
          width: 1300,  // viewport width
          height: 900,  // viewport height
          keepLargerMediaQueries: false,  // when true, will not filter out larger media queries
          forceInclude: [ // selectors to keep, useful for above-the-fold styles added by js scripts
            '.keepMeEvenIfNotSeenInDom',
            /^\.regexWorksToo/
          ],
          propertiesToRemove: [
            '(.*)transition(.*)',
            'cursor',
            'pointer-events',
            '(-webkit-)?tap-highlight-color',
            '(.*)user-select'
          ],
          userAgent: 'Penthouse Critical Path CSS Generator', // specify which user agent string when loading the page
          puppeteer: {
            getBrowser: undefined, // A function that resolves with a puppeteer browser to use instead of launching a new browser session
          }
        })
        .then(criticalCss => {
          // use the critical css
          fs.writeFileSync('./'+item.name+'.php',"%MINIFYHTML120504e5e373744bbc9e6fd61d4e7e5213% ");
        })
        .catch(err => {
            // handle the error
        })
      })
    })
  4. Add a list of URLs to parse and a list of files to write by adding a variant on this to a criticalcss-pagelist.json file. The "link" is the page to parse for Critical CSS based on the configuration in your gulpfile.js and the "name" is the name of the file containing the above-the-fold Critical CSS to output for each corresponding page. In this case we’re referencing local pages but you can use live pages (though it’s slower).
    {
      "urls": [
        {
          "link": "https://local-alexwright.net/",
          "name": "criticalcss/home"
        },
        {
          "link": "https://local-alexwright.net/westlake-plastic-surgery/",
          "name": "criticalcss/portfolio-project"
        },
        {
          "link": "https://local-alexwright.net/free-seo-analysis/",
          "name": "criticalcss/seo-analysis"
        },
        {
          "link": "https://local-alexwright.net/free-seo-analysis-report/",
          "name": "criticalcss/seo-analysis-results"
        }
      ]
    }

    It’s worth noting that if you run a lot of pages all at once, Penthouse can time out. Check this great reference for information on batching up Penthouse runs so your poor computer doesn’t explode.

  5. Run gulp criticalcss and watch as computers do what they’re good at – lots of busywork
  6. Add each generated Critical CSS element to the <head> of each page as needed. We’re in a WordPress workflow, so we add something like this into the header.php file
    <?php if( is_front_page() ) :
    get_template_part( 'criticalcss/home' ); 
      elseif( in_category( 13 ) ) :
    get_template_part( 'criticalcss/portfolio-project' );
      elseif(is_page ( 382 ) ) :
    get_template_part( 'criticalcss/seo-analysis' );
      elseif(is_page ( 384 ) ) :
    get_template_part( 'criticalcss/seo-analysis-results' );
      else :
    endif ?>

    Another option to accomplish this in a WordPress workflow is to use the wp_head() action hook in the functions.php

    add_action( 'wp_head', 'criticalcss');
    function criticalcss() { 
     if( is_front_page() ) {
        get_template_part( 'criticalcss/home' );
     }
     else if( in_category( 13 ) ) {
        get_template_part( 'criticalcss/portfolio-project' );
     }...
    }

    While this works just fine, the first solution of adding conditional tags directly in the head works to get the Critical CSS files higher up in the head section, which is better as the browser gets to the Critical CSS files sooner.

  7. We then use Autoptimize to – among other things – defer our single main style.css file into the footer. Another alternative, or if you want to do this manually, you can use Filament Group’s loadCSS (which Autoptimze uses). Even large, complex websites can get 95 and above on Google PageSpeed Insights (try running this website through that tool)

Are you using a high caliber Critical CSS workflow? Or does none of this make any sense at all? Are you drinking beer, or coffee? Let us know in the comments. And mega special thanks to Jonas Ohlsson Aden for all his work on Penthouse and for suggesting great changes to this post including making things actually correct.

Update

Updated to include new Penthouse functionality – thanks to Jonas Ohlsson Aden. He’s working on a new way to batch up larger runs of Critical CSS generation and we’ll update this post with those details when we get them.

blog post author avatar
Written with by Alex Wright

Runs a creative digital marketing, web design and SEO agency in Austin, Texas   |   Likes good looking, fast performing and high ranking websites   |   Doesn't want to understand Snapchat   |   Wants nothing to do with bananas   |   Wishes he were a BMX superstar

4 thoughts on “How To Use Critical CSS

    1. more time than you might think, and on a bigger site like it can really add up. conversion rates go up a lot when loading time goes down even my small amounts.

Leave a Reply

Your email address will not be published. Required fields are marked *