如果第三方指令碼拖慢您的網頁載入,有兩種方式可以提升效能:
- 如果這個參數無法為網站增添明確價值,請移除。
- 改善載入程序。
本文說明如何使用下列技巧最佳化第三方指令碼的載入程序:
- 在
<script>
標記上使用async
或defer
屬性 - 建立前往必要來源的早期連線
- 延遲載入
- 最佳化第三方指令碼的供應方式
使用async
或defer
由於同步指令碼會延遲 DOM 建構與轉譯,因此除非指令碼必須先執行,網頁才能轉譯,否則您應一律以非同步方式載入第三方指令碼。
async
和 defer
屬性會告訴瀏覽器,在背景載入指令碼時,可以先剖析 HTML,然後在載入後執行指令碼。如此一來,指令碼下載就不會妨礙 DOM 建構或網頁轉譯程序,因此使用者在所有指令碼載入完成前就能查看頁面。
<script async src="script.js">
<script defer src="script.js">
async
和 defer
屬性的差異,在於瀏覽器執行指令碼時。
async
含有 async
屬性的指令碼會在下載完成後,以及視窗的 load 事件前,在第一個機會執行。因此,async
指令碼可能無法依照在 HTML 中的顯示順序執行。這也表示在剖析器仍在運作時,如果完成下載作業,就會中斷 DOM 建構作業。
![採用非同步屬性的剖析器封鎖指令碼圖表](https://web.developers.google.cn/static/articles/efficiently-load-third-party-javascript/image/diagram-parser-blocking-020263bc7658c.png?authuser=3&hl=zh-tw)
async
的指令碼仍可封鎖 HTML 剖析。defer
含有 defer
屬性的指令碼會在 HTML 剖析作業完全完成後、但在 DOMContentLoaded
事件之前執行。defer
能確保指令碼按照在 HTML 中的顯示順序執行,而且不會封鎖剖析器。
![含有延遲屬性的指令碼的剖析器流程圖表](https://web.developers.google.cn/static/articles/efficiently-load-third-party-javascript/image/diagram-parser-flow-a-s-f9a9ef751f974.png?authuser=3&hl=zh-tw)
defer
的指令碼會等到瀏覽器完成 HTML 剖析後執行。- 如果必須在載入過程中提早執行指令碼,請使用
async
。 - 將
defer
用於較不重要的資源,例如需捲動位置的影片播放器。
使用這些屬性可大幅加快網頁載入速度。例如,Telegraph 延遲所有指令碼 (包括廣告和分析) 並將廣告載入時間平均縮短四秒。
與必要來源建立早期連線
建立早期連線至重要的第三方來源,即可節省 100 至 500 毫秒。
preconnect
和 dns-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">
延遲載入第三方資源
內嵌的第三方資源如果建構不良,可能會大幅降低網頁載入速度。如果這些標記不重要,或是位於需捲動位置 (亦即使用者必須捲動才能查看),延遲載入是改善網頁速度和繪製指標的好方法。如此一來,使用者便可更快速地存取主頁面,享有更優質的體驗。
![行動裝置螢幕上顯示的圖表,可捲動內容超出畫面範圍。需捲動位置的內容尚未載入,因此較為飽和。](https://web.developers.google.cn/static/articles/efficiently-load-third-party-javascript/image/a-diagram-a-webpage-show-0c848a2212482.png?authuser=3&hl=zh-tw)
其中一個有效方法是在主網頁內容載入後延遲載入第三方內容。廣告十分適合採用此方法。
廣告是許多網站的重要收入來源,但使用者卻會上網。只要延遲載入廣告,並更快放送主要內容,就能提高廣告的整體可視度百分比。舉例來說,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 交握。
使用第三方伺服器中的檔案時,幾乎無法控制快取。依賴他人的快取策略,可能會導致指令碼過於頻繁地從網路重新擷取。
自行管理第三方指令碼
您可以選擇自行管理第三方指令碼,進一步控管指令碼的載入程序。自行代管可讓您:
例如,Casper 透過自行託管 A/B 測試指令碼來管理 1.7 秒的載入時間。
自我託管有一大缺點:指令碼可能過時,而且在 API 變更或安全性修正項目時無法自動更新。
使用 Service Worker 從第三方伺服器快取指令碼
您可以使用服務工作站從第三方伺服器快取指令碼,做為自行託管的替代方案。這可讓您進一步掌控快取 同時仍保有第三方 CDN 的優點
您可以控制系統從網路重新擷取指令碼的頻率,並建立載入策略,限制非必要第三方資源要求,直到使用者抵達網頁上的重要互動為止。您可以使用 preconnect
建立早期連線,也可以協助降低網路費用。