Fix & Eliminate Render Blocking Resources

Page Speed Checklist

Streamline Loading For Page Speed

Fix and eliminate render blocking resources by reconfiguring the loading process with a progressive approach - separating and loading critical and non-critical resources with appropriate priority.

Jump To The Result

The file resources of a website like HTML, CSS and JavaScript work together to form the content, visual styling and functionality users see and interact with in the browser.

HTML code is the foundation of each page and coordinates how those resources are loaded. Optimizing the structure of file references in the HTML is an important step to streamline the loading process and ensure that pages load quickly and efficiently.

What Is Render Blocking?

If you've run a website loading speed test like Google's PageSpeed Insights, you may have seen an opportunity noted in the test results like Eliminate render-blocking resources. Avoiding or eliminating render blocking resources altogether is a powerful strategy to maximize website speed and ace speed tests.

To make the needed changes and get the best results, it can help to take a closer look at render blocking and why it matters.

The Loading Process

When a user navigates to a page, the web browser first loads and examines the HTML code. Any external resources referenced in the HTML like CSS, JavaScript files and images are downloaded and applied to the page.

This sequence of interpreting the page and its resources into the content displayed on screen is known as the critical rendering path and is important for page speed, particularly the initially-visible, above-the-fold content.

Render Blocking Resources

Render blocking refers to the way conventional CSS <link> and JavaScript <script> references interrupt the rendering process while those resources load and apply to the page.

HTML
<!-- other <head> stuff -->

<!-- conventional render blocking CSS & JavaScript references -->
<link rel="stylesheet" href="styles.css">
<script src="scripts.js"></script>

</head>

The result is a delay in the display of content to the user, during which time the page may appear blank or incomplete. Eliminating render blocking resources is essential to minimize this delay so the page can load and display content as soon as possible.

A Progressive Approach

For very simple pages with only a few small files transferred over a fast internet connection, the loading process is nearly instantaneous. However as content and features become more complex and CSS and JavaScript files become larger, more numerous or loaded over slower internet speeds, the effect of render blocking resources on page speed becomes significant.

Eliminating render blocking resources is the foundation of a progressive approach to page loading.

Loading Priority

On most webpages, the majority of the total CSS and JavaScript loaded by the browser isn't needed to display only the initially-visible or above-the-fold parts of the page, so it makes sense to load these resources with appropriate priority.

Rather than loading all files before the page is displayed on screen, a more efficient, user-friendly strategy is to structure the loading process to prioritize only the most critical resources to load as soon as possible. Lower-priority CSS and JavaScript resources that are not essential to the initially-visible part of the page can then be loaded in the background without render blocking and apply to the page later in the loading process.

Critical vs Non-Critical Resources

The exact CSS and JavaScript considered high priority or critical will depend on the content, layout and functionality of each page, but will likely focus on above-the-fold content elements.

Eliminating render blocking resources is important for both CSS and JavaScript, but most (if not all) JavaScript can be safely deferred to load in the background and run toward the end of the loading process. CSS however can benefit from an extra step - identifying and separating high and low priority resources and loading them accordingly.

Eliminate Render Blocking CSS

Separate and inline critical CSS directly in the HTML and load non-critical CSS asynchronously to fully eliminate all render blocking CSS resources.

Loading CSS styling for above-the-fold content as soon as possible avoids the unpleasant user experience of seeing unstyled content before the CSS is applied - sometimes called a flash of unstyled content.

So how do you eliminate render blocking CSS if it's necessary to properly display the page?

For CSS, a priority-oriented approach means loading and applying only the most critical styling first, while loading non-critical CSS in the background without further delaying the initial display of the page.

A typical setup for critical and non-critical CSS looks like this:

HTML
<!-- other <head> stuff -->

<!-- very small file for critical CSS (or optionally inlined with a <style> block) -->
<link rel="stylesheet" href="critical.css">

<!-- async non-critical CSS -->
<link rel="stylesheet" media="print" onload="this.onload=null;this.removeAttribute('media');" href="non-critical.css">

