JavaScript 啟動最佳化

由於我們建構的網站更仰賴 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 開發人員工具中,剖析和編譯是「效能」面板中黃色「指令碼」時間的一部分。

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 和圖片位元組的成本差異很大。圖片通常不會在解碼和算繪期間阻斷主執行緒,也不會阻止介面進行互動。不過,由於剖析、編譯和執行的成本,JavaScript 可能會延遲互動性。

當我們談到剖析和編譯速度緩慢時,背景資訊就很重要,因為我們指的是一般的手機。一般使用者的手機可能搭載速度較慢的 CPU 和 GPU、沒有 L2/L3 快取,甚至可能有記憶體限制。

網路功能和裝置功能不一定相符。使用者即使擁有絕佳的光纖連線,也不一定擁有最佳 CPU 來剖析及評估傳送至裝置的 JavaScript。反之亦然,如果網路連線品質不佳,但 CPU 速度極快,— LinkedIn 的 Kristofer Baxter

下方是低階和高階硬體在剖析約 1 MB 的解壓縮 (簡單) JavaScript 時的成本。在解析/編譯程式碼方面,市面上速度最快的手機與一般手機之間的差異為 2 至 5 倍

ALT_TEXT_HERE
這張圖表強調了 1 MB JavaScript 套件的剖析時間,此套件經過壓縮後約為 250 KB,並在不同類別的桌機和行動裝置上執行。在分析剖析成本時,請考量解壓縮後的數字,例如解壓縮後的 JS 檔案大小約為 250 KB,解壓縮後的程式碼約為 1 MB。

那麼,實際網站 (例如 CNN.com) 呢?

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

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 秒來剖析及編譯 JavaScript。

ALT_TEXT_HERE

考量擷取和處理 JS 和其他資源所需的時間,您可能會發現,使用者必須等待一段時間,才能感覺到網頁已可使用。我們絕對可以做得更好。

從網頁中移除非必要的 JavaScript,可以縮短傳輸時間、減少 CPU 密集的剖析和編譯作業,並降低潛在的記憶體開銷。這也有助於加快網頁的互動速度。

執行時間

除了剖析和編譯之外,JavaScript 執行作業 (在剖析/編譯後執行程式碼) 是必須在主執行緒上執行的作業之一。執行時間過長也會延長使用者與網站互動的時間。

ALT_TEXT_HERE

如果指令碼的執行時間超過 50 毫秒,則下載、編譯及執行 JS 所需的時間會全部延遲互動時間 — Alex Russell

為解決這個問題,JavaScript 會以小型區塊的形式運作,避免鎖定主執行緒。探索是否可以減少執行期間的工作量。

其他費用

JavaScript 還可能以其他方式影響網頁效能:

  • 記憶體。由於 GC (垃圾收集),頁面可能會經常出現卡頓或暫停的情形。當瀏覽器回收記憶體時,JS 執行作業會暫停,因此經常收集垃圾的瀏覽器可能會比我們預期更頻繁地暫停執行作業。避免記憶體耗損和頻繁的 GC 暫停,確保網頁不會出現卡頓現象。
  • 在執行階段中,長時間執行的 JavaScript 可能會封鎖主執行緒,導致頁面沒有回應。將工作細分為較小的部分 (使用 requestAnimationFrame()requestIdleCallback() 進行排程),可盡量減少回應速度問題,進而改善Interaction to Next Paint (INP)

減少 JavaScript 提交成本的模式

若您想讓 JavaScript 的剖析/編譯和網路傳輸時間保持緩慢,可以使用路徑為基礎的區塊化或 PRPL 等模式。

PRPL

PRPL (Push、Render、Pre-cache、Lazy-load) 是一種模式,可透過積極的程式碼分割和快取,為互動性進行最佳化:

ALT_TEXT_HERE

讓我們來看看這項功能可能帶來的影響。

我們使用 V8 的執行階段呼叫統計資料,分析熱門行動網站和漸進式網頁應用程式的載入時間。如您所見,許多網站的解析時間 (以橘色標示) 都占了相當大的比例:

ALT_TEXT_HERE

Wego 是使用 PRPL 的網站,他們成功維持路徑的解析時間,讓路徑能夠快速完成互動。上述許多其他網站都採用了程式碼分割和效能預算,以便降低 JS 成本。

漸進式啟動

許多網站為了提升內容曝光率,犧牲了互動性。為了在有大型 JavaScript 套件時獲得快速的第一筆繪製,開發人員有時會採用伺服器端轉譯,然後在最終擷取 JavaScript 時「升級」附加事件處理常式。

請注意,這項服務本身會產生費用。1) 您通常會傳送較大的 HTML 回應,這可能會影響互動性;2) 使用者可能會處於奇異的谷中,在 JavaScript 完成處理前,一半的體驗無法實際互動。

漸進式 Bootstrapping 可能會是更好的做法。傳送最基本功能的網頁 (僅包含目前路徑所需的 HTML/JS/CSS)。隨著更多資源到達,應用程式就能以延遲載入的方式取得更多功能。

ALT_TEXT_HERE
漸進式 Bootstrapping (Paul Lewis 著)

載入程式碼的速度與檢視畫面內容成正比,是聖杯。PRPL 和漸進式 Bootstrapping 模式可協助您達成這項目標。

結論

傳輸大小對低階網路至關重要。對於 CPU 受限裝置而言,解析時間十分重要。請務必降低這些數值。

團隊發現,採用嚴格的效能預算可有效降低 JavaScript 傳輸和剖析/編譯時間。請參閱艾力克斯羅素的「Can You Afford It?「實際網站效能預算」一文,瞭解行動版預算的相關指南。

ALT_TEXT_HERE
建議您考量我們做出的架構決策可為應用程式邏輯保留多少 JS「空間」。

如果您要建構以行動裝置為目標的網站,請盡可能使用代表性硬體進行開發,縮短 JavaScript 剖析/編譯時間,並採用效能預算,確保團隊能隨時掌握 JavaScript 成本。

瞭解詳情