PageSpeed 規則和建議

Ilya Grigorik
Ilya Grigorik

發布日期:2018 年 8 月 17 日

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

移除會妨礙顯示的 JavaScript 和 CSS

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

最佳化 JavaScript 用量

除非將 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 的數量和載入時間。

在文件標頭中加入 CSS

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

避免匯入 CSS

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

嵌入禁止轉譯 CSS

為獲得最佳效能,建議您直接將必要 CSS 嵌入 HTML 文件。如此就能避免重要路徑上的額外往返,而且如果正確,可以傳送「一次來回」因為只有 HTML 是造成阻斷資源的重要路徑長度。

意見回饋