PageSpeed 规则和建议

Ilya Grigorik
Ilya Grigorik

本指南审视 PageSpeed Insights 规则背景:优化关键渲染路径时的注意事项以及原因。

消除阻塞渲染的 JavaScript 和 CSS

要以最快的速度进行首次渲染,请尽量减少网页上关键资源的数量并(尽可能)消除,尽可能减少下载的关键字节数,以及优化关键路径长度。

优化 JavaScript 的使用

默认情况下,JavaScript 资源会阻止解析器,除非将其标记为 async 或通过特殊的 JavaScript 代码段进行添加。阻塞解析器的 JavaScript 会强制浏览器等待 CSSOM 并暂停 DOM 的构建,继而会显著延迟首次渲染的时间。

首选异步 JavaScript 资源

异步资源取消屏蔽文档解析器,让浏览器在执行脚本之前避免阻塞 CSSOM。通常,如果脚本可以使用 async 属性,也就意味着它并非首次渲染所必需。考虑在首次渲染后异步加载脚本。

避免同步服务器调用

使用 navigator.sendBeacon() 方法可限制 unload 处理程序中 XMLHttpRequest 发送的数据。由于许多浏览器都要求同步此类请求,因此它们可能会减慢网页转换速度,有时还很明显。以下代码展示了如何在 pagehide 处理程序(而不是 unload 处理程序)中使用 navigator.sendBeacon() 将数据发送到服务器。

    <script>
      function() {
        window.addEventListener('pagehide', logData, false);
        function logData() {
          navigator.sendBeacon(
            'https://putsreq.herokuapp.com/Dt7t2QzUkG18aDTMMcop',
            'Sent by a beacon!');
        }
      }();
    </script>

新的 fetch() 方法提供了一种简单的方法来异步请求数据。由于该功能尚未在所有国家/地区推出,因此您应该使用功能检测来测试其是否存在,然后再使用。此方法使用 Promise 而不是多个事件处理程序来处理响应。与对 XMLHttpRequest 的响应不同,从 Chrome 43 开始,fetch 响应将是信息流对象。这意味着,调用 json() 也会返回 Promise。

    <script>
    fetch('./api/some.json')
      .then(
        function(response) {
          if (response.status !== 200) {
            console.log('Looks like there was a problem. Status Code: ' +  response.status);
            return;
          }
          // Examine the text in the response
          response.json().then(function(data) {
            console.log(data);
          });
        }
      )
      .catch(function(err) {
        console.log('Fetch Error :-S', err);
      });
    </script>

fetch() 方法也可以处理 POST 请求。

    <script>
    fetch(url, {
      method: 'post',
      headers: {
        "Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
      },
      body: 'foo=bar&lorem=ipsum'
    }).then(function() { // Additional code });
    </script>

延迟解析 JavaScript

为了尽量减少浏览器渲染网页的工作量,请延迟所有非必要的脚本,即对构建首次渲染的可见内容没有关键意义的脚本。

避免长时间运行的 JavaScript

运行时间过长的 JavaScript 会阻止浏览器构建 DOM、CSSOM 以及渲染网页,因此请推迟到以后首次渲染时不需要的任何初始化逻辑和功能。如果需要运行较长的初始化序列,请考虑将其拆分为几个阶段,以便浏览器可以中间处理其他事件。

优化 CSS 的使用

CSS 是构建渲染树的必备元素,首次构建网页时,JavaScript 常常会在 CSS 上受阻。确保将所有非必需的 CSS 都标记为非关键 CSS(例如打印和其他媒体查询),并确保关键 CSS 的数量和提交时间尽可能短。

将 CSS 放在文档标头处

尽早在 HTML 文档中指定所有 CSS 资源,以便浏览器尽快发现 <link> 标记并分派 CSS 请求。

避免 CSS 导入

一个样式表可以使用 CSS import (@import) 指令从另一个样式表文件导入规则。但是,请避免使用这些指令,因为它们会在关键路径中增加往返次数:只有在收到并解析完包含 @import 规则的 CSS 样式表之后,才会发现导入的 CSS 资源。

内嵌阻止呈现的 CSS

为获得最佳效果,您可以考虑将关键 CSS 直接内嵌到 HTML 文档中。这样可避免关键路径中出现额外的往返次数,并且如果操作正确,在只有 HTML 为阻塞性资源的情况下,可提供“一次往返”关键路径长度。

反馈