隨著我們建立網站越來越依賴 JavaScript 來建構網站,我們有時也會為了傳送內容而付出代價,我們有時難以察覺。如想瞭解如何在行動裝置上快速載入網站並方便互動,請參閱這份重點。傳送較少 JavaScript 可以減少網路傳輸的時間、降低解壓縮程式碼所花費的時間,以及縮短剖析和編譯這個 JavaScript 的時間。
網路
多數開發人員思考 JavaScript 的費用時,會考量下載和執行費用。透過線傳送更多的 JavaScript 位元組,使用者的連線速度會越慢。
這可能是問題,因為使用者有效的網路連線類型不是 3G、4G 或 Wi-Fi。您可以用咖啡店 Wi-Fi,但連線至有 2G 速度的行動網路無線基地台。
您可以透過以下途徑降低 JavaScript 的網路傳輸費用:
- 只傳送使用者需要的程式碼。
- 壓縮
- 請使用 UglifyJS 來壓縮 ES5 程式碼。
- 使用 babel-minify 或 uglify-es 壓縮 ES2015 以上版本。
- 壓縮
- 移除未使用的程式碼。
- 使用開發人員工具的程式碼涵蓋率,找出可移除或延遲載入的程式碼。
- 使用 babel-preset-env 和瀏覽器清單,避免轉譯新世代瀏覽器中的既有功能。進階開發人員可能會發現謹慎的 Webpack 套件分析,以協助您找出修剪不需要的依附元件的機會。
- 如要去除程式碼,請參閱樹木搖動、Closure Compiler 的進階最佳化和程式庫剪輯外掛程式,例如 lodash-babel-plugin 或 webpack 的 ContextReplacementPlugin,針對 Moment.js 等程式庫。
- 快取程式碼以盡量減少網路行程。
剖析/編譯
下載之後,JavaScript 引擎的「最主要」費用是 JS 引擎剖析/編譯程式碼所需的時間。在 Chrome 開發人員工具中,剖析和編譯是在「Performance」(效能) 面板中顯示黃色的「指令碼處理」時間。
「Bottom-Up」和「Call Tree」分頁會顯示詳細的剖析/編譯時間:
但這很重要嗎?
花費較長時間剖析/編譯程式碼,可能會嚴重延遲使用者與網站互動的時間。傳送的 JavaScript 越多,網站在互動式網站前剖析和編譯所需的時間就越長。
位元組大小的 JavaScript 比瀏覽器大小相同的圖片或網路字型更為昂貴 — Tom Dale
與 JavaScript 相比,在處理大小相等的圖片時需要支付大量費用 (因此圖片仍須解碼!),但以一般行動硬體來說,JS 較有可能對網頁的互動產生負面影響。
這裡所說的剖析和編譯速度緩慢;背景資訊很重要,我們今天要討論的是「一般」手機。一般使用者可以擁有搭載緩慢 CPU 和 GPU 的手機、沒有 L2/L3 快取,甚至記憶體可能有限。
網路功能和裝置功能不一定會相同。如果使用者擁有出色的 Fiber 連線,不見得最好的 CPU 來剖析和評估傳送至其裝置的 JavaScript。情況在逆境中也是如此:網路連線不穩,而是快速 CPU。— Kristofer Baxter,LinkedIn
下方是低階與高階硬體剖析約 1 MB 解壓縮 (簡易) JavaScript 的費用。在市面上最快速的手機和一般手機之間,剖析/編譯程式碼所需的時間是 2 到 5 倍。
像 CNN.com 這樣的真實網站會怎麼樣?
在高階 iPhone 8 上,相較於一般手機 (Moto G4) 大約 13 秒,只需大約 4 秒剖析/編譯 CNN 的 JS。這可能會大幅影響使用者能與這個網站完整互動的速度。
這突顯出在「一般」硬體 (例如 Moto G4) 上進行測試的重要性,而不是只放在口袋中的手機。不過情境很重要:根據使用者的裝置和網路條件進行最佳化。
我們確實傳送了過多的 JavaScript 嗎?呃,可能 :)
現在,我們可以透過 HTTP 封存檔 (前 50 萬個網站) 分析行動裝置上的 JavaScript 狀態,可以看到有 50% 的網站需要超過 14 秒才能產生互動。這些網站花最多 4 秒的時間剖析及編譯 JS。
考慮擷取和處理 JS 和其他資源所需的時間,可能令人感到意外的是,使用者在感覺頁面可供使用之前可能會離開一段時間。我們確實可以做得更好。
從網頁中移除非關鍵的 JavaScript 可縮短傳輸時間、大量剖析 CPU 和編譯,也可能造成記憶體負擔。這也有助於加快網頁互動速度。
執行時間
這不只是剖析及編譯,也可能導致成本增加。JavaScript 執行 (在剖析/編譯後執行程式碼) 是必須在主執行緒上執行的其中一項作業。長時間的執行時間可能也可能導致使用者多快能與您的網站互動。
如果指令碼執行的時間超過 50 毫秒,互動時間會延遲到下載、編譯及執行 JS 所需的「整個」時間 — Alex Russell - Alex Russell
為解決這個問題,JavaScript 的優點在於小型區塊,以免鎖定主執行緒。確認是否可以減少執行期間的工作量。
其他費用
JavaScript 可能會對網頁效能產生其他影響:
- 記憶體。由於垃圾收集器的緣故,網頁可能會出現卡頓或經常暫停。瀏覽器收回記憶體時,JS 就會暫停執行,因此瀏覽器經常收集垃圾資料,就會比系統更常暫停執行程序。避免記憶體流失和頻繁的 GCS 暫停,以免頁面卡頓。
- 在執行階段,長時間執行的 JavaScript 會封鎖導致頁面無回應的主執行緒。將工作劃分為較小的部分 (使用
requestAnimationFrame()
或requestIdleCallback()
安排排程) 可以盡量減少回應速度問題,進而改善與下一個繪製內容的互動 (INP)。
降低 JavaScript 放送成本的模式
當您嘗試加快 JavaScript 的剖析/編譯和網路傳輸時間時,有些模式可以派上用場,例如路徑型區塊或 PRPL。
PRPL
PRPL (推送、轉譯、預先快取、延遲載入) 是一種模式,可透過積極的程式碼分割和快取,針對互動性進行最佳化:
我們以視覺化的方式說明這項工具的影響。
我們會使用 V8 的執行階段通話統計資料分析熱門行動版網站和漸進式網頁應用程式的載入時間。如您所見,剖析時間 (橘線) 是其中許多網站花時間的重要部分:
使用 PRPL 的 Wego 網站管理了一個縮短路徑的剖析時間,加快互動速度。上述許多網站都採用程式碼分割和效能預算,嘗試降低 JS 費用。
漸進式啟動
許多網站會提高內容能見度,而代價高昂。擁有大型 JavaScript 套件時,為了快速進行首次繪製,開發人員有時會採用伺服器端轉譯,之後要「升級」以在最終擷取 JavaScript 時附加事件處理常式。
請務必小心,這類資源有自己的成本。1) 一般而言,會傳送「更大」的 HTML 回應來增加我們的互動性,2) 可能會讓使用者感到困惑,這樣在 JavaScript 處理完成之前,一半的使用者無法提供互動體驗。
漸進式啟動可能是更好的做法,傳送功能最小化的網頁 (僅包含目前路線所需的 HTML/JS/CSS)。隨著資源增加,應用程式可以延遲載入並解鎖更多功能。
載入程式碼與畫面顯示內容成正比,這就是神聖的。PRPL 和漸進式啟動模式等模式可協助達成此目標。
結論
傳輸大小對於低端網路至關重要。剖析時間對於受 CPU 限制的裝置來說非常重要。想壓低碳排量嗎?
團隊發現,採用嚴格的效能預算,有助於降低 JavaScript 傳輸及剖析/編譯時間。請參見 Alex Russell 的「負擔得起嗎?:「實際網頁效能預算」一文。
如果是針對行動裝置建構網站,請盡量使用具代表性的硬體來開發,同時維持低 JavaScript 剖析/編譯時間,並採用效能預算,確保團隊密切留意 JavaScript 費用。
瞭解詳情
- 2017 年 Chrome 開發人員高峰會 - 現代化載入最佳做法
- JavaScript 啟動成效
- 解決網路效能危機 — Nolan Lawson
- 你能負擔一下嗎?實際效能預算 — Alex Russell
- 評估網路架構和程式庫 — Kristofer Baxter
- Cloudflare 對 Brotli 的實驗結果進行壓縮 (請注意,進行品質較高的動態 Brotli 時,初始頁面轉譯作業可能會延遲,因此請審慎評估。建議您改為靜態壓縮)
- PerformanceFutures (效能未來) - Sam Saccone