DEV Community

loading...
Cover image for Render-Blocking Resources

Render-Blocking Resources

Tsowa Babangida
Web developer with a passion for inclusive and performant experiences on the web #webperf #webdev
・Updated on ・4 min read

WHAT ARE RENDER-BLOCKING RESOURCES?

Render-blocking resources are resources that prevent the browser from rendering any processed content. And by default, CSS and HTML are render-blocking resources because the browser can not render content until the CSSOM and DOM are constructed.

These render-blocking resources block the first paint of a website or web application.

To prevent this, we can do the following:

  • Identify render-blocking resources,
  • Identify critical resources,
  • Reduce/eliminate render-blocking resources.

IDENTIFYING RENDER-BLOCKING RESOURCES

A Lighthouse audit flags the following resources as render-blocking:

  • A <script> tag that:
    • Is in the <head> of a HTML document,
    • Does not have a defer attribute,
    • Does not have an async attribute
  • A <link rel="stylesheet"> tag that:
    • Does not have a disabled attribute. When this attribute is present, the browser does not download the stylesheet.
    • Does not have a media attribute that matches the user's device.
  • A <link rel="import"> tag that:
    • Does not have an async attribute.

IDENTIFYING CRITICAL RESOURCES

To reduce the impact of render-blocking resources, identifying critical resources is an important part of the process. To do this, we make use of the Coverage Tab of the Chrome DevTools.

The Coverage Tab allows us to see how much of our code is being used versus how much is being loaded.

To open the Coverage Tab, first open Chrome DevTools via CMD + ALT + I on MacOS and CTRL + SHIFT + I on Windows. Then:

  • Click the Chrome DevTools Options Icon on the top bar Chrome Top Bar
  • Go to More Tools and select Coverage Coverage Option

Coverage Tab
COVERAGE TAB

Clicking on the reload button reloads the website and therefore captures the coverage/usage of several files that were requested by the web page.

Coverage of AliExpress.com

The Coverage Tab shows us information such as the resource URL, resource file type, total file size, its unused bytes and a visualisation of used versus unused bytes.

Clicking on the resource URL, Chrome DevTools opens the file indicating the used (critical) and unused (non-critical) lines of code.

Indication In File

Styles in CSS and code in JavaScript are marked in two colours in the Coverage Tab:

  • Red (non-critical): These are styles that apply to content not immediately visible and code not being used in page's core functionality.
  • Blue (critical): These are styles that are required for first paint and code that's critical to the page's core functionality.

REDUCING/ELIMINATING RENDER-BLOCKING RESOURCES

Once you've identified render-blocking and critical resources, you can go ahead and eliminate the different types of render-blocking resources:

  • Render-blocking stylesheets,
  • Render-blocking scripts and
  • Render-blocking imports
ELIMINATING RENDER-BLOCKING STYLESHEETS

Eliminating render-blocking stylesheets can be done through inlining critical styles required for the first paint inside a <style> block at the head of the HTML document. Then load the rest of the styles asynchronously using the preload link (<link rel='preload'>) which defers unused CSS.

You should also consider automating the process of extracting and inlining "Above the Fold" CSS using the Critical tool.

Another approach to eliminating render-blocking stylesheets is to split up those styles into different files, organised by media query. Then add a media attribute to each stylesheet link. When loading a page, the browser only blocks the first paint to retrieve the stylesheets that match the user's device. Below, is an example of how this can be done.

<link href="style.css"    rel="stylesheet">
<link href="style.css"    rel="stylesheet" media="all">
<link href="portrait.css" rel="stylesheet" media="orientation:portrait">
<link href="print.css"    rel="stylesheet" media="print">
Enter fullscreen mode Exit fullscreen mode

In the example above,

  • The first declaration is render blocking and matches in all conditions.
  • The second declaration is also render blocking: all is the default type so if you don’t specify any type, it’s implicitly set to all. Hence, the first and second declarations are actually equivalent.
  • The third declaration has a dynamic media query, which is evaluated when the page is loaded. Depending on the orientation of the device while the page is loading, portrait.css may or may not be render blocking.
  • The last declaration is only applied when the page is being printed so it is not render blocking when the page is first loaded in the browser.

Finally, you'll want to minify your CSS to remove any extra whitespace or characters. This ensures that you're sending the smallest possible bundle to your users.

ELIMINATING RENDER-BLOCKING SCRIPTS

As with render-blocking stylesheets, once you've identified critical code, move that code from the render-blocking resource URL to an inline script tag in your HTML document. When the page loads, it will have what it needs to handle the page's core functionality.

If there's code in a render-blocking resource URL that's not critical, you can keep it in the URL, and then mark the URL with async or defer attributes.

Code that isn't being used at all should be removed.

ELIMINATING RENDER-BLOCKING IMPORTS

For non-critical HTML imports, mark them with the async attribute. As a general rule, async should be used with HTML imports as much as possible.

<link rel="import" href="file.html" async>
Enter fullscreen mode Exit fullscreen mode

CONCLUSION

This post elaborates on one of the ways to optimise the First Paint(FP) and First Contentful Paint(FCP) metrics by avoiding render-blocking resources.

In the next post, we look at how we can cache critical resources to improve performance on repeat visits.

Discussion (0)