PageSpeed 规则和建议

伊利亚·格里戈里克
Ilya Grigorik

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

移除阻塞渲染的 JavaScript 和 CSS

为了以最快的速度完成首次渲染,请尽可能减少并(如果可能)消除网页上的关键资源数量,最大限度地减少下载的关键字节数,以及优化关键路径长度。

优化 JavaScript 的使用

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

首选异步 JavaScript 资源

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

避免同步服务器调用

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

    <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 开始,提取响应是一个数据流对象。这意味着,调用 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 放在文档标头处

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

避免 CSS 导入

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

内嵌阻止呈现的 CSS

为实现最佳效果,您可能需要考虑将关键 CSS 直接内嵌到 HTML 文档中。这样可以避免关键路径中的额外往返,并且如果操作正确,在只有 HTML 是阻塞资源时,可以实现“一次往返”关键路径长度。

反馈