Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
322 views
in Technique[技术] by (71.8m points)

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

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...