首頁 > web前端 > js教程 > JavaScript性能優化提示:概述

JavaScript性能優化提示:概述

William Shakespeare
發布: 2025-02-15 09:17:11
原創
538 人瀏覽過

JavaScript Performance Optimization Tips: An Overview

本文探討了在瞬息萬變的 JavaScript 生態系統中,如何優化 JavaScript 性能的諸多方面。我們將遵循“工具而非規則”的原則,盡量避免使用過多的 JavaScript 行話。由於篇幅有限,無法涵蓋 JavaScript 性能優化的所有方面,請務必閱讀參考鏈接並自行深入研究。

在深入探討細節之前,讓我們先從更宏觀的角度來理解這個問題:什麼是高性能 JavaScript,它如何與更廣泛的 Web 性能指標相適應?

關鍵要點

  • JavaScript 性能消耗較大,應謹慎使用。務必在低端設備和真實網絡環境下測試網站性能。網站應快速加載,並儘快實現交互。
  • 減少 JavaScript 代碼量並儘可能加快加載速度至關重要。代碼應始終進行壓縮,拆分為更小、更易於管理的包,並在可能的情況下異步加載。
  • 在服務器端,確保啟用 HTTP/2 以實現更快的並行傳輸,並使用 gzip/Brotli 壓縮來大幅減少 JavaScript 傳輸大小。
  • npm 和框架中隔離組件的便利性帶來一個缺點:開發人員解決問題的首要方法變成了添加更多 JavaScript 代碼。嘗試減少 JavaScript 代碼量,並考慮使用更輕量級的框架,例如 Preact 或 HyperHTML。
  • JavaScript 解析時間與包大小成正比。 JavaScript 代碼量越少越好。您使用的每個 JavaScript 框架都是另一層抽象,會增加包大小並降低代碼速度。

背景設置

首先,我們需要明確一點:如果您只在台式機上進行測試,那麼您就排除了超過 50% 的用戶。

JavaScript Performance Optimization Tips: An Overview

隨著新興市場用戶主要通過價格低於 100 美元的 Android 設備訪問互聯網,這一趨勢只會繼續發展。台式機作為訪問互聯網的主要設備的時代已經結束,下一批十億互聯網用戶將主要通過移動設備訪問您的網站。

在 Chrome DevTools 的設備模式下進行測試並不能替代在真實設備上進行測試。使用 CPU 和網絡限流有所幫助,但它本質上是不同的。請在真實設備上進行測試。

即使您正在在真實的移動設備上進行測試,您可能也在使用您全新的 600 美元旗艦手機進行測試。問題是,這並不是您的用戶所擁有的設備。中位數設備類似於 Moto G1——這是一款內存小於 1GB、CPU 和 GPU 非常弱的設備。

讓我們看看它在解析平均 JS 包時的表現如何。

JavaScript Performance Optimization Tips: An Overview Addy Osmani:JS 解析和評估的平均時間。

糟糕。雖然此圖像僅涵蓋 JS 的解析和編譯時間(稍後將詳細介紹),而不是整體性能,但它與整體性能密切相關,可以作為整體 JS 性能的指標。

引用 Bruce Lawson 的話:“這是萬維網,而不是富裕的西方網絡”。因此,您的 Web 性能目標是速度比您的 MacBook 或 iPhone 慢約 25 倍的設備。好好想想這一點。但情況更糟。讓我們看看我們的實際目標是什麼。

什麼是高性能 JS 代碼?

既然我們知道了目標平台,我們就可以回答下一個問題:什麼是高性能 JS 代碼?

雖然沒有絕對的分類來定義高性能代碼,但我們確實有一個以用戶為中心的性能模型可以用作參考:RAIL 模型。

JavaScript Performance Optimization Tips: An Overview Sam Saccone:性能規劃:PRPL

響應 (Respond)

如果您的應用在 100 毫秒內響應用戶操作,用戶會認為響應是即時的。這適用於可點擊的元素,但不適用於滾動或拖動。

動畫 (Animate)

在 60Hz 顯示器上,我們希望在動畫和滾動時達到每秒 60 幀的恆定幀率。這意味著每幀大約有 16 毫秒的時間。在這 16 毫秒的預算中,您實際上只有 8-10 毫秒的時間來完成所有工作,其餘時間被瀏覽器內部機制和其他差異佔用。

空閒工作 (Idle work)

如果您有一個昂貴且持續運行的任務,請確保將其分割成更小的塊,以便主線程能夠響應用戶輸入。您不應該有一個任務會將用戶輸入延遲超過 50 毫秒。

加載 (Load)

您應該將頁面加載時間控制在 1000 毫秒以內。超過這個時間,您的用戶就會開始感到不耐煩。對於頁面具有交互性而言,這是一個相當難以實現的目標,而不僅僅是將其繪製在屏幕上並可滾動。實際上,時間更短:

JavaScript Performance Optimization Tips: An Overview Fast By Default:現代加載最佳實踐(2017 年 Chrome Dev 峰會)

實際上,目標是 5 秒的交互時間。這是 Chrome 在其 Lighthouse 審核中使用的指標。

