How and Why You Should Inline Your Critical CSS

Asha Laxmi
Asha Laxmi
Share
A website stage setting

In the early days of the internet, websites were primarily used to show text based information. Slowly, our connection speeds have improved and users have been able to download high-resolution images and videos fairly quickly. Now websites do a lot more than just provide necessary information in the form of text. Websites are becoming more complicated, with CSS and JavaScript frameworks, plugins galore and more. With all of this in play, loading all the necessary files for all of this can take some time.

A faster website can result in a better user experience, which can make a huge difference in a website’s success. What can developers do to start making performance improvements? One thing that developers can do which helps greatly is to inline critical CSS and load non-critical CSS asynchronously. In this article, we’ll cover these points one-by-one and help you improve your website’s performance.

What is Critical CSS?

The critical CSS in your project is the CSS that’s used to style the above-the-fold content of your website. Above-the-fold content is what users see on your website first, which can include navigation and other elements. So it’s very important to properly style and render this part of the website as quickly as possible.

One thing that I would like to mention here is that your visitors probably use a myriad of devices with different viewports to visit your website. So, above-the-fold content is not going to be of much help by itself. To solve this issue, you should also consider any CSS related to the basic layout and typography to be critical as well.

Modern web development practices often recommend that you inline your critical CSS. It would be placed into your web page like so:

<!doctype html>
<html>
  <head>
    <title>An Optimized Web Page</title>
    <style type="text/css"> (Your minified critical CSS would be here) </style>
  </head>
  <body>
     (Your markup)
  </body>
</html>

Why is Inlining Necessary?

If you head over to Google PageSpeed Insights and analyze one of your web pages, you might see warnings about optimizing your CSS delivery by inlining critical CSS and loading render-blocking stylesheets asynchronously.

Browsers won’t render the above-the-fold content of your web pages unless they have loaded all of your CSS files. This can be a big deal when a lot of files need to be loaded.

Not all of your users will have a fast internet connection and waiting for the libraries, CSS and JavaScript to load before they can actually access the content they came for can be very frustrating. Even users with fast internet can lose connectivity in certain situations, like when they are passing through a tunnel. At this point, they would still be able to access the main content if your website has inlined critical CSS and doesn’t load other files before showing main content.

The image below illustrates the difference between a regular and an optimized web page. As you can see, the optimized version will allow users to access the content about 0.5 seconds earlier. The improvements will be more pronounced when there are a lot of extra libraries that need to be loaded.

Inline CSS loading stages

Should You Inline Critical CSS?

It depends on the situation. If you are not using any heavy frameworks or libraries and your own CSS files also have a small size, then you may not need to inline your CSS.

If you are using a framework like Bootstrap, you are probably not using all the features that the framework offers. In that case, you can just extract the critical CSS from the framework’s stylesheets and load the actual framework asynchronously. This should significantly improve your website’s speed.

While inlining, stylesheets can be cached. HTML often is not cached (it is often not a good idea to do so!). This means there can occasionally be a difference between the two. Keep this in mind when making updates! Also, the inlined CSS will result in some extra page weight every time a user loads your website. For example, if there is 30kB of inline CSS on every page of your website then 10 page views by a single user will cost the user 300kB. It may not sound like a big deal but data is expensive in some parts of the world (and on some 3G/4G data plans). Ensure that the CSS you are planning to inline is genuinely critical to your web page and you are not inlining everything.

Finding Critical CSS

Finding critical CSS manually will be a daunting and boring task. Fortunately, there are tools available that can help you do it quickly.

Using Grunt

If you are familiar with the Grunt build system, there is a plugin which makes this process easier — the popular grunt-critical plugin. If you prefer Gulp or using npm, see the next sections for how to do this process with those.

First, you need to install the plugin using the following command:

npm install grunt-critical --save-dev

You also need to create your Gruntfile.js. This will contain all the code to set various options for the plugin including viewport dimensions and the path to source and destination file. Here is an example:

