有效載入第三方 JavaScript

Milica Mihajlija
Milica Mihajlija

如果第三方指令碼減緩網頁載入速度,您可以使用以下兩種方法來改善效能:

  • 如果這項功能無法為您的網站帶來明顯價值,請將其移除。
  • 改善載入程序。

本文將說明如何使用下列技術,改善第三方指令碼的載入程序:

  • <script> 標記上使用 asyncdefer 屬性
  • 建立必要來源的早期連線
  • 延遲載入
  • 改善第三方指令碼的放送方式

由於同步指令碼會延遲 DOM 建構和算繪作業,因此您應一律以非同步方式載入第三方指令碼,除非指令碼必須在網頁算繪前執行。

asyncdefer 屬性會告訴瀏覽器,在背景載入指令碼時,可以繼續剖析 HTML,然後在載入完成後執行指令碼。這樣一來,指令碼下載作業就不會阻斷 DOM 建構或網頁轉譯作業,讓使用者在所有指令碼都載入完成前,就能看到網頁。

<script async src="script.js">

<script defer src="script.js">

asyncdefer 屬性的差異在於瀏覽器執行指令碼的時間。

async

具有 async 屬性的指令碼會在完成下載後,並在視窗的 load 事件發生前,於第一個機會執行。這表示 async 指令碼可能不會按照 HTML 中的顯示順序執行。這也表示,如果解析器仍在運作時,他們可以中斷 DOM 建構作業。

含有 async 屬性的剖析器封鎖指令碼圖表
含有 async 的指令碼仍可阻擋 HTML 剖析。

defer

含有 defer 屬性的指令碼會在 HTML 剖析作業完成後,但在 DOMContentLoaded 事件之前執行。defer 可確保指令碼按照 HTML 中的顯示順序執行,且不會阻擋剖析器。

含有延遲屬性指令碼的剖析器流程圖
含有 defer 的 Scripts 會等待執行,直到瀏覽器完成剖析 HTML 為止。
  • 如果需要在載入程序的早期執行指令碼,請使用 async
  • 請將 defer 用於較不重要的資源,例如位於折疊區域下的影片播放器。

使用這些屬性可大幅提升網頁載入速度。舉例來說,Telegraph 延遲了所有指令碼 (包括廣告和數據分析),並將廣告載入時間縮短了平均四秒。

建立必要來源的早期連線

及早連線至重要的第三方來源,可節省 100 到 500 毫秒的時間。

兩種 <link> 類型 preconnectdns-prefetch 可在這裡提供協助:

preconnect

<link rel="preconnect"> 會告知瀏覽器,您的網頁想要建立與其他來源的連線,且您希望盡快開始這個程序。當瀏覽器從預先連結的來源要求資源時,下載作業會立即開始。

<link rel="preconnect" href="https://cdn.example.com">

dns-prefetch

<link rel="dns-prefetch> 處理的內容僅是 <link rel="preconnect"> 處理內容的一小部分。建立連線時,系統會執行 DNS 查詢和 TCP 握手,如果是安全來源,則會進行 TLS 協商。dns-prefetch 會指示瀏覽器在明確呼叫特定網域之前,只解析該網域的 DNS。

preconnect 提示最適合用於最關鍵的連線。如果是較不重要的第三方網域,請使用 <link rel=dns-prefetch>

<link rel="dns-prefetch" href="http://example.com">

瀏覽器支援 dns-prefetchpreconnect 支援 略有不同,因此 dns-prefetch 可做為不支援 preconnect 的瀏覽器的備用方案。請使用個別的連結代碼來安全地實作這項功能:

<link rel="preconnect" href="http://example.com">
<link rel="dns-prefetch" href="http://example.com">

延遲載入第三方資源

如果內嵌的第三方資源建構不良,可能會大幅減緩網頁載入速度。如果這些內容不是必要的,或位於折頁下方 (也就是使用者必須捲動畫面才能查看),延遲載入是改善網頁速度和繪製指標的好方法。這樣一來,使用者就能更快取得主要網頁內容,享有更優質的體驗。

行動裝置上顯示的網頁示意圖,其中可捲動內容超出螢幕範圍。下方內容未載入,因此會呈現低飽和度。
延遲載入位於需捲動位置的內容。

一種有效的方法是在主要網頁內容載入後,延後載入第三方內容。廣告是採用這種做法的理想選擇。

廣告是許多網站的重要收入來源,但使用者是為了內容而來。透過延遲載入廣告並加快主要內容的放送速度,您就能提高廣告的整體可視率百分比。舉例來說,MediaVine 改用延遲載入廣告後,網頁載入速度提升了 200%。Google Ad Manager 說明文件說明如何延遲載入廣告

您也可以設定只在使用者首次捲動至網頁該部分時,才載入第三方內容。

Intersection Observer 是一種瀏覽器 API,可有效偵測元素進入或離開瀏覽器檢視區的時間,您可以使用此 API 實作這項技術。lazysizes 是一種常見的 JavaScript 程式庫,可用於延後載入圖片和 iframes。支援 YouTube 嵌入和小工具。Intersection Observer 也提供選用支援

使用 loading 屬性來延後載入圖片和 iframe,是 JavaScript 技巧的絕佳替代方案,而且最近在 Chrome 76 中也已推出!

改善第三方指令碼的放送方式

以下是一些建議的策略,可協助您改善第三方指令碼的使用方式。

第三方 CDN 代管服務

第三方供應商通常會為其代管的 JavaScript 檔案提供網址,通常是位於內容傳遞網路 (CDN) 中。這種方法的好處是,您可以快速開始使用 (只要複製及貼上網址即可),而且沒有維護成本。第三方供應商會處理伺服器設定和指令碼更新。

但由於這些檔案與其他資源不在相同來源,因此從公開 CDN 載入檔案會產生網路費用。瀏覽器需要執行 DNS 查詢、建立新的 HTTP 連線,並在安全來源上與供應商的伺服器執行 SSL 握手。

使用第三方伺服器的檔案時,您幾乎無法控制快取。依賴他人快取策略可能會導致不必要的情況,導致系統經常從網路重新擷取指令碼。

自行託管的第三方指令碼

自行代管第三方腳本可讓您進一步控管腳本的載入程序。自行代管可讓您:

  • 縮短 DNS 查詢和往返時間。
  • 改善 HTTP 快取標頭。
  • 善用 HTTP/2 或較新的 HTTP/3。

舉例來說,Casper 透過自行代管 A/B 測試指令碼,成功縮短 1.7 秒的載入時間。

不過,自行代管有一個重大缺點:指令碼可能會過時,且不會在 API 變更或安全性修復時自動更新。

使用服務工作者將第三方伺服器的指令碼快取

您可以使用服務工作者來快取第三方伺服器的程式碼,做為自助代管的替代方案。這樣一來,您就能進一步控管快取,同時保留第三方 CDN 的優點。

您可以控制從網路重新擷取指令碼的頻率,並建立載入策略,在使用者到達網頁上的關鍵互動前,限制對非必要第三方資源的要求。有了 preconnect,您就能及早建立連線,並協助降低網路成本。