JavaScript 性能優化技巧分享

 
 
JavaScript 做爲當前最爲常見的直譯式腳本語言,已經普遍應用於 Web 應用開發中。爲了提升Web應用的性能,從 JavaScript 的性能優化方向入手,會是一個很好的選擇。
本文從加載、上下文、解析、編譯、執行和捆綁等多個方面來說解 JavaScript 的性能優化技巧,以便讓更多的前端開發人員掌握這方面知識。

什麼是高性能的 JavaScript 代碼?
儘管目前沒有高性能代碼的絕對定義,但卻存在一個以用戶爲中心的性能模型,能夠用做參考: RAIL模型
 
  • 響應
若是你的應用程序能在100毫秒內響應用戶的操做,那麼用戶會認爲該響應爲即時的。這適用於可點擊的元素,不適用於滾動或拖動操做。
  • 動畫
在60Hz的顯示器上,咱們但願動畫和滾動時每秒有60幀,這種狀況下每幀大約爲16ms。在這16ms的時間內,實際上只有8-10ms來完成全部工做,其他時間則由瀏覽器的內部和其它差別佔據。
  • 空閒工做
若是你有一個耗時好久,須要持續運行的任務時,請確保把它分紅很小的塊,以便容許主線程對用戶的輸入操做作出反應。不該該出現一個任務延遲超過50ms的用戶輸入。
  • 加載
頁面加載應該在1000毫秒內完成。在移動設備上,這是一個很難達到的目標,由於它涉及到頁面的互動,而不只僅是在屏幕上渲染和滾動。
 
  • 若是移動網站的加載時間超過三秒,則會有53%的用戶放棄訪問
  • 50%的用戶但願在不到2秒的時間內完成頁面加載
  • 77%的移動網站須要10秒以上的時間來加載3G網絡
  • 19秒是3G網絡上移動站點的平均加載時間
代碼內容
你可能已經注意到了,最大的瓶頸是加載網站所需的時間。具體來講就是 JavaScript 的下載、解析、編譯和執行時間。除了加載更少的 JavaScript 文件或者加載的更加靈活之外,看起來沒有其它辦法。
除去啓動網站以外,JavaScript 代碼又是如何實際工做的呢?
在進行代碼優化以前,請考慮你當前正在構建的內容。你正在創建的是一個框架仍是一個 VDOM 庫?你的代碼是否須要每秒執行數千次操做?你是否正在作一個對時間要求較爲嚴格的庫來處理用戶輸入和/或動畫?若是沒有,你須要把時間和精力轉移到更有影響力的地方。
編寫高性能代碼並非那麼重要,由於對於宏觀計劃一般沒有什麼影響。50k ops/s 聽起來好於 1k ops/s,但在大多數狀況下總體時間並不會有所改變。
圖片 
解析、編譯和執行
從根本上說,大多數 JavaScript 的性能問題,並不在於運行代碼自己,而是在代碼開始執行以前必須採起的一系列步驟。
咱們在這裏討論抽象層次的問題。計算機上運行的大多數代碼都是編譯後的二進制格式。意思是說,除了全部的操做系統級別的抽象外,代碼均可以在硬件上本地運行,不須要準備工做。
JavaScript 代碼不是預編譯的,它在瀏覽器上是可讀的。
JavaScript 代碼首先會被解析,也就是讀取並轉換成可用於編譯的計算機索引的結構,而後再被編譯成字節碼,最後被編譯成機器碼,用於設備/瀏覽器執行。
另外一個很是重要的方面是:JavaScript 是單線程的,而且在瀏覽器的主線程上運行。這意味着一次只能運行一個進程。若是你的 DevTools 性能時間線充滿黃色峯值,同時 CPU 佔用率達到100%,則將出現丟幀的狀況。這是滾動操做常出現的,也是很討厭的一種狀況。
 
在 JavaScript 代碼運行以前,須要完成全部的這些解析、編譯和執行工做。在 ChromeV8 引擎中,解析和編譯佔 JavaScript 執行總時間的50%左右。
 
因此在這部分中,應該瞭解兩件事情:
1. 雖然 JavaScript 解析的時間長度和包的大小不是徹底線性的,可是須要處理的 JavaScript 越少,則所花時間越少。
2. 你使用的每個 JavaScript 框架(React,Vue,Angular,Preact …)都是另外一個抽象層次(除非它是一個預編譯的)。這不只會增長你的包的大小,並且會讓你的代碼變慢,由於你不是直接與瀏覽器通訊的。
有些方法能夠緩解這種狀況,好比使用 service workers 在後臺的另外一個線程中執行部分工做,或者使用 asm.js 編寫更容易編譯機器指令的代碼。
咱們所能作的,就是避免使用 JavaScript 動畫庫。只有在使用常規的 CSS 轉換和動畫徹底沒法實現時,纔去使用這些庫。
即便這些 JavaScript 動畫庫使用 CSS 轉換,合成屬性和 requestAnimationFrame( ),可是它們仍然運行在 JavaScript 的主線程上。基本上這些庫會使用內聯樣式每16ms訪問一次 DOM。你須要確保全部的 JavaScript 都在每幀8ms之內完成,才能保持動畫的平滑性。
另外一方面,CSS 動畫和轉換會在主線程中運行,若是可以高效執行,則能避免從新佈局/重排的狀況出現。
考慮到大多數動畫都在加載或用戶交互的過程當中運行,這能夠爲你的 web 應用程序提供很是重要的調整空間。
web Animations API 是一個即將到來的功能集,它可以脫離主線程執行高性能的 JavaScript 動畫。但就目前而言,還須要繼續使用 CSS 轉換等技術。

在學習的小夥伴,能夠加羣434623999學習,領取資料
相關文章
相關標籤/搜索