How to eliminate render blockers for page speed optimization
‘Slo-mo’ websites, hmmm... They just make you feel your patience running out while you contemplate if it will be worth the wait, or perhaps you should bounce. Except you have an annoyingly slow internet connection, such an experience could just be the result of poorly loaded files and codes hindering the browser from rendering the page faster than it can.
Render blockers are resources that hinder the browser from loading the page until those resources are loaded. These blockers are usually CSS, JavaScript, and media files and assets.
Understanding Render Blockers
Let’s first establish a foundational understanding of the first few steps the browser takes to construct a page.
The browser downloads the HTML
The browser begins to read and parse the HTML to create the DOM, and if in the process, encounters a stylesheet, It fetches the stylesheet while still constructing the rest of the DOM.
The fetched stylesheet is used to construct a CSS Object Model (CSSOM).
The DOM and CSSOM are then combined to create the render tree.
But not just yet. These days, any decent webpage has some level of JavaScript. This is the point where render-blocking happens because when the browser encounters a script, it stops constructing the DOM in order to execute the script found before parsing is resumed. This is important because Javascript can alter the layout and looks of the page and the browser needs to know exactly what to render.
NB: Parsing and rendering are not synonymous. Parsing means analyzing the downloading page data to figure out the DOM and CSSOM construction.
Rendering means painting pixels onto the screen based on the results after parsing.
The Impact of Render Blockers
Render blockers negatively affect a site's performance and user experience by causing slower loading times, which can lead to a high bounce rate when impatient users navigate away.
It also affects your SEO ranking and indexing because search engine bots allocate a limited amount of time to crawl a website. If your site is slow to load and takes longer for these bots to access and index contents, fewer pages may be crawled during a single visit.
Identifying Render Blockers
Before you can tackle render blockers, you need to fish them out. Google Lighthouse which is part of the Chrome dev tools, GTMetrix, and PageSpeed Insight can help you pinpoint render-blocking issues on your website. These tools can also analyze your site's performance and provide recommendations for improvement.
Is HTML render blocking?
HTML generally does not pose as a render blocker because they are rendered incrementally i.e. browsers start parsing HTML as soon as it comes in instead of waiting for the whole document to download.
Also, HTML file size is negligible compared to images and videos. If your HTML source is so large and complex that it is affecting rendering and performance, you should aim to split the content up.
Eliminating Render Blockers in CSS
All CSS is render blocking. The browser pauses page rendering until it receives and processes all the CSS needed to construct the CSS Object model. This is because if CSS is rendered in chunks, it might lead the browser to render an element using the wrong styles because elements already rendered might have their styles altered when the next chunk of CSS is parsed (remember that rules that appear later in the code override earlier rules). This could lead to interface change, etc. So how can we reduce these render blockers?
Use media queries - codes written in the media queries can be viewed as conditional CSS and so, conditionally importing such CSS files makes it non-render blocking.
Let’s say we have CSS rules concerned with printing, we first abstract them into a separate CSS file, which can then be imported by using the
media
attribute of thelink
tag to set a conditionNote that the browser still downloads this CSS file, but without parsing it, therefore not blocking render.
<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" />
Defer non-critical CSS - Critical codes are codes required to render the page the user will see immediately after the site loads. Hence, the CSS styles not required for immediate display can be loaded later. This can be achieved by splitting the critical and non-critical CSS into separate files. The critical CSS can be defined in the style tag inside the head tag of your page.
The non-critical CSS can then be linked just above the closing body tag or can be loaded with JavaScript.
Identifying the critical CSS required to run your project can be handled manually or seamlessly by using a sitelocity which will split your CSS into critical and combined, along with a short script to efficiently load the combined script after the page has been rendered.
Eliminating render blockers in Javascript
When the browser encounters a script tag, it pauses the page construction and allows the javascript to execute, before it continues. This is because JavaScript could potentially manipulate the DOM and alter CSS styles.
Since Javascript blocks rendering, it would be great if we could tell the browser that a script has nothing to do with how the page will be rendered. For instance, if we had a script concerned with analytics, it’s recommended to execute that script after the page has loaded. Here’s how to;
Use Async and Defer - Adding a script before the closing body tag doesn't optimally solve the problem of waiting for the script to load. Instead Asynchronous and Deferred loading are used to control when and how scripts are executed.
The
async
allows the browser to parse the script while parsing the rest of the page without blocking the critical rendering path.The
defer
attribute instructs the browser to execute the script after the page has finished parsing. Can only be used for external scripts.Third-party scripts such as analytics and ads that do not depend on the DOM order, should be loaded with the
async
attribute.<script src="script.js" defer></script> <script src="analytics.js" async></script>
Code Splitting - split your script into modules and load each part on demand, instead of putting all your code into one script and loading it all at the beginning.
Handling Media files and assets for page speed
Note that resources such as images are not necessarily render-blocking because the page will still render fine without them.
So why should we care? Because such resources impact the overall page performance metrics such as the Last contentful paint, and also, we do not want users to experience the annoying interface shift after an image is finally loaded, so do the following ;
Lazy loading - Lazy loading is a strategy to identify resources as non-critical and load these only when needed for user interaction. Lazy loading shortens the length of the critical rendering path, hence, reducing the page load time. Add
loading="lazy"
to theimg
andiframe
tags.<img src="image.jpg" alt="..." loading="lazy" /> <iframe src="video-player.html" title="..." loading="lazy"></iframe>
You can also lazy load video content by using the
preload
attribute and setting it tonone
. For example:<video controls preload="none" poster="poster.jpg"> <source src="video.webm" type="video/webm" /> <source src="video.mp4" type="video/mp4" /> </video>
This tells the browser not to load any of the video data before the user decides to play it. Instead, it will just show the image indicated by the poster attribute.
Preload Critical Resources - Use the
<link rel="preload">
tag to instruct the browser to fetch the referenced resource early and make it available so that it will be ready for use sooner when it is referenced in subsequent code. Preloading is recommended for high-priority resources that the user will encounter early on in a page.<link rel="preload" href="sintel-short.mp4" as="video" type="video/mp4" />
This works for CSS and Javascript files as well.
Optimize Image Size - Resize your images to the exact dimensions needed for their display on your website. Avoid using images that are larger than necessary because they increase loading times. Also, removing unnecessary metadata that provides auxiliary information about the image will give an even smaller image size.
Do not import fonts with @import - This is because using
@import
creates a chain of blockers, where a render-blocking resource begins to load another render-blocking resource. Instead using the link tag will ensure that the resource is discovered earlier without having to load the parent css file.Use this ;
<link rel="preload" as="style" href="https://fonts.googleapis.com/css?family=Press+Start+2P">
Instead of ;
@import url(https://fonts.googleapis.com/css?family=Press+Start+2P);
Removing render blockers is an ongoing process. Regularly test your website's performance and monitor for new issues when new content and codes are added. Automated monitoring tools and services can help you stay on top of your website's performance. And always regard speed as a feature 🚀 .
Subscribe to my newsletter
Read articles from Pius Iniobong directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by