Perceived Web Performance - What is Blocking the DOM?
When it comes to web performance and optimizing speeds on a page-level basis it is very important to understand the relationship between HTML and how a page is actually constructed in your browser, so that you can pinpoint delays in page loads due to render blocking. In this post, we will dig deeper into what is blocking the DOM and ways you can prevent it from happening.
What is the DOM?
DOM in Laymen Terms
What is Blocking the DOM?
One of the easiest ways to see what is currently blocking the DOM is to use Chrome Devtools and PageSpeed Insights. In our examples below we are using the latest developer tools in Chrome Canary.
- Launch developers tools in Google Chrome.
Ctrl + Shift + I
Cmd + Opt + I
- Browse to the “Network” panel and refresh the page by pressing
Ctrl + R(
Cmd + R).
- You will now see a waterfall with load times. There are two things we want to look at here, first is the total DOMContentLoaded, which is 342ms and then also the resources that are before (left of) or touching the blue line.
style.css file and the
jquery.min.js file are both blocking the DOM.
You can also verify this information by running it through Google PageSpeed Insights. As you can see below it confirms both of these files are render blocking.
Note, it is not always necessary to go for that 100/100 score on PageSpeed Insights. For example, if you link to a Google web font using their external
fonts.googleapis.com stylesheet this is always going to be a render blocking resource, no matter what you do. The important thing is to recognize how to fix them so that on larger sites when you are dealing with 10+ files blocking the DOM you understand what is causing delays and have strategies in place to more efficiently load them.
Non-Render Blocking CSS
If you are going for completely non-render blocking CSS then you really only have one good option, and that is to inline your CSS. You include the CSS required for the initial rendering, typically styles for the above-the-fold content, directly in the HEAD section in the
<style></style> elements and move the rest of your CSS to the bottom before the
</body> element. This will prevent render blocking.
Inline CSS plugins for automated task systems
As you can see in Chrome Devtools we now inlined our CSS and the DOMContentLoaded was slightly faster at 279ms.
And now when we test it in Google PageSpeed Insights we no longer have our render blocking CSS.
While this is great, it all depends upon your site. Most sites will not want to inline all of their CSS because depending upon how much CSS you have this could significantly increase the download size of that page. For smaller sites or even possibly landing pages inlining CSS thought could be a good alternative if you are wanting to avoid render blocking completely.
Our CSS Recommendations
Even on our KeyCDN homepage we have one render blocking CSS file. However, there are things we have done to improve the load times of our CSS. Below are some recommendations.
- Properly call your CSS files
- Use media queries to mark some CSS resources as non-render blocking
- Lessen the amount of CSS files (concatenate your CSS files into one file)
- Minify Your CSS (remove extra spaces, characters, comments, etc)
- Use less CSS overall
Minify CSS plugins for automated task systems
- Move your scripts to the bottom of the page right before your
- Use the async or defer directive to avoid render blocking.
Async allows the script to be downloaded in the background without blocking. Then, the moment it finishes downloading, rendering is blocked and that script executes. Render resumes when the script has executed.
<script async src="foobar.js"></script>
The defer directive does the same thing, except it guarantees that scripts execute in the order they were specified on the page. So, some scripts may finish downloading then sit and wait for scripts that downloaded later but appeared before them.
jquery.min.js file now appears after the DOM blue line.
Web fonts can also be a render blocking resource as they are loaded with CSS. You really have two choices, either block the render or repaint later (then you have to deal with FOUT). For example, in Chrome (36+), Opera (23+), and Firefox there is a three-second timeout, after which the fallback font is shown.
There are a couple recommendations when it comes to loading fonts and optimizing the critical rendering path.
- Use a web font loader or font loading API
- Optimize font loading with inlining
- Use other storage methods such as localStorage
See our post on analyzing web font performance to see a more in-depth explanation of the different options you have for loading web fonts so you avoid render blocking and FOUT/FOIT.