How to Identify & Reduce Render-Blocking Resources via @abbynhamilton

How to Identify & Reduce Render-Blocking Resources via @abbynhamilton


In 2018, the average time to fully load a mobile page was 15 seconds. That is substantially higher than Google’s recommended page load time of 3 seconds.

So, of course, reducing the total load time remains a top priority for allowing user interaction as quickly as possible.

But page speed isn’t only about total page load time; it’s also about what users experience in those 3 (or 15) seconds. It’s essential to consider how efficiently pages are rendering.

This is accomplished by optimizing the critical rendering path to get to your first paint as quickly as possible.

Basically, you’re reducing the amount of time users spend looking at a blank white screen to display visual content ASAP (see 0.0 below).

Optimized Page Rendering” width=”977″>Example of optimized vs. unoptimized rendering from Google

There’s a whole process on how to do this, outlined in Google’s developer guide documentation (thank you, Ilya Grigorik), but I’ll be focusing on one heavy hitter in particular: reducing render-blocking resources.

What Is the Critical Rendering Path?

The critical rendering path refers to the series of steps a browser takes on its journey to render a page, by converting the HTML, CSS, and JavaScript to actual pixels on the screen.

Essentially, the browser needs to request, receive, and parse all HTML and CSS files (plus some additional work) before it will start to render any visual content.

Until the browser completes these steps, users will see a blank white page.

Steps to Render a Page” width=”760″>

How Do I Optimize It?

Improving the critical rendering path involves identifying and analyzing your critical resources (any resource that blocks the initial rendering of the page), and looking for opportunities to:

  • Reduce the number of critical resources by deferring render-blocking resources.
  • Shorten the critical path by prioritizing above-the-fold content and downloading all critical assets as early as possible.
  • Reduce the number of critical bytes by reducing the file size of the remaining critical resources.

This article will focus on step 1 – deferring render-blocking resources (i.e., rearranging elements for efficiency to make it feel like the experience is faster without removing stuff).

Why Should I Care?

Well, no one puts it more frankly than the hundred-dollar man himself:

“Time is money.” – Benjamin Franklin

Google’s user behavior data reports that most users abandon a slow site after about 3 seconds.

On the contrary, a page speed study by Unbounce found that nearly three-quarters of consumers said that they were willing to wait 4 seconds or more for a page to load.

What gives?

“Time is an illusion.” – Albert Einstein

A study published by the Journal of Consumer Research indicated that there are two types of time:

  • Objective time: Standard clock time.
  • Subjective time: Consumer’s perception of time.

Focusing too heavily on objective time can be problematic, as humans (and our real-life users) are notoriously bad at estimating time.

“Time flies when you’re having fun.” – My Dad

People’s perception of time is based on a variety of subjective factors.

Of these includes whether they are in “passive wait” or “active wait.” In terms of page rendering, these can be defined as:

  • Passive wait: User is looking at a blank white screen
  • Active wait: Visual content is rendering on the page

Research published by INFORMS found that, even when wait times are measurably equal, people in passive wait overestimate their time spent waiting by 36%.

Passive vs Active Wait” width=”760″>

The same concept inspired the widespread use of the progress (or loading) bar in computing, as it was found to reduce anxiety, creating a more positive experience for users.

“Web pages don’t have loading bars. So when the page is slow, the visitor doesn’t know if the delay will be another 500 milliseconds or 15 seconds. Maybe it will never load. And the back button is right there” (Andy Crestodina, Orbit Media quoted by Unbounce).

With many studies linking reductions in page load times to improvements in valuable KPIs (conversions, bounce rate, time on site), improving site latency has become a top-of-mind business goal for many organizations.

SEO professionals are in a unique position to guide this effort, as our role is often to bridge the gap between business goals and web developer’s priorities.

Having the ability to audit a site, analyze results, and identify areas for improvement helps us to work with developers to improve performance and translate results to key stakeholders.

Back to Render-Blocking Resources

The primary goal of optimizing the critical rendering path is to prioritize the resources needed to render meaningful, above-the-fold content.

To do this, we also must identify and deprioritize render-blocking resources – resources that are not necessary to load above-the-fold content and prevent the page from rendering as quickly as it could.

Render-Blocking CSS

CSS is inherently render-blocking.

The browser won’t start to render any page content until it is able to request, receive, and process all CSS styles.

This avoids the negative user experience that would occur if a browser attempted to render un-styled content.

A page rendered without CSS would be virtually unusable, and the majority (if not all) of content would need to be repainted.

Page with CSS Disabled” width=”661″>

Looking back to the page rendering process, the gray box represents the time it takes the browser to request and download all CSS resources, so it can begin to construct the CCSOM tree (the DOM of CSS).

The time it takes the browser to accomplish this can vary greatly, depending on the number and size of CSS resources.

Steps to Render a Page CSS” width=”760″>

Official Google Recommendation:

“CSS is a render-blocking resource. Get it to the client as soon and as quickly as possible to optimize the time to first render.”

Render-Blocking JavaScript

Wait, what about JavaScript?

Unlike CSS, the browser doesn’t need to download and parse all JavaScript resources to render the page, so it’s not technically* a “required” step (*most modern websites require JavaScript for their above-the-fold experience).

Yet, when the browser encounters JavaScript before the initial render of the page, the page rendering process is paused until after the JavaScript is executed (unless otherwise specified using the defer or async attributes – more on that later).

For example, adding a JavaScript alert function into the HTML blocks page rendering until the JavaScript code is finished executing (when I click “OK” in the screen recording below).

Example of Render Blocking Java Script” width=”1280″>

This is because JavaScript has the power to manipulate page (HTML) elements and their associated (CSS) styles.