<!-- no-JS fallback for non-critical CSS -->
<noscript>
    <link rel="stylesheet" href="non-critical.css">
</noscript>

</head>

Critical CSS

Critical styles are those that apply to the initially-visible or above-the-fold elements of the page. This can be done with a small, conventionally-loaded (and purposefully render blocking) external CSS file:

HTML
<!-- other <head> stuff -->

<link rel="stylesheet" href="critical.css"> <!-- under ~10KB -->

</head>

In this case the render blocking effect is desirable to avoid unstyled content from appearing before the CSS is applied - sometimes called a flash of unstyled content - which can be disorienting to users. This single render blocking file should be kept as small as possible, ideally under ~10KB minified and compressed.

Inline Critical CSS

A single small render blocking CSS file is a good strategy for critical CSS and doesn't impact page speed on an otherwise well-optimized page. But what if you want to eliminate all render blocking CSS resources?

To eliminate all render blocking CSS, critical styles can be added to the page as an inline style block. This technique avoids the render blocking effect of a separate file reference by embedding the critical CSS directly in the HTML.

HTML
<!-- other <head> stuff -->

<style>.main-menu{...}.main-menu a{...}/*-- etc --*/</style>

</head>

A potential downside to this method is that inline CSS won't be cached by the browser and is therefore re-loaded each time the page is viewed. HTTP/2 may also make this method less advantageous.

Non-Critical CSS

Non-critical CSS resources for content that isn't initially visible should be loaded in the background without blocking further rendering of the page. The render blocking effect of non-critical and other low-priority CSS can be eliminated with asynchronous CSS loading:

Asynchronous CSS

The recommended method for most cases uses a combination of the media attribute and a bit of inline JavaScript:

HTML
    <!-- other <head> stuff like critical CSS -->

    <link rel="stylesheet" href="non-critical.css" media="print" onload="this.onload=null;this.removeAttribute('media');" fetchpriority="high">

    <!-- no-JS fallback -->
    <noscript>
        <link rel="stylesheet" href="non-critical.css">
    </noscript>

</head>

This technique loads the non-critical CSS in the background and with a low priority, although as shown, an optional fetchpriority="high" attribute can be added to increase loading priority. Since it relies on JavaScript, a conventional <link> reference is an easy fallback.

Media Conditions

Media queries are another great way to manage render-blocking CSS by selectively prioritizing critical resources based on conditions like screen size. All files will be downloaded, but with appropriate priority, and only CSS with matching media conditions will block rendering.

HTML
<link rel="stylesheet" href="critical-general.css">
<link rel="stylesheet" href="critical-large.css" media="(min-width:60em)">

Eliminate Render Blocking JavaScript

Eliminate the render blocking effect of JavaScript resources with the purpose-made defer attribute on external <script> references.

Much of the same CSS concepts apply to optimizing JavaScript resources, however JavaScript typically acts on the content after the page is otherwise loaded so in most cases all JavaScript can be defer'd to load in the background and execute later in the loading process.

HTML
<!-- other <head> stuff -->

<script defer src="sitewide.js"></script>
<script defer src="jquery.min.js"></script>
<script defer src="page-specific.js"></script>

</head>

(The similar async attribute can be a good option as well, but may interrupt rendering to execute.)

async & defer

Unlike CSS, JavaScript references can use the async and defer attributes to instruct those files to download in the background at a low priority without interrupting the rendering process. Although their loading behavior is the same, async and defer follow different rules for when the JavaScript runs.

As in the example above, one of the benefits of the async and defer attributes is that <script>s can be kept in the <head> section to be discovered and begin downloading early in the loading process.

Learn more about the difference between async and defer and how to use them strategically for page speed:

Async & Defer

Inline JavaScript

All inline JavaScript can potentially be moved to one or more separate files to maximize caching. If some inline <script> blocks can't be avoided and they also rely on a defer'd external file (jQuery for example) the inline JavaScript can be wrapped with a DOMContentLoaded event listener to ensure that they execute after the defer'd file:

HTML
<!-- other <head> stuff -->

