Optimize CSS Delivery

This rule triggers when PageSpeed Insights detects that a page includes render blocking external stylesheets, which delay the time to first render.

Overview

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.

Recommendations

If the external CSS resources are small, you can insert those directly into the HTML document, which is called inlining. Inlining small CSS in this way allows the browser to proceed with rendering the page. Keep in mind if the CSS file is large, completely inlining the CSS may cause PageSpeed Insights to warn that the above-the-fold portion of your page is too large via Prioritize Visible Content. In the case of a large CSS file, you will need to identify and inline the CSS necessary for rendering the above-the-fold content and defer loading the remaining styles until after the above-the-fold content.

Example of inlining a small CSS file

If the HTML document looks like this:
<html>
  <head>
    <link rel="stylesheet" href="small.css">
  </head>
  <body>
    <div class="blue">
      Hello, world!
    </div>
  </body>
</html>
And the resource small.css is like this:
  .yellow {background-color: yellow;}
  .blue {color: blue;}
  .big { font-size: 8em; }
  .bold { font-weight: bold; }
Then you can inline critical CSS as follows:
<html>
  <head>
    <style>
      .blue{color:blue;}
    </style>
    </head>
  <body>
    <div class="blue">
      Hello, world!
    </div>
    <noscript id="deferred-styles">
      <link rel="stylesheet" type="text/css" href="small.css"/>
    </noscript>
    <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 = window.requestAnimationFrame || window.mozRequestAnimationFrame ||
          window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
      if (raf) raf(function() { window.setTimeout(loadDeferredStyles, 0); });
      else window.addEventListener('load', loadDeferredStyles);
    </script>
  </body>
</html>

This transformation, including the determination of critical/non-critical CSS, inlining of the critical CSS, and deferred loading of the non-critical CSS, can be made automatically by the PageSpeed Optimization modules for nginx, apache, IIS, ATS, and Open Lightspeed, when you enable the prioritize_critical_css filter.

See also the loadCSS function to help load CSS asynchronously, which can work with Critical, a tool to extract the critical CSS from a web page.

The critical styles needed to style the above-the-fold content are inlined and applied to the document immediately. The full small.css is loaded after 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.

Note that the web platform will soon support loading stylesheets in a non-render-blocking manner, without having to resort to using JavaScript, using HTML Imports.

Don't inline large data URIs

Be careful when inlining data URIs in CSS files. While selective use of small data URIs in your CSS may make sense, inlining large data URIs can cause the size of your above-the-fold CSS to be larger, which will slow down page render time.

Don't inline CSS attributes

Inlining CSS attributes on HTML elements (e.g., <p style=...>) should be avoided where possible, as this often leads to unnecessary code duplication. Further, inline CSS on HTML elements is blocked by default with Content Security Policy (CSP).

Feedback

Was this page helpful?