首页 > 解决方案 > 在正文标记末尾呈现阻止 Javascript - 内联与外部脚本

问题描述

这是基于对先前问题的观察的后续行动。将此作为一个单独的问题进行讨论并且不要使原始问题过于宽泛是有道理的。

根据我的理解,javascript 默认是渲染阻塞并且它会停止 DOM 解析,这似乎表明只有在所有同步脚本都执行后才会渲染页面。

考虑以下示例:
案例 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>

这确实会在脚本执行之前阻止浏览器呈现。
Chrome 在脚本执行后呈现。
Firefox 在脚本执行后呈现。

如果我将同一段 javascript 提取到外部文件中,如下所示:

<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>

外部.js

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

}

console.log('here external');

Chrome 在脚本执行之前呈现。
Firefox 在脚本执行后呈现。

现在考虑另一个例子:
案例 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 在脚本执行之前呈现。
Firefox 在脚本执行之前呈现。

浏览器:
Chrome 版本:78
Firefox 版本:70

我还没有弄清楚当脚本是内联脚本还是外部脚本时这种行为的原因。任何指针都会有所帮助。这两种情况不应该在所有浏览器中定义为渲染阻塞吗?

Chrome 似乎在内联脚本之后呈现,但在外部脚本之前呈现。Firefox 似乎在内联脚本之后渲染,在案例 1 的外部脚本之后,但在案例 2 的外部脚本之前。

如果我们像这样将脚本标签放在 html 之间,则会观察到类似的行为:

<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>

Chrome 在脚本执行之前再次渲染前 4 个 div。
Firefox 会在执行后呈现所有内容。

但是如果我们用另一个脚本替换脚本标签:

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

Firefox 在脚本执行前渲染前 4 个 div,与案例 2 相同。

标签: javascriptgoogle-chromefirefoxweb-performance

解决方案


推荐阅读