Since the JavaScript could theoretically change the entire content on the page, the browser pauses HTML parsing to download and execute the JavaScript just in case.

How Browser Handles JavaScript” width=”997″>How the browser handles JavaScript, image from Bits of Code

Official Google Recommendation:

“JavaScript can also block DOM construction and delay when the page is rendered. To deliver optimal performance … eliminate any unnecessary JavaScript from the critical rendering path.”

How to Identify Render-Blocking Resources

To identify the critical rendering path and analyze critical resources:

  • Run a test using org and click on the “waterfall” image.
  • Focus on all resources requested and downloaded before the green “Start Render” line.

Analyze your waterfall view; look for CSS or JavaScript files that are requested before the green “start render” line but are not critical for loading above-the-fold content.

WPT Start Render Line” width=”760″>

After identifying a (potentially) render-blocking resource, test removing it to see if above-the-fold content is affected.

In my example, I noticed some JavaScript requests to the Google Maps API that don’t appear to be critical. But it’s a good idea to test removing these scripts to test how shifting elements on the site affects the experience.

Example of Render Blocking JavaScript” width=”760″>

To test within the browser on how deferring these resources would affect above-the-fold content:

  • Open the page in a Chrome Incognito Window (best practice for page speed testing, as Chrome extensions can skew results, and I happen to be a collector of Chrome extensions).
  • Open Chrome DevTools (ctrl shift i) and navigate to the “Request blocking” tab in the Network panel.
  • Check the box next to “Enable request blocking” and click the plus sign.
  • Type a pattern to block the resource(s) you’ve identified, being as specific as possible (using * as a wildcard).
  • Click “Add” and refresh the page.

Test Removing Scripts Example” width=”1280″>

Methods to Reduce Render-Blocking

Once you have confirmed a resource is not critical to render above-the-fold content, explore different methods available to defer resources and improve page rendering.

Method Impact Works with
JavaScript at the bottom of the HTML Low JS
Async or defer attribute Medium JS
Custom Solutions High JS/CSS
CSS media queries Low-High CSS

Place JavaScript at the Bottom of the HTML

If you’ve ever taken a Web Design 101 course, this one may be familiar: place links to CSS stylesheets at the top of the HTML and place links to external scripts at the bottom of the HTML .

Circling back to my example using a JavaScript alert function, the higher up the function is in the HTML, the sooner it will be downloaded and executed by the browser.

How to Identify & Reduce Render-Blocking Resources” width=”1673″>Example of JavaScript placed at the top of the HTML, page rendering is immediately blocked by the alert function and no visual content renders.


How to Identify & Reduce Render-Blocking Resources” width=”1810″>Example of JavaScript placed at the bottom of the HTML, some visual content appears before page rendering is blocked by the alert function.

While placing JavaScript resources at the bottom of the HTML remains a standard best practice, the method by itself is sub-optimal for eliminating render-blocking scripts from the critical path.

Continue to use this method for critical scripts, but explore other solutions to truly defer non-critical scripts.

Use the Async or Defer Attribute

The async attribute signals to the browser to load JavaScript asynchronously, fetch the script when resources become available (as opposed to pausing HTML parsing).

Once the script is fetched and downloaded, HTML parsing is paused while the script is executed.

Async Attribute” width=”944″>How the browser handles JavaScript with an async attribute, image from Bits of Code

The defer attribute signals to the browser to load JavaScript asynchronously (same as the async attribute) and to wait to execute JavaScript until the HTML parsing is complete, resulting in additional savings.

Defer Attribute” width=”854″>How the browser handles JavaScript with a defer attribute, image from Bits of Code

Both methods are relatively easy to implement and help reduce the time the browser spends parsing HTML (the first step in page rendering) without significantly changing how content loads on the page.

Async and defer are good solutions for the “extra stuff” on your site (social sharing buttons, a personalized sidebar, social/news feeds, etc.) that are nice to have, but don’t make or break the primary user experience.

Use a Custom Solution

Remember that annoying JS alert that kept blocking my page from rendering?

Adding a JavaScript function with an “onload” event (from Patrick Sexton on resolved the problem once and for all.

The script below uses the onload event to call the external resource “alert.js” only after all the initial page content (everything else) has finished loading, removing it from the critical path.

JavaScript Onload Event” width=”772″>JavaScript onload event used to call alert function

How to Identify & Reduce Render-Blocking Resources” width=”1468″>Alert displays only after all the initial page content is fully loaded.

This isn’t a one-size-fits-all solution.

While it may be useful for the lowest priority resources (i.e., event listeners, elements in the footer, etc.), you’ll probably need a different solution for important content located below-the-fold.

Work with your development team to find the best solution to improve page rendering while maintaining an optimal user experience.

Use CSS Media Queries

CSS media queries can unblock rendering by flagging resources that are only used some of the time and setting conditions on when the browser should parse the CSS (based on print, orientation, viewport size, etc.).

All CSS assets will be requested and downloaded regardless, but with a lower priority for non-blocking resources.

Example CSS Media Query” width=”1604″>Example CSS media query that tells the browser not to parse this stylesheet unless the page is being printed.

When possible, use CSS media queries to tell the browser which CSS resources are (and are not) critical to render the page.


  • The goal of optimizing the critical rendering path is to provide users with meaningful content as quickly as possible.
  • Deferring render-blocking CSS and JavaScript allows important, above-the-fold content to render faster.
  • To identify render-blocking resources:
    • Look for non-critical resources loading before the start render line (via
    • Test removing resources via Google Dev Tools to see how page content is affected.
    • Once identified, work with developers to find the best solution to defer render-blocking resources.

More Resources:

Image Credits

Featured Image: Screenshot taken by author, July 2019

All screenshots taken by author, July 2019

error: Content is protected !!