[翻譯]JavaScript的成本

當咱們創建嚴重依賴於JavaScript的網站時,咱們不老是很容易看到咱們發送的內容所付出的代價。在這篇文章中,若是你但願你的網站在移動設備上可以快速加載和互動,我將介紹爲何一些規則能夠幫助你。javascript

tl;dr:較少的代碼=較少的解析/編譯+較少的傳輸+較少的解壓縮html

網絡

當大多數開發人員考慮JavaScript的成本時,他們會考慮下載和執行成本。經過線路發送更多字節的JavaScript須要的時間越長,用戶的鏈接也就越慢。java

這多是一個問題,即便在發達國家,由於用戶有效的網絡鏈接類型可能實際上並非3G,4G或WiFi。你可能在咖啡店使用Wifi,但鏈接到的是2G的蜂窩熱點。webpack

您能夠經過如下方式下降 JavaScript的網絡傳輸成本:git

  • 只發送用戶須要的代碼。代碼拆分這時候就有用武之地了。github

  • 壓縮代碼(ES515的 Uglify, ES2015的 babel- minify或uglify -es)web

  • 高度壓縮(使用Brotli〜q11,Zopfli或gzip的)。Brotli的壓縮比超過Gzip。它讓CertSimple節省了17%的JS壓縮字節大小,LinkedIn節省了 4%的加載時間。瀏覽器

  • 刪除未使用的代碼。經過DevTools代碼覆蓋來肯定。對於剝離的代碼,能夠查看tree shaking閉包編譯器的高級優化和微調庫插件如lodash-babel-plugin插件或WebPack的ContextReplacementPlugin如Moment.js庫。使用babel-preset-env和browserlist來避免現代瀏覽器中已經存在的轉譯功能。高級開發人員可能會發現仔細分析Webpack捆綁包有助於識別修剪不須要的依賴關係。緩存

  • 使用HTTP緩存以儘可能減小網絡跳轉。肯定腳本的最佳生命週期(max-age)和提供令牌驗證(ETag)以免傳輸沒有變動的字節。Service Worker緩存可使您的應用程序網絡具備彈性,讓您能夠快速訪問V8的代碼緩存等功能。瞭解有關文件名哈希的長期緩存。 服務器

    如何減小發送給用戶的JavaScript最佳實踐

解析/編譯

一旦JS下載完畢,JavaScript最大的一個成本就是JS引擎解析/編譯這段代碼的時間。在Chrome DevTools中,解析和編譯是「性能」面板中黃色「腳本」時間的一部分。

Bottom-Up/Call Tree容許查看確切的解析/編譯時序:

Chrome DevTools「性能」面板>自下而上。經過啓用V8的運行時調用統計,咱們能夠看到分析和編譯階段花費的時間

可是,爲何這會有問題呢?

花費很長時間解析/編譯代碼會嚴重延遲用戶與網站互動的時間。發送的JavaScript越多,在網站交互以前解析和編譯的時間就越長。

一樣多的字節,瀏覽器處理JavaScript要比同等大小的圖像或Web字體開銷更大。 - Tom Dale

與JavaScript相比,在處理等效大小的圖片時(涉及到大量的圖片仍然須要解碼!),涉及到大量的開銷,可是在通常的移動設備上,JS更有可能對頁面的交互性產生負面影響。

JavaScript和圖像字節的開銷有很大的不一樣。圖像一般不會阻塞主線程,也不會阻止接口在解碼和柵格化時進行的交互。然而JS因爲解析,編譯和執行的成本會延遲交互性。

當咱們談論解析和編譯變慢的時候,上下文很重要 - 咱們在這裏談論的普通手機。指的是大部分用戶使用的CPU和GPU速度較慢的手機,無L2 / L3緩存,甚至可能內存很小

網絡功能和設備功能並不老是相匹配。使用光纖鏈接的用戶不必定有最好的CPU來解析和執行發送到他們的設備的JavaScript。反過來也是如此。一個糟糕的網絡鏈接,但卻有一個快速的CPU。 - Kristofer Baxter,LinkedIn

JavaScript啓動性能中,我注意到在低端和高端硬件上解析大約1MB已經被解壓的(簡單)JavaScript的開銷。在市場上最快的手機和普通手機之間解析/編譯代碼的時間有2-5倍的差別

在不一樣類別的桌面和移動設備上解析一個1MB的JavaScript包(約有250KB 被gzip壓縮了)的解析時間。在查看解析的開銷時,解壓後的數據要考慮到大約有250KB 被gzip壓縮的空間會被釋放出來當解壓縮大約1MB的代碼的時候

那麼現實世界的網站如何呢,如CNN.com 在高端的iPhone 8上,解析/編譯CNN的JS須要花費大約4秒,而普通手機(Moto G4)則只須要13秒。這能夠顯著影響用戶與本網站徹底交互的速度。

