PageSpeed 規則和建議

Ilya Grigorik
Ilya Grigorik

本指南會檢視 PageSpeed Insights 規則的背景資訊,在最佳化重要轉譯路徑時應留意的事項與原因。

排除禁止轉譯的 JavaScript 和 CSS

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

針對 JavaScript 使用情形進行最佳化

根據預設,除非將 JavaScript 資源標示為 async 或透過特殊 JavaScript 程式碼片段新增,否則 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

請盡早在 HTML 文件中指定所有 CSS 資源,以便瀏覽器發現 <link> 標記並盡快針對 CSS 發送要求。

避免匯入 CSS

CSS 匯入 (@import) 指令可讓樣式表從其他樣式表檔案匯入規則。不過,請避免使用這類指令,在關鍵路徑中導入額外的往返作業:只有在接收並剖析含有 @import 規則的 CSS 樣式表後,才會找到匯入的 CSS 資源。

嵌入禁止轉譯 CSS

為獲得最佳成效,建議您考慮在 HTML 文件中直接內嵌重要的 CSS。這樣可以避免重要路徑中出現額外的往返作業,而且如果正確完成,即可傳送「一次往返」關鍵路徑長度,只有 HTML 是會阻擋資源的資源。

意見回饋: