One of the things we want to do when trying to make our websites faster is to have content appear on screen as quickly as possible. It’s something that metrics such as First and Largest Contentful Paint try to measure.
To achieve faster paint times, we often want to try and prioritise content requests like fonts and images. While we can do a lot by ourselves to optimise these resources, there are times when even our best efforts can sometimes be undone by third-party requests that block the browser from rendering content.
In this post, we’ll cover:
- What are render-blocking resources?
- How can render-blocking third-party requests hurt a site’s performance?
- Ways to identify render-blocking resources?
- How to mitigate the impact of render-blocking third-party requests?
anchorWhat is a render-blocking resource?
A render-blocking resource forces the browser to put a pause on rendering a web page. The browser waits until the code has been completely parsed and executed before it can continue rendering content in the viewport.
HEAD of a page. This includes inline code (found in
<style> tags) as well as linked external resources (using the
CSS is always render-blocking. Regardless of what it’s doing at the time, the moment a browser encounters a CSS resource it will stop to download and parse the CSS. Once that’s out the way the browser will continue working on rendering content on the screen.
💡 Can I load CSS asynchronously?
Yes, CSS can be loaded asynchronously to avoid render-blocking. This post from Filament Group explains how this can be done. However, if not managed properly this can result in unstyled content being shown to the user before the CSS has been completely parsed by the browser.
<script> tag), then parse and finally execute the code. Using
defer attributes on
💡 What about
Because of this race condition tools like WebPageTest will flag
<!-- CSS will download and parse first -->
<link rel="stylesheet" href="/css/my-styles.css" />
<!-- JS will download, parse and execute first -->
<link rel="stylesheet" href="/css/my-styles.css" />
<!-- JS will start downloading in parallel with the CSS file -->
<script async src="/js/important-file.js"></script>
<link rel="stylesheet" href="/css/my-styles.css" />
anchorIt can get worse with render-blocking third-party requests
The problems that can be caused by render-blocking resources get exacerbated when they are also third-party requests. A third-party resource is one that is not hosted on the same origin as the website requesting it.
When a browser encounters a request for a third-party resource, it must first ensure it can reach that domain and establish a secure connection. Once this is done, only then can the browser initiate the request to download the resource. This whole process can take anywhere between a few hundred milliseconds to a few seconds.
However, with so many moving parts to make a third-party request the chances of something going wrong increase. Third-party requests can fail. And, if that third-party request also just so happens to be for a render-block a resource, then the impact on your site’s performance can be significant.
💡 Example: NRL Fantasy
For the rest of this post, we’ll be using the NRL Fantasy website as an example. As a kid who grew up in Sydney, Australia I love myself some Rugby League. Each year, as the new season rolls around, a few friends and I like to get involved with the online Fantasy NRL game.
So, when looking for an example for this post I thought I’d see if the NRL Fantasy website uses any render-blocking third-party resources. Turns out they do! You can follow along with the rest of this post using these test results.
anchorIdentifying a blocking third-party request in the WebPageTest Waterfall
Tests run on Chrome, Edge, Brave
If you’ve run a WebPageTest in a Chromium-based browser (Chrome, Edge, Brave) then identifying render-blocking resources is straightforward in the WebPageTest waterfall chart. Any identifiable render-blocking request will have an orange circle with a white cross at the start of the request row.
You can see from the screenshot below that the test on the NRL Fantasy website highlights two render-blocking requests (on rows 2 and 4). We can tell by the domain shown which each request that row 2 is a first-party request, while row 4 is a third-party request for Google Fonts.
In the waterfall chart below, you can also see the connection cost incurred by making the third-party request. This is indicated by the narrow teal, orange, and purple bars.
Figure 1: Waterfall chart showing render-blocking requests on rows 2 and 4.
Tests run on Firefox or Safari
As yet, Firefox and Safari do not surface information on the render-blocking status. If you’re running a WebPageTest on those agents then you’ll not see any visual indicator like we can with Chromium-based browser tests.
If you are testing with Firefox or Safari agents, but struggling with render related metrics like First or Largest Contentful Paint, then run one test in a Chromium-based browser. This will allow you to easily surface any render-blocking requests that might be causing slow paint times.
anchorFinding potentially blocking requests
There are times, however, when Chromium can’t quite be sure if a request is blocking or not. This is often the case with
However, clicking on an individual request row will reveal the full request details. If it’s available, you’ll see a listing for Render Blocking Status. If Chromium is unsure how the request will impact rendering, then you’ll see
potentially_blocking here. Tim has written up a post explaining the (relatively) new field and what the different status messages can mean.
In the image below, we can see that the NRL Fantasy website makes a call to Google Tag Services (row 5). The request is sent off alongside the request to Google Fonts, so we can guess that the script is probably
async. When we inspect the request, we can see the
potentially_blocking indicator for the Render Blocking Status field.
Waterfall chart detail view
If you’ve taken steps to address all the identified render-blocking requests, but are still seeing long FCP or LCP timings then drilling down into potentially blocking requests should be your next step.
anchorTesting the impact of a failed request
Now that we’ve identified a render-blocking third-party request we can use WebPageTest to see what happens if that request fails. A SPOF (Single Point of Failure) test allows us to simulate a request timeout for one or more domains.
Run a SPOF test on a render-blocking request
In our example, let’s test the impact on page performance if the render-blocking Google Fonts request was to fail. To do this, we’ll run a SPOF test. Since this request has been flagged as render-blocking in our test results, we can get this done pretty quickly.
- Click on the request row to open the Request Details dialogue.
- Navigate to the Request Blocking tab.
- Click on the Run a SPOF Test link.
A new tab will open in your browser showing two tests being run (Original and SPOF). Since SPOF tests simulate a request timeout, they can sometimes take a while to complete. It can help to have some patience and a cup of tea handy.
Run a SPOF test on a potentially blocking request
Say, instead, we want to test the impact of a potentially blocking request failing. In that case, we’ll need to open up the WebPageTest homepage (you can do that in a new tab). Once there:
- Enter the URL you were testing.
- Expand the Advanced Configuration section.
- Set your test location and browser.
- Navigate to the SPOF tab.
- In the text box, enter the domain of the request you’d like to fail. In our case let’s try the Google Tag Services request identified earlier.
- Get your cup of tea ready, and click Start Test.
Figure 5: Running a SPOF test from the WebPageTest homepage.
Viewing SPOF test results
The results of a SPOF test are p resented as a comparison filmstrip. You can see the results of the original test above the results of the SPOF test. SPOF results are among the most impactful visual results that WebPageTest presents. Scrolling the filmstrip allows you to get a visual sense of the impact the failed request has on a page’s overall rendering performance.
Figure 6: Filmstrip comparison showing results of Google Fonts SPOF test.
Below the filmstrip, you’ll find the Waterfall charts for the two tests. The SPOF result is overlayed on top of the original results. This can be a bit hard to read initially. Just below the filmstrip is a small expandable section titled Waterfall Opacity. Adjusting the slider in this section will allow you to smoothly transition between the original and SPOF Waterfall charts.
Creating a comparison video of a SPOF test
You can also generate a comparison video of the original and SPOF test. This is as impactful a visual comparison as the filmstrip view. It’s especially handy if you’re looking to present the results of your SPOF test or share them within your company.
To create a comparison video of a SPOF test, click the Adjust Filmstrip Settings button that’s at the top right of the filmstrip. This will open up a dialogue window with a heap of settings to tweak the filmstrip appearance and detail level. Scroll to the very bottom and you’ll see a large View Video button. Clicking that will load a side-by-side video comparing the two results.
Figure 7: The expanded Adjust Filmstrip Settings dialogue, which allows you to create a comparison video.
You can see what it looks like for our Google Fonts SPOF test below. The video can be downloaded, or saved as a GIF, to share.
anchorReducing the impact of blocking third-party resources
- Since requests will be made to your own domain, you won’t incur the cost of the browser having to establish a connection with a new origin. In most cases, this will save a few hundred milliseconds right off the bat.
- You may also be able to make further modifications to the resources, like removing unused code. This can help bring down their size and reduce download time. Some licensing agreements prevent this, though, so be sure to check those before diving in here.
Asynchronously load third-party requests
Move A/B testing onto the server
One common use case for render-blocking third-party resources is client-side A/B testing. This has the potential to significantly influence page performance. Since client-side A/B testing relies on third-party code being downloaded, parsed and executed on the user’s device before content changes are made visible.
If possible, look to move the A/B test execution onto the server. This will mean that all the heavy optimisations will be handled on more capable machines, and the user won’t have to incur the cost of downloading and executing a client-side package.
Edge compute services like Cloudflare Workers make this even easier. They allow you to intercept requests and then, based on conditions you set, can modify the web page HTML before returning the page to the user.
Are there alternatives?
Are there more efficient alternatives to the third-party resource you’re using? Perhaps there are open-source options that can you can self-host. Or, maybe you don’t need that third party at all.
Being able to quickly identify render-blocking requests can help give a performance audit an early sense of direction. Using the SPOF test, and filmstrip/video comparison in WebPageTest allow us to visualise the potential impact when those requests fail.
To see how to check for render-blocking third-party requests as part of a broader website audit, check out the WebPageTest Live! Hidden Gems Twitch stream replay on the WebPageTest YouTube channel. In it, Tim covers a few of the things we’ve talked about here, plus other hints that will help with your next site audit.