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
- Is in the
- 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.
- Does not have a
- A
<link rel="import">
tag that:- Does not have an
async
attribute.
- Does not have an
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
- Go to More Tools and select Coverage
Clicking on the reload button reloads the website and therefore captures the coverage/usage of several files that were requested by the web page.
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.
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">
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 toall
. 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>
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.
Top comments (0)