module.exports = function(grunt) {

  grunt.initConfig({
    critical: {
      extract: {
        options: {
          base: './',
          width: 1024,
          height: 768,
          minify: true
        },
        src: 'path/to/initial.html',
        dest: 'path/to/final.html'
      }
    }
  });

  grunt.loadNpmTasks('grunt-critical');
  grunt.registerTask('default', ['critical']);

};

Inside our wrapper function, we use the grunt.initConfig method to specify all configuration options. In this case, I have specified a base directory in which the source and destination files are to be written. I have also set the minify option to true. This gives me a final minified version of the critical CSS that the plugin extracts. The src property contains the location of our source file which is to be operated against. The dest property contains the location where the final output needs to be saved.

In case the dest file is a stylesheet, the resulting CSS is saved to a file for use in future. However, if the dest property is a markup file (HTML, PHP and so on), then the CSS is inlined and the existing stylesheets are wrapped in a JavaScript function to load them asynchronously. A noscript block is also added for users who have disabled JavaScript. There are other options available as well. You can access the full list of options on critical’s documentation.

Now, you can just run the plugin by typing grunt into the console:

C:\path\to\project>grunt

If your initial file had the following markup:

<!doctype html>
<html>
  <head>
    <title>The Optimizer</title>
    <link rel="stylesheet" href="link/to/stylesheet">
  </head>
  <body>
     <div>All the markup stuff</div>
  </body>
</html>

It will now look like:

<!doctype html>
<html>
  <head>
    <title>The Optimizer</title>
    <style type="text/css">Minified Inlined CSS</style>
    <script id="loadcss">
       JavaScript to load styles asynchronously...
    </script>
    <noscript>
      <link rel="stylesheet" href="link/to/stylesheet">
    </noscript>
  </head>
  <body>
     <div>All the markup stuff</div>
  </body>
</html>

As you can see, this plugin does all your work for you. Now, if you analyze your web page using PageSpeed, you should get a better score. In my case, the score changed from 86 to 95.

There are other plugins available for Grunt that achieve a similar feat — grunt-criticalcss and grunt-penthose. However, when using these plugins you will have to specify the stylesheets from which to extract the critical CSS.

Using npm Modules

Critical is the npm package created by Addy Osmani, it contains the functionality that the grunt-critical plugin uses. You can use it without Grunt to extract and inline critical path or above the fold CSS from a web page using JavaScript and npm. To install the package, you need to run:

npm install critical --save-dev

Once the package has been installed, you need to create a JavaScript file in the project directory and put the following code in it.

var critical = require('critical');

critical.generate({
  inline: true,
  base: 'initial/',
  src: 'homepage.html',
  dest: 'final/homepage.html',
  width: 1366,
  height: 768
});

You can specify a bunch of options to create your optimized web page. Setting inline to true will generate an HTML page with CSS inlined, otherwise a CSS file will be generated. The width and height option set the dimensions of our target viewport. There are a lot of other options like minifying the inlined CSS which you can find on the critical npm package’s documentation. The markup of the optimized web page will look similar to the output by the grunt plugin.

Another npm module that is available for you to use is the critical-css module. This module generates the critical CSS from the supplied URL. The generated CSS can be further processed using a callback function because the grunt plugin is based on this package.

Using Gulp

If you are more comfortable working with Gulp, Addy Osmani recommends Gulp users use the Critical npm module directly. The example he provides on the Critical GitHub page for Gulp users looks like so:

var critical = require('critical').stream;

// Generate & Inline Critical-path CSS
gulp.task('critical', function () {
  return gulp.src('dist/*.html')
    .pipe(critical({base: 'dist/', inline: true, css: ['dist/styles/components.css','dist/styles/main.css']}))
    .pipe(gulp.dest('dist'));
});

The Critical team also have a sample Gulp project showing this in action.

There is also a gulp-critical-css plugin to generate critical CSS. However, this one works by extracting certain selector types from your CSS, rather than by detecting above-the-fold elements and so on.

More Resources

Another tool available is the Critical Path CSS Generator by Jonas Ohlsson. All you have to do is enter your page URL and then supply all the CSS from which you want to extract the critical CSS. Clicking on the “Create Critical Path CSS” button after that will output your CSS.

