PageSpeed 規則和建議

Ilya Grigorik
Ilya Grigorik

發布日期:2018 年 8 月 17 日

本指南將從整體角度檢視 PageSpeed Insights 規則:在最佳化關鍵運算路徑時,應注意哪些事項,以及原因為何。

移除會妨礙顯示的 JavaScript 和 CSS

為了加快首次轉譯的速度,請盡可能減少並 (可能) 減少頁面上的關鍵資源數量、將下載的重要位元組數降到最低,並最佳化關鍵路徑長度。

最佳化 JavaScript 用量

除非標示為 async,或使用特殊 JavaScript 程式碼片段新增,否則 JavaScript 資源會根據預設遭到剖析器封鎖。解析器阻擋 JavaScript 會迫使瀏覽器等待 CSSOM,並暫停 DOM 的建構作業,進而大幅延遲首次轉譯作業的時間。

偏好非同步 JavaScript 資源

非同步資源會解除文件剖析器的封鎖,讓瀏覽器在執行指令碼前避免 CSSOM 封鎖。通常,如果指令碼可以使用 async 屬性,就表示該指令碼在第一次算繪時並非必要。建議在初次轉譯後,以非同步方式載入指令碼。

避免同步伺服器呼叫

請使用 navigator.sendBeacon() 方法,限制 unload 處理常式中 XMLHttpRequest 傳送的資料。由於許多瀏覽器要求這類要求必須同步處理,因此這類要求可能會導致網頁轉換速度變慢,有時甚至會明顯變慢。以下程式碼會示範如何使用 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() 方法提供更好的非同步要求資料方式。fetch() 會使用 Promise 處理回應,而非多個事件處理常式。與 XMLHttpRequest 的回應不同,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

請盡早在 HTML 文件中指定所有 CSS 資源,讓瀏覽器能夠盡快發現 <link> 標記,並調度 CSS 要求。

避免匯入 CSS

CSS 匯入指示詞 (@import) 可讓一個樣式表匯入其他樣式表檔案中的規則。不過,請避免使用這些指示詞,因為這會在關鍵路徑中引入額外的往返作業:只有在收到並剖析含有 @import 規則的 CSS 樣式表後,系統才會發現匯入的 CSS 資源。

嵌入禁止轉譯 CSS

為獲得最佳成效,建議您考慮在 HTML 文件中直接內嵌重要的 CSS。這麼做可避免在關鍵路徑中產生額外的往返次數,如果執行正確,則可提供「單趟」關鍵路徑長度,其中只有 HTML 是阻斷資源。

意見回饋