5 tips to clear up rendering blocking resources and speed up your website

Render-blocking resources are static files, such as fonts, HTML, CSS, and JavaScript files, that are essential to the rendering process of a web page. When the browser encounters a rendering blocking resource, it stops downloading the rest of the resources until these critical files are processed. During this time, the entire rendering process is put on hold. On the other hand, resources that do not block rendering do not delay the rendering of the page.

The browser can safely download them in the background after the page has been initially rendered.

However, not all resources that the browser considers blocking rendering are essential for the first render; it all depends on the individual characteristics of the page. There are best practices you can use to turn these non-critical render-blocking resources into non-render-blocking resources. In addition, you can also decrease the number and/or size of rendering blocking resources which are still critical and cannot be eliminated.

Why eliminate resources blocking rendering?

If you reduce the number of render-blocking resources, you can shorten the critical render path and reduce page load times, improving user experience and search engine optimization.

There are three ways to reduce the number and impact of rendering blocking resources:

Make them non-blocking resources for rendering by deferring their download.

Decrease the total number of resources blocking rendering by using techniques such as grouping (which also means fewer HTTP requests).

Reduce the size of a resource by minifying it so that the page has fewer bytes to load.

The 5 types of resources blocking rendering

Typically, the browser treats anything it finds in the <head> section of an HTML page as a render-blocking resource.

This includes :

  • CSS style sheets
  • JavaScript files added in the <head> section.
  • fonts added from CDN or local server
  • HTML imports (even though HTML imports are now obsolete, you may still encounter them on older pages)
  • Images, media files, and <script> tags placed at the bottom of the <body> section are treated as non-rendering blocking resources.

Now let’s zoom in on five strategies for eliminating or reducing the number and impact of resources blocking rendering.

1. Do not add CSS with the @import rule

You can add CSS to a page using either of the following two methods:

The <link rel = “stylesheet”> tag that you must add to your HTML file.

The @import rule that you need to add to your CSS file.

While the @import rule will keep your HTML file cleaner and keep all of your CSS dependencies in one place, it’s not the best choice for performance. The @import rule allows you to import style sheets from other style sheets, but it slows down the browser’s processing of your CSS file because it must also download the imported files.

Until this download has taken place, the rendering process will be blocked.

If you want to add more than one CSS file to your page, you can either use the <link> tag or chain the files together using a minification and/or grouping tool.

You must add the <link> element to the <head> section of the HTML page as follows:


  <link href = “style.css” rel = “stylesheet”>


2. Use the media attribute for conditional CSS

By default, the browser treats all CSS files as rendering blocking resources. However, if you add the media attribute to the <link> tag, you can indicate to the browser the presence of a conditional CSS file.

Conditional CSS only applies under certain conditions, such as below or above a given window size or on a printed page. With the media attribute, you can define a specific media condition for a CSS file. You can use any value you would use for a media query in a CSS file.

For example :

<link href = “print.css” rel = “stylesheet” media = “print”>

<link href = “large.css” rel = “stylesheet” media = “screen and (min-width: 1500px)”>

<link href = “mobile.css” rel = “stylesheet” media = “screen and (max-width: 600px)”>

Even though these files are still downloaded on all devices, they become non-rendering blocking resources if the condition is evaluated as false. However, they will still render blockers if the condition is evaluated as true.

For example, the mobile.css stylesheet in the example above will be blocking for rendering on mobile devices with a maximum viewport width of 600px and non-blocking for viewports larger than 600px. If you have an existing CSS file with one or more media queries, you can extract all @media rules and save them as separate files using this PostCSS plugin. This technique for optimizing performance is also referred to as code splitting.

While code splitting is usually associated with JavaScript, you can also split larger CSS files and load each file only when necessary in order to shorten the critical render path and reduce the initial page load time.

3. Use the defer and async attributes to eliminate rendering blocking JavaScript.

JavaScript files added to the <head> section of the document are treated by default as rendering blocking resources. You can remove them from the critical render path by placing the <script> tags just before the closing </body> tag instead of the <head> section.

In this case, they don’t start downloading until you have downloaded all of the HTML. However, since the download of these scripts starts later, the stuff they load, like ads, animations, or dynamic features, may load later than the rest of the frontend – especially if it’s a longer script. This can lead to noticeable delays and lagging user interfaces on slower connections, which is bad for the user experience.

The defer and async attributes of the <script> tag provide a solution to this problem. They are both Boolean attributes, meaning if you add them they will fire without further configuration. They also allow scripts added to the <head> section of an HTML document not to block rendering, but in a different way – lazy scripts respect document order while asynchronous scripts are DOM independent.