The article on CSS-Tricks outlines how you can use CSS preprocessors to author critical fold CSS. Additionally, SitePoint has also published an excellent article about optimizing critical rendering path in the past that you can read to gain a deeper understanding of the topic.

Conclusion

Whether you should or shouldn’t inline critical CSS depends on the visiting pattern of your users and the structure of your website. If your website is a one pager and visitors are not going visit it frequently, or if you’ve got a complex site with frameworks and plugins, inlining critical CSS can improve performance significantly.

The only concern about inlining is that it adds additional page weight for each visit. This can be mitigated by using cookies and sending critical CSS only during the first visit while still loading the full CSS file asynchronously and then caching it. It is a little complicated but you get the best of both worlds.

Have you tried inlining CSS in your own projects? How significant were the improvements? Do you have any advice for fellow developers? Let us know in the comments.

Frequently Asked Questions (FAQs) about Inlining Critical CSS

What is the main purpose of inlining critical CSS?

The primary purpose of inlining critical CSS is to speed up the rendering of a webpage. When a browser loads a webpage, it has to parse the HTML, CSS, and JavaScript files. If the CSS is external, the browser has to make an additional HTTP request to fetch it, which can delay the rendering of the webpage. By inlining the critical CSS, you are essentially embedding the CSS rules directly into the HTML document. This eliminates the need for an additional HTTP request, allowing the browser to render the webpage faster.

How can I identify the critical CSS that needs to be inlined?

Identifying critical CSS can be a bit tricky as it varies from page to page. Generally, critical CSS is the minimal amount of blocking CSS that is needed to render the above-the-fold content of a webpage. Tools like Google’s PageSpeed Insights, Critical Path CSS Generator, and Penthouse.js can help you identify and extract the critical CSS.

What are the potential drawbacks of inlining critical CSS?

While inlining critical CSS can improve page load speed, it’s not without its drawbacks. One of the main disadvantages is that it can increase the size of your HTML document. Since the CSS rules are embedded directly into the HTML, it can lead to code redundancy if the same CSS rules are used across multiple pages. This can potentially negate the performance benefits of inlining critical CSS.

How can I inline critical CSS in WordPress?

There are several plugins available that can help you inline critical CSS in WordPress. Some of the popular ones include Autoptimize, Above The Fold Optimization, and W3 Total Cache. These plugins can automatically identify, extract, and inline the critical CSS for you.

Can I use media queries in inlined CSS?

Yes, you can use media queries in inlined CSS. However, keep in mind that the CSS rules within the media queries will not be applied until the media conditions are met. This means that they won’t be part of the critical CSS and therefore, won’t be inlined.

Is it necessary to inline CSS for every webpage?

It’s not necessary to inline CSS for every webpage. In fact, it’s recommended to only inline the critical CSS that is needed to render the above-the-fold content. The rest of the CSS can be loaded asynchronously or deferred until after the initial render.

How does inlining CSS affect SEO?

Inlining critical CSS can have a positive impact on SEO as it can improve page load speed, which is a ranking factor in Google’s search algorithm. However, excessive inlining can increase the size of your HTML document and lead to code redundancy, which can potentially harm your SEO.

Can I inline CSS in an external CSS file?

No, inlining CSS means embedding the CSS rules directly into the HTML document. If the CSS is in an external file, it cannot be inlined. However, you can extract the critical CSS from the external file and inline it in the HTML document.

What is the difference between inlining CSS and using inline CSS?

Inlining CSS refers to the practice of embedding the critical CSS rules directly into the HTML document to speed up page load time. On the other hand, using inline CSS means applying CSS rules directly to the HTML elements using the style attribute. While both methods involve adding CSS rules to the HTML document, they serve different purposes and have different implications on performance and maintainability.

How does inlining CSS affect the browser’s cache?

When you inline CSS, the CSS rules are embedded directly into the HTML document. This means that they won’t be cached separately by the browser. As a result, if the same CSS rules are used across multiple pages, the browser will have to download them for each page, which can increase the total amount of data transferred. On the other hand, if the CSS is in an external file, the browser can cache it and reuse it across multiple pages, reducing the amount of data transferred.