JavaScript 啟動最佳化

Addy Osmani
Addy Osmani

隨著我們建立網站越來越依賴 JavaScript 來建構網站,我們有時也會為了傳送內容而付出代價,我們有時難以察覺。如想瞭解如何在行動裝置上快速載入網站並方便互動,請參閱這份重點。傳送較少 JavaScript 可以減少網路傳輸的時間、降低解壓縮程式碼所花費的時間,以及縮短剖析和編譯這個 JavaScript 的時間。

網路

多數開發人員思考 JavaScript 的費用時,會考量下載和執行費用。透過線傳送更多的 JavaScript 位元組,使用者的連線速度會越慢。

當瀏覽器要求資源時,系統必須擷取該資源後再解壓縮。如果是 JavaScript 等資源,則必須在執行前剖析及編譯。

這可能是問題,因為使用者有效的網路連線類型不是 3G、4G 或 Wi-Fi。您可以用咖啡店 Wi-Fi,但連線至有 2G 速度的行動網路無線基地台。

您可以透過以下途徑降低 JavaScript 的網路傳輸費用:

  • 只傳送使用者需要的程式碼
  • 壓縮
  • 壓縮
    • 至少使用 gzip 壓縮文字資源。
    • 請考慮使用 Brotli ~ q11。Brotli 在壓縮率上超越 gzip。這種做法讓 CertSimple 的 JS 位元組大小減少 17%,LinkedIn 則節省了 4% 的載入時間。
  • 移除未使用的程式碼
  • 快取程式碼以盡量減少網路行程。
    • 使用 HTTP 快取,確保瀏覽器能有效快取回應。為指令碼 (max-age) 和提供驗證權杖 (ETag) 決定最佳生命週期,避免轉移未變更的位元組。
    • Service Worker 快取功能可讓應用程式網路更具彈性,並讓您立即使用 V8 的程式碼快取等功能。
    • 使用長期快取可避免系統重新擷取未變更的資源。如果使用 Webpack,請參閱檔案名稱雜湊

剖析/編譯

下載之後,JavaScript 引擎的「最主要」費用是 JS 引擎剖析/編譯程式碼所需的時間。在 Chrome 開發人員工具中,剖析和編譯是在「Performance」(效能) 面板中顯示黃色的「指令碼處理」時間。

ALT_TEXT_HERE

「Bottom-Up」和「Call Tree」分頁會顯示詳細的剖析/編譯時間:

ALT_TEXT_HERE
Chrome 開發人員工具效能面板 > 由下往上。啟用 V8 的執行階段呼叫統計資料後,即可查看剖析和編譯等階段花費的時間。

但這很重要嗎?

ALT_TEXT_HERE

花費較長時間剖析/編譯程式碼,可能會嚴重延遲使用者與網站互動的時間。傳送的 JavaScript 越多,網站在互動式網站前剖析和編譯所需的時間就越長。

位元組大小的 JavaScript 比瀏覽器大小相同的圖片或網路字型更為昂貴 — Tom Dale

與 JavaScript 相比,在處理大小相等的圖片時需要支付大量費用 (因此圖片仍須解碼!),但以一般行動硬體來說,JS 較有可能對網頁的互動產生負面影響。

ALT_TEXT_HERE
JavaScript 和圖片位元組的費用差異很大。一般來說,圖片不會封鎖主執行緒,也不會在解碼和光柵化時讓介面具備互動功能。不過,JS 可能會因為剖析、編譯和執行費用而延遲互動。

這裡所說的剖析和編譯速度緩慢;背景資訊很重要,我們今天要討論的是「一般」手機。一般使用者可以擁有搭載緩慢 CPU 和 GPU 的手機、沒有 L2/L3 快取,甚至記憶體可能有限。

網路功能和裝置功能不一定會相同。如果使用者擁有出色的 Fiber 連線,不見得最好的 CPU 來剖析和評估傳送至其裝置的 JavaScript。情況在逆境中也是如此:網路連線不穩,而是快速 CPU。— Kristofer Baxter,LinkedIn

下方是低階與高階硬體剖析約 1 MB 解壓縮 (簡易) JavaScript 的費用。在市面上最快速的手機和一般手機之間,剖析/編譯程式碼所需的時間是 2 到 5 倍

ALT_TEXT_HERE
這個圖表針對不同類別的電腦和行動裝置,醒目顯示 1 MB 組 JavaScript 組合 (約 250 KB 壓縮) 的剖析時間。查看剖析成本時,需要考量的已壓縮數據,例如約 250KB 以 gzip 格式解壓縮的 JS 會解壓縮至約 1 MB 的程式碼。

像 CNN.com 這樣的真實網站會怎麼樣?

在高階 iPhone 8 上,相較於一般手機 (Moto G4) 大約 13 秒,只需大約 4 秒剖析/編譯 CNN 的 JS。這可能會大幅影響使用者能與這個網站完整互動的速度。

ALT_TEXT_HERE
以上我們見過剖析時間,比較 Apple 的 A11 Bionic 晶片和 Snapdragon 617 是一般 Android 硬體的表現。

