移除会阻止内容呈现的 JavaScript

当 PageSpeed Insights 检测到以下情形时,就会触发此规则:您的 HTML 在网页首屏部分中引用了一个会阻止内容呈现的外部 JavaScript 文件。

概览

浏览器必须先通过解析 HTML 标记来构建 DOM 树,然后才能呈现网页。 在此过程中,每当解析器遇到脚本时,它都必须先停止解析 HTML 并执行该脚本,然后才能继续解析。对于外部脚本,系统还会强制解析器等待相应资源下载完毕(这可能会产生一次或多次网络往返过程并导致网页的首次呈现时间延迟)。 要想详细了解 JavaScript 对关键呈现路径有何影响,请参阅使用 JavaScript 添加互动性

建议

您应尽可能避免使用会阻止内容呈现的 JavaScript,尤其是必须先由系统获取然后才能被执行的外部脚本。用于呈现网页内容的脚本可内嵌到网页中,以避免产生额外的网络请求,但内嵌的内容不能太大,而且必须可被快速执行以提供良好的性能。对初次呈现不重要的脚本应设为异步加载,或推迟到首次呈现完毕后再开始加载。请注意,要通过这种方式缩短加载用时,您还必须优化 CSS 发送过程

内嵌 JavaScript

会阻止内容呈现的外部脚本会强制浏览器等待系统获取 JavaScript,这可能会使系统在网页得以呈现之前增加一次或多次网络往返过程。如果外部脚本较小,您可将其内容直接内嵌到 HTML 文档中,以避免造成网络请求延迟。例如,如果 HTML 文档如下所示:
<html>
  <head>
    <script type="text/javascript" src="small.js"></script>
  </head>
  <body>
    <div>
      Hello, world!
    </div>
  </body>
</html>
资源 small.js 如下所示:
  /* contents of a small JavaScript file */
您就可以按照如下方式内嵌脚本:
<html>
  <head>
    <script type="text/javascript">
      /* contents of a small JavaScript file */
    </script>
  </head>
  <body>
    <div>
      Hello, world!
    </div>
  </body>
</html>
内嵌脚本内容可消除对 small.js 的外部请求,并可使浏览器缩短首次呈现网页所需的时间。但请注意,内嵌也会导致 HTML 文档变大,并且相同的脚本内容可能需要内嵌在多个网页中。因此,我们建议您只内嵌较小的脚本以实现最佳性能。

将 JavaScript 设为异步加载

默认情况下,JavaScript 会阻止 DOM 构建,因而会导致网页的首次呈现时间延迟。为防止 JavaScript 阻止解析器正常运行,我们建议您对外部脚本使用 HTML async 属性。例如:
<script async src="my.js">
要详细了解异步脚本,请参阅解析器被阻止与异步 JavaScript。 请注意,异步脚本未必会按指定的顺序执行,且不应使用 document.write。考虑到这些限制,如果脚本有赖于执行顺序或者需要访问或修改网页的 DOM 或 CSSOM,那么您可能需要重新编写此类脚本。

延迟加载 JavaScript

如果某些脚本对于初次呈现网页不是必不可少的,此类脚本的加载和执行便可被推迟到初次呈现网页后或网页的其他关键部分加载完毕后。这样做有助于减少资源争用并提高性能。

常见问题解答

如果我使用的是 JavaScript 库(例如 jQuery),该怎么做?
很多 JavaScript 库(例如 jQuery)都可用来增强网页,从而为网页增添额外的互动性、动画和其他效果。不过,这些行为大多可在首屏内容呈现后再添加,以确保无虞。 请考虑将此类 JavaScript 设为异步加载或推迟其加载时间。
如果我使用 JavaScript 框架来构建网页,该如何操作?
如果网页内容是由客户端 JavaScript 构建的,那么我们建议您考虑嵌入相关的 JavaScript 模块以避免产生额外的网络往返过程。同样,利用服务器端呈现可显著提升网页的首次加载速度,具体方法如下:在服务器上呈现 JavaScript 模板以加快首次呈现速度,然后在网页加载完毕后使用客户端模板。要想详细了解服务器端呈现,请参见 http://youtu.be/VKTWdaupft0?t=14m28s