The defer attribute tells the browser to download the script in the background so that it does not block the rendering of the page. The lazy script runs after the DOM is ready but before the DOMContentLoaded event fires.

<script src = “script01.js” defer> </script>

<script src = “script02.js” defer> </script>

Deferred scripts follow the order of the document, as do default, non-deferred scripts. So, in the example above, script01.js will be executed first, regardless of which script loads first. You cannot add defer to scripts online; this only works with external scripts that specify the location of the script using the src attribute.

On the other hand, the async attribute informs the browser that a script is completely independent of the page. It will be downloaded in the background as a non-rendering blocking resource, just like deferred scripts.

However, unlike deferred scripts, asynchronous scripts do not follow the order of the document, so they run as soon as their download is complete, which can happen at any time.

For example, in the example below, we can’t be sure which script will run first; it only depends on which one downloads the fastest (usually the smallest). Remember that asynchronous scripts are independent of both the document and each other, so the order of the document will not affect them.

<script src = “script03.js” async> </script>

<script src = “script04.js” async> </script>

4. Collapse and group CSS and JavaScript

In addition to removing non-essential CSS and JavaScript from the critical rendering path, you can also collapse and group resources that block rendering and those that don’t.

For example, you can create groups for files that use the same loading rules and minify each package separately. Because minified files are lighter, and groups involve fewer files in the critical render path, the initial rendering of the page will complete faster. In addition, it will take less time to download resources that do not block rendering in the background.

There are many tools available to help you perform best practice minification and grouping, including Minify, CSS Minifier, Minify Code, and PostCSS.

5. Locally load custom fonts

Because custom fonts are called from the <head> section of the document, they are also rendering blocking resources.

For example :

<link href = “https://fonts.googleapis.com/css2?family=Lato&display=swap” rel = “stylesheet”>

You can reduce the impact of custom fonts on the initial look of the page by adding them locally rather than pulling them from a content delivery network like Google’s CDN. Font providers tend to add multiple @ font-face rules, many of which are unnecessary.

For example, Google Fonts adds @ font-face rules for all character sets provided with a character, such as Latin, Cyrillic, Chinese, Vietnamese, etc. Say, for example, that the inline CSS file that you add with the <link> tag has @ font-face rules for seven different character sets, but you only want to use one (for example, the Latin). However, Google Fonts fonts do not download font files for all character sets; they just add lots of redundant @ font-face rules to the CSS file.

If you add the fonts locally, you can also collapse your CSS relative to the fonts and bundle it with the rest of your CSS. You can use the Google Web Fonts Helper to quickly generate local @ font-face rules for Google Fonts fonts.

For example, here is what you need to add to include the Lato Regular font face:

  • / * lato-regular – latin * /
  • @ font-face {
  •   font-family: ‘Lato’;
  •   font-style: normal;
  •   font-weight: 400;
  •   font-display: swap;
  •   src: local (‘Lato Regular’), local (‘Lato-Regular’),
  •   url (‘../ fonts / lato-v16-latin-regular.woff2’) format (‘woff2’),
  •   url (‘../ fonts / lato-v16-latin-regular.woff’) format (‘woff’);


Note that the Google Web Fonts Helper does not add the font-display: swap rule; I added it myself to the above statement. This is a descriptor for the @ font-face rule that allows you to specify how the browser should display the font face on the page.

Using font-display with the swap value tells the browser to immediately start using a system font and replace it with the custom font as soon as it is downloaded (this rule is also added when you

pull the font from the CDN of Google). This allows you to avoid having invisible text on the page while the custom font is still loading.

When loading fonts locally, be sure to serve compressed font formats for modern browsers, such as WOFF and WOFF2. Keep in mind that smaller files also reduce the impact of blocking rendering resources. Besides generating @ font-face rules, Google Web Fonts Helper also allows you to download a zipped file that contains all the font formats you need.

Summary of resources blocking rendering

In this article, we covered five strategies for eliminating rendering blocking resources. To summarize :

Don’t use CSS imports

Load conditional CSS with media attributes

Use the defer and async attributes to eliminate JavaScript that blocks rendering.

Split, group, and collapse CSS and JavaScript files.

Load custom fonts locally

To locate your render-blocking files, you can use performance analysis tools such as Lighthouse, web. dev (the same tool as Lighthouse, but built into a web application), GTmetrix, etc. In addition to helping you find render-blocking resources, these tools offer practical tips to help you improve your site’s performance.

Leave a Comment

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

Scroll to Top
× How can I help you?