Why google is using the term "Render-Blocking JavaScript"?
Asked Answered
L

2

-3

See:

https://developers.google.com/speed/docs/insights/BlockingJS

Google is talking there about "Render-Blocking JavaScript", but in my opinion that term is incorrect, confusing and misleading. It almost looks like "Google" is also not understanding it?

This point is that Javascript execution is always pausing / blocking rendering AND also always pausing / blocking the "HTML parser" (at least in Chrome and Firefox). It's even blocking it in case of an external js file, in combination with an async script tag!

So talking about removing "render-blocking Javascript" by for example using async, implies that there is also non blocking Javascript or that "async Javascript execution" is not blocking rendering, but that's not true!

The correct term would be: "Render-Blocking Download(s)". With async you will avoid that: downloading the js file, will not pause / block rendering. But the execution will still block rendering.

One more example which confirms it looks like Google is not "understanding" it.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Test</title>
</head>
<body>
    Some HTML line and this is above the fold
    <script>
        // Synchronous delay of 5 seconds
        var timeWhile = new Date().getTime(); 
        while( new Date().getTime() - timeWhile < 5000 );
    </script>
</body>
</html>

I tested it in Firefox and Chrome and they are showing (rendering): "Some HTML line and this is above the fold" after 5 seconds and not within 5 seconds!!!! It looks like Google is thinking that in a case like that, the Javascript will not block rendering, but as expected from theory, it will block. Before the js execution will start, all the html is already in the DOM (execept end body / html tag), but rendering is not done yet and will be paused. So if Google would be really aware of this, then Chrome would first finish rendering before starting with the execution of javascript.

If you take the example above and you're using:

<script src="delay.js" async></script>

or

<script src="delay.js"></script>

instead of internal javascript. Then it can also give the same results as the example above. For example:

  • If the preloader (scanning for files to already download) already would have downloaded "delay.js", before the "HTML parser" is coming at the Javascript part.
  • Usually external files from Google, Facebook et cetera are already stored in the cache, so there is no download and they just take the file from cache.

In cases like that (and also with async), the result will be the same as the example above (at least in pretty a lot of cases). Because if there is no extra download time, the "Javascript execution" will / can already start, before the preceding html finished rendering.

So in a case like that you could even consider to put "no-cache" / "no-store" on delay.js (or even extra delay), to make your page render more fast. By forcing a download (or extra delay) you will give the browser some extra time to finish rendering of the preceding html, before executing the render blocking Javascript.

So i really don't understand why Google (and others) are using the term "Render-Blocking JavaScript", while from theory and from "real life" examples it looks like it's the wrong term and wrong thinking. I see noone talking about this on the internet, so i don't understand. I know i am f**king intelligent (j/k), but it looks kind of weird to me, to be the only one with the thoughts above.

Landgrave answered 30/10, 2017 at 9:47 Comment(2)
From the page you linked to: inline scripts are always parser blocking unless you write additional code to defer their execution.Bendicty
@JoshLee But that's also not true. Javascript execution, is always parser blocking. And it does not matter if it's async / sync / defer. So that's why Google is confusing people with their information and as you can see you, now you are also thinking the wrong way because of their information. You can just do my test with an external script tag with defer and in case of caching (so no download time): "Some HTML line and this is above the fold" is shown after 5 seconds again, because rendering is blocked during js execution!Landgrave
S
2

I work with developers on Chrome, Firefox, Safari and Edge, and I can assure the people working on these aspects of the browser understand the difference between async/defer and neither. You might find others will react more politely to your questions if you ask them politely.

Here's an image from the HTML spec on script loading and execution:

Diagram of script loading

This shows that the blocking happens during fetch if a classic script has neither async or defer. It also shows that execution will always block parsing, or certainly the observable effects of parsing. This is because the DOM and JS run on the same thread.

I tested it in Firefox and Chrome and they are showing (rendering): "Some HTML line and this is above the fold" after 5 seconds and not within 5 seconds!!!!

Browsers may render the line above, but nothing below. Whether the above line renders depends on the timing of the event loop in regards to the screen refresh.

It looks like Google is thinking that in a case like that, the Javascript will not block rendering

I'm struggling to find a reference to this. You linked to my article in an email you sent me, which specifically talks about rendering being blocked during fetching.

In cases like that (and also with async), the result will be the same

That isn't guaranteed by the spec. You're relying on retrieval from the cache being instant, which may not be the case.

in a case like that you could even consider to put "no-cache" / "no-store" on delay.js (or even extra delay), to make your page render more fast. By forcing a download (or extra delay) you will give the browser some extra time to finish rendering of the preceding html, before executing the render blocking Javascript.

Why not use defer in this case? It achieves the same without the bandwidth penalty and unpredictability.

