JavaScript >> Javascript 文檔 >  >> JavaScript

JavaScript 縮小/壓縮和性能

上週,我看到了 Mint.com 的 Matt Snider 的一篇博客文章,他在其中討論瞭如何改進 YUI Compressor 在 JavaScript 代碼上的輸出。這讓我想起了我去年在 Yahoo! 的內部前端工程峰會上發表的題為“使用 YUI Compressor 進行極端 JavaScript 壓縮”的演講。這是我的 YUI 博客文章幫助 YUI 壓縮器的後續文章,我在其中討論了可能幫助或阻礙 YUI 壓縮器的某些模式。在整理演示文稿之前,我繼續深入挖掘,嘗試了幾件事並查看了源代碼結果。請注意,我的目標是找到最好的壓縮沒有 使用 gzip,我認為這些技術過於激進,這就是我使用“極端”這個詞的原因。

JavaScript 性能問題

談論 JavaScript 性能實際上意味著四件事:

  1. 網絡傳輸時間 - 瀏覽器請求資源後接收資源所需的時間。
  2. 資源準備時間 - 準備資源以供使用所需的時間。
  3. 源代碼解析時間——將資源解析為有用的東西所需的時間。
  4. 執行時間——將資源應用到頁面所需的時間。已在此博客上詳細討論過。

第一個問題,網絡傳輸時間,在很長一段時間內一直處於 Web 開發關注的前沿。當然,當大多數用戶通過調製解調器連接到 Internet 時,情況要糟糕得多。這是第一輪 JavaScript 縮小工具誕生的時候,比如 ESC 和 JSMin。由於 JavaScript 文件在沒有任何優化的情況下直接傳輸,因此網絡傳輸時間比必要的要長。這些早期工具試圖通過最小化傳輸的字節數(通常稱為“線重”)來最小化網絡傳輸時間。

隨著這個問題得到更好的理解,瀏覽器開始實現真正的解壓縮解決方案,以便服務器可以使用真正的壓縮,而不僅僅是字節減少,來傳輸資源。兩種常用的壓縮方案是 gzip 和 deflate,所有主流瀏覽器和服務器軟件都支持。通常,這些 gzip 和 deflate 以相同的方式工作。 gzip的基本說明(來源):

使用 gzip 或 deflate 壓縮資源使資源文件在網絡傳輸過程中盡可能小。但是,這樣做會引入第二個興趣點:資源準備時間。

瀏覽器必須在使用壓縮資源之前對其進行解壓縮,我稱之為資源準備時間。您已經節省了網絡傳輸時間,但在瀏覽器可以使用該文件之前引入了一個額外的步驟。值得慶幸的是,在現代瀏覽器中解壓速度很快,並且不會導致任何問題(舊版瀏覽器,如 Internet Explorer 5 在解壓某些文件時會出現問題)。不過,我將其視為過程的一部分。

一旦文件採用瀏覽器可以使用的格式,就必須對其進行解析。瀏覽器的解析時間到底需要多長時間有點神秘,儘管 PageSpeed 對這個過程有一個小小的了解。我推測,隨著給定頁面上 JavaScript 總量的增加,解析時間變得更加重要。這是探索如何優化 YUI Compressor 輸出的基礎,因為我認為未壓縮的文件大小會影響解析時間。我與 YUI Compressor 的創建者 Julien Lecomte 討論了這一點,他不同意,指出在解析期間重要的是源代碼生成的令牌數量而不是字節數。不幸的是,我們都沒有足夠的數據來證明或反駁我們的立場。

批評

雖然看起來很多人都喜歡這個演示文稿,但也有一部分人不喜歡。在這些反對者中,有兩個基本的擔憂:

  1. 按照我的建議進行操作實際上可以增加壓縮文件的大小。
  2. 聲明要使用的變量而不是 true 的文字值的性能開銷 , false , null , 和 undefined .

為了解決第一點,我之前指出 gzip 的工作原理是尋找重複的字符串模式並用指針替換它們。通過將重複的文字值存儲在變量中,您可以有效地移除 gzip 最有效的武器。當然,這會影響文件的整體壓縮大小。

我決定對此進行一個非常簡單的測試並使用 toggle() 功能以演示文稿為例。我在原始版本和優化版本上都運行了 YUI Compressor 和 gzip。

版本 原始 縮小 壓縮包 兩者都有
原創 263 172 161 140
優化 327 127 194 144