既然我們知道了指標,讓我們來看一些統計數據:

  • 如果移動網站加載時間超過三秒鐘,則 53% 的訪問會被放棄。
  • 每兩個人中就有一人希望頁面在兩秒鐘內加載完畢。
  • 77% 的移動網站在 3G 網絡上的加載時間超過 10 秒。
  • 在 3G 網絡上,移動網站的平均加載時間為 19 秒。

以及 Addy Osmani 提供的更多信息:

  • 應用在台式機(使用電纜)上需要 8 秒才能實現交互,在移動設備(Moto G4 通過 3G)上需要 16 秒。
  • 中位數情況下,開發人員為其頁面提供了 410KB 的 gzip 壓縮 JS 代碼。

感覺夠沮喪了嗎?很好。讓我們開始工作,修復 Web。 ✊

上下文至關重要

您可能已經註意到,主要瓶頸是加載網站所需的時間。具體來說,是 JavaScript 下載、解析、編譯和執行時間。除了加載更少的 JavaScript 代碼並更智能地加載之外,別無他法。

但是,除了啟動網站之外,您的代碼實際執行的工作呢?那裡一定有一些性能提升,對吧?

在深入優化代碼之前,請考慮您正在構建的內容。您是在構建框架還是 VDOM 庫?您的代碼是否需要每秒執行數千次操作?您是否正在為處理用戶輸入和/或動畫編寫一個時間關鍵型庫?如果不是,您可能需要將時間和精力轉移到更有效的地方。

這並不是說編寫高性能代碼不重要,而是它通常在整體情況中幾乎沒有影響,尤其是在談論微優化時。因此,在您開始在 Stack Overflow 上就 .map 與 .forEach 與 for 循環進行爭論,並比較 JSperf.com 上的結果之前,請確保您看到了森林,而不僅僅是樹木。在紙面上,50k ops/s 可能聽起來比 1k ops/s 好 50 倍,但在大多數情況下,它不會產生任何區別。

解析、編譯和執行

從根本上說,大多數非高性能 JS 的問題不是運行代碼本身,而是代碼開始執行之前必須執行的所有步驟。

我們在這裡談論的是抽象級別。您計算機中的 CPU 運行機器碼。您計算機上運行的大部分代碼都採用編譯後的二進制格式。 (考慮到當今所有的Electron 應用程序,我說的是代碼而不是程序。)這意味著,除了所有操作系統級別的抽象之外,它都在您的硬件上原生運行,無需任何準備工作。

JavaScript 沒有預編譯。它(通過相對較慢的網絡)以可讀代碼的形式到達您的瀏覽器中,就所有意圖和目的而言,它是您的 JS 程序的“操作系統”。

該代碼首先需要進行解析——也就是說,讀取並轉換為可供計算機索引的結構,以便用於編譯。然後將其編譯成字節碼,最後編譯成機器碼,然後才能由您的設備/瀏覽器執行。

另一個非常重要的事情需要提到的是,JavaScript 是單線程的,並且在瀏覽器的主線程上運行。這意味著一次只能運行一個進程。如果您的 DevTools 性能時間軸充滿了黃色峰值,使您的 CPU 運行到 100%,您將遇到長時間/丟幀、卡頓滾動以及其他各種討厭的事情。

JavaScript Performance Optimization Tips: An Overview Paul Lewis:當一切都很重要時,什麼都不重要! 。

因此,在您的 JS 開始工作之前,需要完成所有這些工作。在 Chrome 的 V8 引擎中,解析和編譯最多佔 JS 執行總時間的 50%。

JavaScript Performance Optimization Tips: An Overview Addy Osmani:JavaScript 啟動性能。

您應該從本節中記住兩件事:

  1. 雖然不一定是線性的,但 JS 解析時間與包大小成正比。 JS 代碼量越少越好。
  2. 您使用的每個 JS 框架(React、Vue、Angular、Preact……)都是另一層抽象(除非它是預編譯的,例如 Svelte)。它不僅會增加包大小,還會降低代碼速度,因為您不是直接與瀏覽器對話。

有一些方法可以減輕這種情況,例如使用服務工作線程在後台和另一個線程上執行作業,使用 asm.js 編寫更容易編譯成機器指令的代碼,但這又是另一個主題。

但是,您可以做的是避免為所有內容都使用 JS 動畫框架,並了解觸發繪製和佈局的內容。僅當絕對無法使用常規 CSS 過渡和動畫來實現動畫時,才使用這些庫。

即使它們可能使用 CSS 過渡、合成屬性和 requestAnimationFrame(),它們仍在 JS 中、在主線程上運行。它們基本上只是每 16 毫秒都用內聯樣式來敲打您的 DOM,因為它們幾乎沒有其他事情可做。為了保持動畫流暢,您需要確保所有 JS 都能在每幀 8 毫秒內完成執行。

另一方面,CSS 動畫和過渡在主線程之外運行——如果高效地實現,則在 GPU 上運行,而不會導致重新佈局/重新繪製。

考慮到大多數動畫是在加載或用戶交互期間運行的,這可以為您的 Web 應用提供急需的喘息空間。

Web Animations API 是一個即將推出的功能集,它允許您在主線程之外執行高性能 JS 動畫,但目前,請堅持使用 CSS 過渡和 FLIP 等技術。

包大小至關重要

如今,一切都是關於包的。 Bower 和在結束

以上是JavaScript性能優化提示:概述的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板