Shel answered 30/10, 2017 at 17:39 Comment(16)
I am asking the question pretty politely, but appartly i can not say that in my opinion Google seems wrong. I don't curse and i am just giving arguments. But anyway thanks a lot for your reply! I really appriciate that! Althought i have still no answers ;). Firstable in my mail i was not talking about "rendering being blocked during fetching". I was talking about why Chrome is not finishing rendering of the preceding html, before starting with the javascript execution.Landgrave
And you said: "You're relying on retrieval from the cache being instant, which may not be the case.". I said "will / can", so i am aware of that, but i am relying on tests i did. You can do the test with that example of mine, but then with the async script tag. Then you will find out that in for example a case like that, the "javascript execution" is blocking the rendering of the "preceding html". So then an option would be to not cache it to give the browser some extra time to finish rendering of the preceding html.Landgrave
See for that test: #46979965Landgrave
And anyway maybe you can tell me why Chrome is not finishing rendering, before executing the javascript in the example i gave? I don't see a reason for that. Then you can say that you can assume the people understand it, but then i don't understand why Chrome is doing it like that and until now i could not get any answer to that question. Only people who are just saying "Google is always right" without any arguments / answers. That's where my frustration is coming from. And you don't think the term "Render-Blocking JavaScript" is confusing?Landgrave
Oh one more thing. About your defer suggesting ... i'm sorry to say and i don't mean it bad, but it really looks like you don't understand my point and the problem. Because with using defer, the javascript execution will also block rendering. So for example in case of caching, the javascript can be executed before finish rendering of the preceding html, so then it's still blocking rendering. Tests (with defer) will give the same results as my shown example with inline / async / sync et cetera. So after 5 seconds you will see something.Landgrave
When you are telling others they don't understand, pause for a moment and consider that the misunderstanding may be yours. As I said in the answer, the preceding paragraph no-rendering is in-keeping with the event loop. The spec does not guarantee a render before a script tag. In terms of defer, it's objectively better than breaking caching, which is what I was responding to. I even quoted you to be clear.Shel
I'm telling that in my opinion they don't understand. I think i can just say it like that, because i'm still thinking like that. I'm waiting for better arguments against what i'm saying and then i would consider the misunderstanding may be mine. But defer better than breaking caching? When using defer, the javascript will still block rendering in my example (of the preceding url), so that's no solution at all for it. With disabling caching you will give the browser some more time (during downloading) to finish rendering of the preceding html.Landgrave
Let's do it step by step ... are you agree with me that the execution javascript, is always blocking rendering and the html parser?Landgrave
Also see: #46931530 A post of me a while ago. Only positive "reputation" comments and no answer at all. I don't think, you guys don't take me seriously enough with this point. Although you are reacting, so that's kind of sweet ;) of you if you're still think that i don't understand it or i misunderstood something. But maybe you can read my comments like: oh maybe that guy has a point, so i will read it differently.Landgrave
"are you agree with me that the execution javascript, is always blocking rendering and the html parser?" yes I posted you an image from the HTML spec, and a link to the HTML spec, that defines exactly that.Shel
Okay then the next step is: because js execution is always blocking rendering, you will not avoid that with using async, defer et cetera. Are you agree with that? (i'm talking about js execution and not download, fetching or whatever)Landgrave
I already agreed with that, and showed the spec which defines it. Rendering and JS execution happens as part of the same event loop, so they can block each other.Shel
So if we agree with each other about that then why you are not agree with me that talking about avoiding "render blocking javascript" by using defer and async is kind of weird and confusing, because javascript execution is always render blocking.Landgrave
See: rendering-async-defer.glitch.me By default is Glitch using: "cache-control => max-age=0", kind of weird in my opinion, so now i can not show you the caching case. But the content will be shown AFTER 5 seconds in a caching case with my example. I am trying to avoid that and showing the content immediately. So as you can see in the example, your defer solution is not a remedy for that. Disable caching is a solution for it, because then the content will be shown within 5 seconds. Do you get my point or which part i have to explain more?Landgrave
Javascript files from Google, Facebook are usually already in the visitors cache. And anyway with the second visit your own files usually are also in the visitors cache. So in cases like that (and there are plenty): solutions like async, defer are not avoiding "render blocking".Landgrave
Maybe you will get it like this. I will use a metaphor to make it clear. Google is actually saying: i'm gonna avoid that the sun shines. Then they will take you to the night and they are saying: now the sun does not shine. That's incorrect, because the sun is "always" shining. And that's the same with avoiding "render blocking Javascript". You can not avoid something that is always the case.Landgrave
M
0

Maarten B, I did test you code and you are correct indeed. Whether you use async, defer or whatever, the lines above the inline JavaScript are not beeing rendered. The information in the documentation of Google is therefore incorrect.

Mucilage answered 30/10, 2017 at 18:33 Comment(1)
Which piece of documentation do you consider incorrect?Shel

© 2022 - 2024 — McMap. All rights reserved.