如您所見,當在源代碼上同時使用 YUI Compressor 和 gzip 時,原始版本實際上比優化後的版本要小。差異可能很小,但我們也在談論一個相當小的代碼示例。您可以假設使用我演示文稿中的技術優化的代碼在縮小和 gzip 壓縮後會比原始代碼大一小部分。

鑑於這種差異,在演示文稿中應用所有技術的唯一性能原因將是具有盡可能小的縮小但未壓縮的文件大小是否有價值。我關於這個大小影響解析時間的理論必須得到證明(或者可能被證明是錯誤的),但還有其他原因說明縮小文件大小很重要。

雅虎! Exceptional Performance 團隊對瀏覽器緩存進行了一些研究,發現 iPhone 版 Safari 緩存了文件的未壓縮版本。此外,Mobile Safari 緩存的最大文件大小為 25 KB。在這種情況下,出於性能原因,線重量和磁盤重量都很重要,因為如果沒有必要,您顯然不想在 iPhone 上重新下載資源。事實上,雅虎的瑞安格羅夫! Search 寫了一篇關於他如何使用這些技術來優化 Yahoo! 的文章。搜索 iPhone。

可能存在一個平衡點,即應用其中一些技術(但不是全部)會導致文件大小盡可能小,我將繼續研究,看看是否有辦法朝這個方向優化。

對於第二個批評,你會注意到我對 JavaScript 中變量性能的研究表明,範圍外的變量比範圍內的變量需要更長的時間來讀取和寫入。我還對數據訪問進行了一些研究,發現局部變量與文字值(實驗)具有大致相同的性能特徵,因此當變量是本地時,用變量替換文字 true 不會對性能產生太大影響.用超出範圍的變量替換文字會影響執行時間。

這是空間與時間的經典性能優化鬥爭。如果這種方法導致文件大小更小,因此網絡傳輸時間和解析時間更快,您是否願意對執行時間的性能造成小幅影響?這不是我可以為您或其他任何人回答的問題,這是您必須問自己是否願意做出的權衡。獲得最快的執行代碼和最小的代碼是不可能的,因此作為開發人員,您需要在一個平衡點上做出決定。

使用哪些技術

在軟件開發中總是需要做出權衡。我們需要滿足許多要求,而偏向於一個要求通常會使其他要求受到影響。我在雅虎的演講中指出的事情!前端工程峰會是本演示文稿中介紹的一些技術與我在可維護 JavaScript 演講中介紹的技術相同。我建議這些對代碼的整體質量很重要。儘管將常用字符串和值存儲在變量中可能會對性能產生影響,但我相信為了讓您的代碼更易於維護,這種權衡是值得的。其他更極端的措施,例如替換本機文字,僅在您出於特定原因擔心代碼大小縮小時才可取。

結論

與我介紹的所有內容一樣,我永遠不會大膽地說您應該始終遵循使用 YUI Compressor 進行 Extreme JavaScript 壓縮中的技術。研究對於了解如何更好地使用我們擁有的工具很重要,但這並不意味著您應該自動做任何不同的事情。在不了解目標的情況下執行任何類型的優化都是愚蠢的。對於您的情況,僅 gzipping 實際上可能是最小化網絡傳輸時間的正確答案。我會繼續研究這個話題,當我有更多數據要分享時會再寫一篇文章。


Tutorial JavaScript 教程
  1. 使用 React 和 Chessboardjsx 創建一個國際象棋遊戲♟️

  2. 為什麼 Google Maps API 不能在服務器上運行? [錯誤:地理位置服務失敗]

  3. 如何在 React 中使用上下文?

  4. 將超時設置為事件偵聽器函數

  5. JavaScript 測驗問題 #1:數組排序比較

  6. 日記 - 2018.09.13

  7. Javascript 數組方法 - Sort()

  1. JavaScript 中 this.variable 和 this._variable 的區別?

  2. AngularJS — 使用指令和數據綁定構建應用程序

  3. 美味的鏈接#1

  4. 🚀 PH 發射;改造我們的 OSS 電子商務平台

  5. useLocal:用於正確同步狀態的 useState 掛鉤

  6. 使用蘋果派理解 Array.prototype.reduce() 和遞歸

  7. 使用 Typescript 在前端和後端之間創建一個健壯的 API

  1. 在您的 GitHub 個人資料自述文件中自動顯示您最新的 dev.to 帖子

  2. AWS Lambda,CLI 方式(食譜)

  3. 天才之路:聰明 #23

  4. 在 Javascript 中實現我們自己的`split()`