<script defer src="scripts.js"></script>
<script defer src="jquery.min.js"></script>

</head>
<body>
    <!-- page content -->

<script>
    document.addEventListener('DOMContentLoaded', function(){
        // more jQuery-dependent stuff
    });
</script>

</body>

Javascript contained in a defer'd file that depends on another defer'd file can use this same kind of event listener. For example, if along with some vanilla JavaScript that should load and run first, the scripts.js file above also contains some jQuery code that relies on jquery.min.js, that jQuery code can be wrapped with a DOMContentLoaded event listener to ensure that it runs after jQuery.

Eliminate Render Blocking Google Fonts

Custom, stylish fonts are an easy way to add visual interest, establish branding and give your website a unique look, and Google Fonts makes it as easy as adding one line of code to include one or more fonts to the page.

That one line is a <link> reference to a CSS file, which by nature is render blocking. This means that the render blocking effect of Google Fonts can be eliminated with the same asynchronous CSS technique that's commonly used for other non-critical or low-priority CSS resources.

But don't stop there. Combine async CSS loading with the preconnect resource hint to speed up Google Fonts even more:

Optimize Google Fonts

Eliminate Render Blocking Google Analytics

Whether you prefer to use the conventional asynchronous snippet or the Global Site Tag version of the tracking code, Google Analytics can also be reconfigured to eliminate render blocking resources and minimize the impact on page speed.

As with other JavaScript references, Google Analytics can use the defer attribute on the external <script> reference to load in the background without interrupting the loading process. The inline JavaScript snippet can also be moved to a defer'd external file for the same effect.

Eliminate the render blocking effect of Google Analytics in two simple steps:

Defer Google Analytics

Eliminate Render Blocking jQuery

As with other JavaScript resources, the render blocking effect of jQuery can be eliminated by adding the defer attribute to the <script> reference.

This instructs the browser to load jQuery in the background without delaying the initial display of content on screen.

HTML
<!-- self hosted -->
<script defer src="jquery.min.js"></script>

<!-- or from a CDN -->
<script defer src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

Inline jQuery

It's generally good practice to move all inline <script>s to an external file for deferring and caching, but if you can't avoid inline JavaScript and those <script>s rely on a defer'd file like jQuery, the inline content can be wrapped in an appropriate event listener:

HTML
<script>
document.addEventListener('DOMContentLoaded', function(){
    // jQuery-dependent stuff
});
</script>

The inline jQuery will now run right after the DOMContentLoaded event and after any defer'd files it may depend on (like jQuery) are executed and ready.

All Together

Putting it all together, this example of commonly-used page resources structured for speed includes resource hints, asynchronous CSS and optimized Google Fonts:

HTML
<!doctype html>
<html lang="...">
<head>
<meta charset="utf-8">
<title>...</title>

<!-- critical CSS (under ~10KB or optionally inlined) -->
<link rel="stylesheet" href="critical.css">

<!-- connect to domain of Google Font files -->
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

<!-- asynchronous non-critical CSS (optionally increase loading priority with fetchpriority="high" ) -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" media="print" onload="this.onload=null;this.removeAttribute('media');" fetchpriority="high">
<link rel="stylesheet" href="non-critical.css" media="print" onload="this.onload=null;this.removeAttribute('media');">

<!-- no-JS fallback for non-critical CSS -->
<noscript>
    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap">
    <link rel="stylesheet" href="non-critical.css">
</noscript>

<!-- all JavaScript defer'd -->
<script defer src="scripts.js"></script> <!--  wrap jQuery-dependent content with DOMContentLoaded listener if needed -->
<script defer src="jquery.min.js"></script>
<script defer src="page-specific.js"></script>

</head>

<body>
    <!-- visible content -->
</body>
</html>

Resource Hints

Eliminating render blocking resources is a critical stride to maximize loading speed, but there's one more step we can take.

With a few simple lines of HTML, resource hints help get a jumpstart on 3rd-party connections and strategically load important files like above-the-fold CSS background images.

Resource Hints