有效載入第三方 JavaScript

Milica Mihajlija
Milica Mihajlija

如果第三方指令碼拖慢您的網頁載入,有兩種方式可以提升效能:

  • 如果這個參數無法為網站增添明確價值,請移除。
  • 改善載入程序。

本文說明如何使用下列技巧最佳化第三方指令碼的載入程序:

  • <script> 標記上使用 asyncdefer 屬性
  • 建立前往必要來源的早期連線
  • 延遲載入
  • 最佳化第三方指令碼的供應方式

使用asyncdefer

由於同步指令碼會延遲 DOM 建構與轉譯,因此除非指令碼必須先執行,網頁才能轉譯,否則您應一律以非同步方式載入第三方指令碼。

asyncdefer 屬性會告訴瀏覽器,在背景載入指令碼時,可以先剖析 HTML,然後在載入後執行指令碼。如此一來,指令碼下載就不會妨礙 DOM 建構或網頁轉譯程序,因此使用者在所有指令碼載入完成前就能查看頁面。

<script async src="script.js">

<script defer src="script.js">

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

async

含有 async 屬性的指令碼會在下載完成後,以及視窗的 load 事件前,在第一個機會執行。因此,async 指令碼可能無法依照在 HTML 中的顯示順序執行。這也表示在剖析器仍在運作時,如果完成下載作業,就會中斷 DOM 建構作業。

採用非同步屬性的剖析器封鎖指令碼圖表
包含 async 的指令碼仍可封鎖 HTML 剖析。

defer

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

含有延遲屬性的指令碼的剖析器流程圖表
含有 defer 的指令碼會等到瀏覽器完成 HTML 剖析後執行。
  • 如果必須在載入過程中提早執行指令碼,請使用 async
  • defer 用於較不重要的資源,例如需捲動位置的影片播放器。

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

與必要來源建立早期連線

建立早期連線至重要的第三方來源,即可節省 100 至 500 毫秒。

preconnectdns-prefetch 有兩種 <link> 類型可協助您:

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 前,指示瀏覽器只解析特定網域的 DNS。

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

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

dns-prefetch 的瀏覽器支援與 preconnect 支援稍有不同,因此 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,可有效地偵測元素進入或離開瀏覽器可視區域的時機,可用來實作這項技巧。Lazysize 是常見的 JavaScript 程式庫,適用於延遲載入圖片和 iframes。並支援 YouTube 嵌入和小工具。這個 API 也提供 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 變更或安全性修正項目時無法自動更新。

使用 Service Worker 從第三方伺服器快取指令碼

您可以使用服務工作站從第三方伺服器快取指令碼,做為自行託管的替代方案。這可讓您進一步掌控快取 同時仍保有第三方 CDN 的優點

您可以控制系統從網路重新擷取指令碼的頻率,並建立載入策略,限制非必要第三方資源要求,直到使用者抵達網頁上的重要互動為止。您可以使用 preconnect 建立早期連線,也可以協助降低網路費用。