蘋果的A11仿生芯片和很是普通的Android硬件中的Snapdragon 617的解析時間性能比較。

這突出了普通硬件(如Moto G4)測試的重要性,而不只僅是口袋裏的手機。可是,使用環境很重要:優化您的用戶擁有的設備和網絡條件。

分析能夠深刻了解您的真實用戶訪問您的網站的移動設備類別。這能夠提供機會來了解他們正在使用的真正的CPU / GPU的限制。

咱們是否真的發送了太多的JavaScript?錯誤,這頗有可能:)

使用HTTP Archive(最高大約50萬個站點)來分析移動設備上JavaScript的狀態,咱們能夠看到,50%的站點須要14秒才能得到交互。僅僅只是解析和編譯JS,這些網站就花費長達4秒。

在獲取和處理JS和其餘資源所花費的時間中,由於感受網頁已經可使用,用戶可能會等待一段時間,這也許並不奇怪。但咱們必定能夠在這裏作得更好。

從網頁中刪除不重要的JavaScript能夠減小傳輸時間,CPU密集型解析和編譯以及潛在的內存開銷。這也有助於讓您的網頁更快地交互。

執行時間

這不只僅是解析和編譯,並且可能會帶來額外的開銷。JavaScript執行(一次解析/編譯運行代碼)是在主線程上發生的操做之一。很長的執行時間也能夠推出用戶能夠與網站互動的時間。

若是腳本執行時間超過50ms,則交互時間會被下載,編譯和執行JS所花時間延遲了 - Alex Russell

爲了解決這個問題,JavaScript受益於small chunks,以免鎖定主線程。探索是否能夠減小執行過程當中正在進行的工做量。

減小JavaScript發送開銷的模式

當你試圖保持JavaScript的解析/編譯和網絡傳輸時間很慢時,有一些模式能夠幫助像基於路由的分塊(route-based chunking)或PRPL

PRPL是一種經過代碼分割和緩存來優化交互性的模式:

讓咱們看看它能夠產生的影響。 咱們使用V8的運行時調用統計來分析流行移動網站和Progressive Web Apps的加載時間。正如咱們所看到的,解析時間(以橙色顯示)是許多這些站點花費時間的比較大的部分:

Wego是一個使用PRPL的網站,它設法保持較低的路由解析時間,可以很是迅速地進行互動。上面的許多其餘站點都採用代碼分解和性能預算來下降JS的開銷。

其餘開銷

JavaScript能夠經過其餘方式影響頁面性能:

  • 內存。因爲GC(垃圾收集),頁面可能常常會出現卡頓或暫停。當瀏覽器回收內存時,JS執行被暫停,因此常常進行垃圾收集的瀏覽器能夠比咱們想要的更頻繁地暫停執行。避免內存泄漏和頻繁的gc暫停,以保持頁面流暢。

  • 在運行時,長時間運行的JavaScript能夠阻止主線程致使無響應的頁面。將工做分紅更小的部分(使用requestAnimationFrame()或有計劃的使用requestIdleCallback())能夠最大限度地減小響應性問題。

漸進式引導

許多網站將內容可視性做爲交互性的代價來優化。爲了在有大的JavaScript包時得到一個快速的首頁,開發者有時會使用服務器端渲染;而後在JavaScript最終獲取時將其「升級」以附加事件處理程序。

當心 - 這有它本身的開銷。1)這一般會發送一個更大的 HTML響應,這會延遲交互性,2)這會把用戶留在一個離奇的山谷中,其中有一半的實際功能是沒有辦法交互的,直到JavaScript運行完成。

漸進式引導多是一個更好的方法。發送一個最小功能的頁面(由當前路由所需的HTML / JS / CSS組成)。隨着更多的資源到達,該應用程序能夠延遲加載和解鎖更多的功能。

Paul Lewis的 漸進式引導視覺

根據所看到的加載代碼是聖盃。PRPL和漸進引導是能夠幫助實現這一點的模式。

結論

傳輸大小對低端網絡相當重要。解析時間對於CPU受限的設備很重要。保持這二者的抵開銷。

團隊發現成功採用嚴格的性能預算來保持JavaScript傳輸和解析/編譯時間較短。請參閱Alex Russell的「 您能夠承受嗎?:真實世界的Web性能預算 」,以獲取關於移動預算的指導。

考慮一下咱們製做的架構決策能夠爲應用程序邏輯留下多少JS「空間」。

若是您正在構建針對移動設備的網站,請儘量在表明性硬件上開發,保持較低的JavaScript分析/編譯時間,並採用性能預算來確保您的團隊可以關注其JavaScript成本。

原文地址

相關文章
相關標籤/搜索