25

I've been reading Google Developers documentation on optimizing web performance. I'm a little confused with the terminology used there. Both CSS and JavaScript files block DOM construction. But, CSS is called render-blocking whereas JavaScript is called parser-blocking. What is the difference in the 'parser-blocking' and 'render-blocking' terms? Or are they the same and the terminology is just interchangeably used?

user229044
  • 232,980
  • 40
  • 330
  • 338
M00
  • 327
  • 4
  • 11
  • From docs, _"JavaScript can also block `DOM` construction and delay when the page is rendered.(`parser-blocking`)"_ vs _"CSS is treated as a render blocking resource, which means that the browser will hold rendering of any processed content until the `CSSOM` is constructed.(`render-blocking`)"_ – Rayon Jun 11 '16 at 02:43

3 Answers3

41

Imagine an HTML page has two <script src="..."> elements. The parser sees the first one. It has to stop* parsing while it fetches and then executes the javascript, because it might contain document.write() method calls that fundamentally change how the subsequent markup is to be parsed. Fetching resources over the internet is comparatively much slower than the other things the browser does, so it sits waiting with nothing to do. Eventually the JS arrive, executes and the parser can move on. It then sees the second <script src="..."> tag and has to go through the whole process of waiting for the resource to load again. It's a sequential process, and that's parser blocking.

CSS resources are different. When the parser sees a stylesheet to load, it issues the request to the server, and moves on. If there are other resources to load, these can all be fetched in parallel (subject to some HTTP restrictions). But only when the CSS resources are loaded and ready can the page be painted on the screen. That's render blocking, and because the fetches are in parallel, it's a less serious slow down.


* Parser blocking is not quite as simple as that in some modern browsers. They have some ability to tentatively parse the following HTML in the hope that the script, when it loads and executes, doesn't do anything to mess up the subsequent parsing, or if it does, that the same resources are still required to be loaded. But they can still have to back out the work if the script does something awkward.
Alohci
  • 78,296
  • 16
  • 112
  • 156
  • 1
    Thanks for the great explanation. This sure cleared my understanding! – M00 Jun 11 '16 at 03:03
  • There is also something known as *preload scanning*, where the browser looks ahead and issues a request to get more than on JS/CSS files. Though, there is a limit to the number of parallel calls a browser can make. – ankit_m Apr 22 '17 at 13:50
  • because of the above reason mentioned by @ankit_m, it sometimes make sense to add async even to the last script on the HTML page if the script is not DOM dependent. So that the browser can preload and even execute the script optimizing the Critical Rendering Path. – Novice Jun 22 '18 at 04:45
  • 1
    If CSS is render blocking then why do we see FOUCs (Flash of unstyled content)? – darKnight Aug 05 '21 at 18:39
  • Some explanations here: https://stackoverflow.com/questions/53220261/if-css-is-render-blocking-why-do-we-see-fouc – Jithin Nair Sep 02 '21 at 17:14
4

CSS's render-blocking will not block DOM construction, it only blocks the content from displaying/rendering until CSSOM is ready. But there is a special case to note:

If there is any inline <script> under an external CSS's <link> tag, even if that is just an empty <script> tag that contains no JavaScript at all, the DOM construction for the HTML below that <script> tag will still be blocked util the external CSS is fetched. If you have a slow network connection, that empty <script> still causes a long delay of DOM construction. Because the <script> tag waits for the external CSS, and DOM construction waits for the script. In this case the external CSS resource implicitly causes a parser-blocking.

STEN
  • 433
  • 1
  • 6
  • 15
0

One more thing to keep in mind. You can achieve FP(First Paint) on the screen with inline styles before the CSS is loaded. How ? You just add the reference to the CSS after the element/s you want to be displayed first. For example:

<html>
<body>
<h1 style="color:red"> I will be displayed on the screen and I will be RED</h1>
<link rel="stylesheet" href="styles.css">
<h2> Every elementfrom this point forward (including me) will wait for the CSS to load first and then be displayed on the screen</h2>
</body>
</html>

NOTE: I should mention that what I'm doing here are considered bad practices.