render-blocking Javascript at end of body tag - inline vs external script

天涯浪子 提交于 2020-01-05 03:51:10

问题


This is a follow up based on observations of a previous question. It made sense to discuss this as a separate question and to not make the original question too broad.

As per my understanding, javascript by default is render blocking and it stops DOM parsing, which seems to suggest that the page would only be rendered after all synchronous scripts have executed.

Consider the below example:
Case 1:

<html>
  <head>
  </head>
  <body>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <script>
      for(var i=0; i< 900000000; i++) {

      }

      console.log('here inline');
    </script>
  </body>
</html>

This does stop the browser from rendering before the script is executed.
Chrome renders after script execution.
Firefox renders after script execution.

If i extract the same piece of javascript to an external file, like this:

<html>
  <head>
  </head>
  <body>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <script src="./external.js"></script>
  </body>
</html>

external.js

for(var i=0; i< 900000000; i++) {

}

console.log('here external');

Chrome renders before script execution.
Firefox renders after script execution.

Now consider another example:
Case 2

<html>
  <head>
  </head>
  <body>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <script src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>
  </body>
</html>

Chrome renders before script execution.
Firefox renders before script execution.

Browsers:
Chrome version: 78
Firefox version: 70

I am yet to figure out a reason for this behaviour when the script is inline vs when it is external. Any pointers would be helpful. Shouldn't both of these cases be render blocking by definition in all the browsers?

Chrome seems to render after inline script, but before external script. Firefox seems to render after inline script, after external script in case 1, but before external script in case 2.

Similar behaviour is observed if we put the script tag in between the html like this:

<html>
  <head>
  </head>
  <body>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <script src="./external.js"></script>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
    <div>Some Content</div>
  </body>
</html>

again Chrome renders the first 4 divs before script execution.
Firefox renders everything after execution.

but if we replace the script tag with the other script:

<script src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>

Firefox renders the first 4 divs before script execution, same as in Case 2.

来源:https://stackoverflow.com/questions/59471566/render-blocking-javascript-at-end-of-body-tag-inline-vs-external-script

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!