這突顯出在「一般」硬體 (例如 Moto G4) 上進行測試的重要性,而不是只放在口袋中的手機。不過情境很重要:根據使用者的裝置和網路條件進行最佳化

ALT_TEXT_HERE
Google Analytics (分析) 能夠深入分析使用者用來存取您網站的行動裝置類別。這有助於瞭解用於操作的實際 CPU/GPU 限制。

我們確實傳送了過多的 JavaScript 嗎?呃,可能 :)

現在,我們可以透過 HTTP 封存檔 (前 50 萬個網站) 分析行動裝置上的 JavaScript 狀態,可以看到有 50% 的網站需要超過 14 秒才能產生互動。這些網站花最多 4 秒的時間剖析及編譯 JS。

ALT_TEXT_HERE

考慮擷取和處理 JS 和其他資源所需的時間,可能令人感到意外的是,使用者在感覺頁面可供使用之前可能會離開一段時間。我們確實可以做得更好。

從網頁中移除非關鍵的 JavaScript 可縮短傳輸時間、大量剖析 CPU 和編譯,也可能造成記憶體負擔。這也有助於加快網頁互動速度。

執行時間

這不只是剖析及編譯,也可能導致成本增加。JavaScript 執行 (在剖析/編譯後執行程式碼) 是必須在主執行緒上執行的其中一項作業。長時間的執行時間可能也可能導致使用者多快能與您的網站互動。

ALT_TEXT_HERE

如果指令碼執行的時間超過 50 毫秒,互動時間會延遲到下載、編譯及執行 JS 所需的「整個」時間 — Alex Russell - Alex Russell

為解決這個問題,JavaScript 的優點在於小型區塊,以免鎖定主執行緒。確認是否可以減少執行期間的工作量。

其他費用

JavaScript 可能會對網頁效能產生其他影響:

  • 記憶體。由於垃圾收集器的緣故,網頁可能會出現卡頓或經常暫停。瀏覽器收回記憶體時,JS 就會暫停執行,因此瀏覽器經常收集垃圾資料,就會比系統更常暫停執行程序。避免記憶體流失和頻繁的 GCS 暫停,以免頁面卡頓。
  • 在執行階段,長時間執行的 JavaScript 會封鎖導致頁面無回應的主執行緒。將工作劃分為較小的部分 (使用 requestAnimationFrame()requestIdleCallback() 安排排程) 可以盡量減少回應速度問題,進而改善與下一個繪製內容的互動 (INP)

降低 JavaScript 放送成本的模式

當您嘗試加快 JavaScript 的剖析/編譯和網路傳輸時間時,有些模式可以派上用場,例如路徑型區塊或 PRPL

PRPL

PRPL (推送、轉譯、預先快取、延遲載入) 是一種模式,可透過積極的程式碼分割和快取,針對互動性進行最佳化:

ALT_TEXT_HERE

我們以視覺化的方式說明這項工具的影響。

我們會使用 V8 的執行階段通話統計資料分析熱門行動版網站和漸進式網頁應用程式的載入時間。如您所見,剖析時間 (橘線) 是其中許多網站花時間的重要部分:

ALT_TEXT_HERE

使用 PRPL 的 Wego 網站管理了一個縮短路徑的剖析時間,加快互動速度。上述許多網站都採用程式碼分割和效能預算,嘗試降低 JS 費用。

漸進式啟動

許多網站會提高內容能見度,而代價高昂。擁有大型 JavaScript 套件時,為了快速進行首次繪製,開發人員有時會採用伺服器端轉譯,之後要「升級」以在最終擷取 JavaScript 時附加事件處理常式。

請務必小心,這類資源有自己的成本。1) 一般而言,會傳送「更大」的 HTML 回應來增加我們的互動性,2) 可能會讓使用者感到困惑,這樣在 JavaScript 處理完成之前,一半的使用者無法提供互動體驗。

漸進式啟動可能是更好的做法,傳送功能最小化的網頁 (僅包含目前路線所需的 HTML/JS/CSS)。隨著資源增加,應用程式可以延遲載入並解鎖更多功能。

ALT_TEXT_HERE
Paul Lewis 的「漸進式啟動

載入程式碼與畫面顯示內容成正比,這就是神聖的。PRPL 和漸進式啟動模式等模式可協助達成此目標。

結論

傳輸大小對於低端網路至關重要。剖析時間對於受 CPU 限制的裝置來說非常重要。想壓低碳排量嗎?

團隊發現,採用嚴格的效能預算,有助於降低 JavaScript 傳輸及剖析/編譯時間。請參見 Alex Russell 的「負擔得起嗎?:「實際網頁效能預算」一文。

ALT_TEXT_HERE
如果我們需要瞭解 JS 為應用程式邏輯而做出的架構決策,會有幫助。

如果是針對行動裝置建構網站,請盡量使用具代表性的硬體來開發,同時維持低 JavaScript 剖析/編譯時間,並採用效能預算,確保團隊密切留意 JavaScript 費用。

瞭解詳情