JavaScript 微觀效能測試、歷史和侷限性

aow054發表於2024-09-20
我認為效能最佳化對許多開發人員感興趣,因為他們更多地瞭解完成任務的不同方法。一些內心的聲音問道:“哪種方式最好?”雖然“最佳”指標有很多變化,例如 douglas crockford 的 2008 年 javascript:the good parts,但效能是容易獲得的,因為我們可以自己測試它。然而,測試和證明效能並不總是那麼容易做到。 一點歷史 瀏覽器大戰到 2000 年代初期,internet explorer 贏得了第一次瀏覽器戰爭。 ie 甚至一度成為 mac 上的預設瀏覽器。曾經佔據主導地位的網景公司被出售給美國線上並最終關閉。他們的衍生產品 mozilla 對其新的獨立瀏覽器 phoenix firebird firefox 進行了長達數年的測試。 2003 年,opera 7 推出了 presto,這是一種新的、更快的渲染引擎。 apple 還發布了 safari,這是一款基於鮮為人知的 konqueror khtml 引擎構建的 mac 效能瀏覽器。 firefox於2004年正式推出。微軟於2006年釋出了ie 7,opera 9釋出了更快的javascript引擎。 2007 年,safari 出現在 windows 和新 iphone 上。 2008 年出現了 google chrome 和 android 瀏覽器。立即學習“Java免費學習筆記(深入)”;隨著更多的瀏覽器和更多的平臺,效能成為這一時期的關鍵部分。新的瀏覽器版本定期宣佈它們是新的最快的瀏覽器。 apple 的 sunspider 和 mozilla 的 kraken 等基準測試經常在版本中被引用,而 google 則維護著自己的 octane 測試套件。 2010年chrome團隊甚至做了一系列“速度測試”實驗來展示瀏覽器的效能。 高效能 javascript微效能測試在 2010 年代受到了廣泛關注。 web 正在從有限的頁面互動性轉向完整的客戶端單頁應用程式。 nicholas zakas 的 2010 年高效能 javascript 等書籍展示了看似微小的設計選擇和編碼實踐如何能夠產生有意義的效能影響。 不斷變化不久前,javascript 引擎競賽就致力於解決高效能 javascript 中的一些關鍵效能問題,引擎的快速變化使得很難知道什麼是最好的現在。隨著新的瀏覽器版本和移動裝置的出現,微效能測試成為一個熱門話題。到 2015 年,現已關閉的效能測試網站 jsperf.com 非常受歡迎,它開始因垃圾郵件而出現效能問題。 測試正確的事情隨著 javascript 引擎的發展,編寫測試很容易,但很難確保你的測試公平甚至有效。如果您的測試消耗了大量記憶體,則後續測試可能會看到垃圾收集造成的延遲。設定時間是否被計入或排除在所有測試之外?測試是否產生相同的輸出?測試的背景重要嗎?如果我們測試 !~arr.indexof(val) 與 arr.indexof(val) === -1 ,如果我們只是執行表示式或在 if 條件下使用它,會有什麼不同嗎? 編譯器最佳化隨著指令碼直譯器被各種編譯器取代,我們開始看到編譯程式碼的一些好處和副作用:最佳化。例如,在沒有副作用的迴圈中執行的程式碼可能會被完全最佳化。// Testing the speed of different comparison operatorsfor (let i = 0; i <p>因為這是執行 10000 次操作而沒有輸出或副作用,所以最佳化可能會完全丟棄它。但這並不能保證。</p><h3> 移動目標</h3><p>此外,微最佳化在不同版本之間可能會發生顯著變化。 jsperf.com 的不幸關閉意味著不同瀏覽器版本的數百萬歷史測試比較丟失,但這仍然是我們今天可以看到的。</p><p>重要的是要記住,微最佳化效能測試有很多注意事項。 </p><p>隨著效能改進開始趨於平穩,我們看到測試結果出現反彈。其中一部分是引擎的改進,但我們也看到引擎針對<em>常見模式</em>最佳化程式碼。即使存在更好的編碼解決方案,最佳化通用程式碼模式對使用者來說也有真正的好處,而不是期望每個站點都進行更改。</p><h3> 變化的景觀</h3><p>比不斷變化的瀏覽器效能更糟糕的是,2018 年計時器的準確性和精度發生了變化,以減輕 spectre 和 meltdown 等推測執行攻擊。如果您感興趣的話,我寫了一篇關於這些時間問題的單獨文章。</p><h3> 分焦</h3><p>讓事情變得複雜的是,您是否針對最新的瀏覽器或專案支援的最低瀏覽器進行測試和最佳化?同樣,隨著智慧手機的普及,處理能力明顯較低的手持裝置成為重要的考慮因素。知道在哪裡分配時間以獲得最佳結果或<em>最有影響力</em>結果變得更加困難。 </p><h2> 過早最佳化?</h2><blockquote>過早的最佳化是萬惡之源。 ——唐納德·高德納</blockquote><p>這句話經常被引用。人們用它來暗示,每當我們考慮最佳化時,我們可能會為了虛幻的或微不足道的收益而浪費時間並使程式碼變得更糟。在很多情況下這可能是正確的。但這句話還有更多內容:</p><blockquote><p>我們應該忘記小的效率,大約 97% 的情況下:過早的最佳化是萬惡之源。但我們不應該放棄這關鍵的 3% 的機會。</p></blockquote><p>更完整的引用新增了關鍵上下文。如果我們允許自己這樣做,我們可以在<em>小效率</em>上花費大量時間。這通常會花費時間來實現專案目標,但無法提供太多價值。</p><h3> 收益遞減</h3><p>我個人在這些最佳化上花了很多時間,目前看來並不算浪費。但回想起來,並不清楚這些工作有多少是值得的。我確信我當時寫的一些程式碼將執行時間縮短了幾毫秒,但我真的不能說節省的時間是否<em>重要</em>。</p><p>google 甚至談到了 2017 年 octane 測試套件退役的回報遞減。我強烈建議您閱讀這篇文章,深入瞭解致力於這項工作的團隊在效能最佳化方面遇到的限制和問題。</p><p>那麼我們如何聚焦那“關鍵的3%”呢?</p><h2> 應用而非操作</h2><p>瞭解程式碼的使用方式和時間有助於我們更好地決定關注點。</p><h3> 工具而非規則</h3><p>不久之後,新瀏覽器的效能提升和變化就開始將我們從這些型別的微觀測試推向更廣泛的工具,例如火焰圖。<br>如果您有 30 分鐘時間,我推薦這個關於 v8 引擎的 2015 chrome devsummit 演示。它討論的正是這些問題......瀏覽器不斷變化,跟上這些細節可能很困難。</p><p>對正在執行的應用程式進行效能監控和分析可以幫助您快速識別程式碼的哪些部分執行緩慢或執行頻繁。這使您能夠處於有利的位置來考慮最佳化。</p><h3> 重點</h3><p>使用效能監控工具和庫可以讓您瞭解程式碼如何執行以及哪些部分需要工作。它們還讓我們有機會了解不同的領域是否需要在不同的平臺或瀏覽器上工作。也許 localstorage 在記憶體和 emmc 儲存有限的 chromebook 上要慢得多。也許您需要快取更多資訊來應對緩慢或不穩定的蜂窩服務。我們可以猜測哪裡出了問題,但測量是更好的解決方案。</p><p>如果您的客戶群足夠大,您可能會發現真實使用者監控 (rum) 工具的好處,它可以讓您瞭解實際的客戶體驗。這些超出了本文的範圍,但我已經在幾家公司使用它們來了解客戶體驗的範圍,並將重點放在實際效能和錯誤處理上。</p><h2> 替代方案</h2><p>深入思考“我如何改進這件事”很容易,但這並不總是最好的答案。您可以退後一步並詢問“這是解決此問題的正確解決方案嗎?”來節省大量時間</p><p>在 dom 上載入非常大的元素列表時出現問題?也許僅在頁面上載入可見元素的虛擬化列表可以解決效能問題。</p><p>在客戶端執行許多複雜的操作?在伺服器上計算部分或全部這些會更快嗎?部分工作可以快取嗎?</p><p>退一步:這是執行此任務的正確使用者介面嗎?如果您設計的下拉選單預計有 20 個條目,而現在有 3000 個條目,那麼您可能需要不同的元件或體驗來進行選擇。</p><h2> 夠好了嗎?</h2><p>對於任何表演作品,都存在一個次要問題:“什麼才足夠”?有一個來自 stand-up maths 的 matt parker 的精彩影片,講述了他編寫的一些程式碼以及他的社群如何將其從執行時間<em>周</em>改進到<em>毫秒</em>。雖然令人難以置信的是,這樣的最佳化是可能的,但幾乎所有專案都有一個達到“足夠好”的點。 </p><p>對於只執行一次的程式,幾周可能是可以接受的,幾個小時會更好,但你快速花費多少時間就成為一個重要的考慮因素。</p><p>您可能會認為它就像工程中的<em>公差</em>。我們有一個目標,我們有一個接受範圍。我們可以追求完美,同時明白成功和完美並不相同。</p><h3> 確定績效目標</h3><p>目標是最佳化的關鍵部分。如果你只知道當前狀態不好,“讓它變得更好”就是一個開放式目標。如果沒有最佳化之旅的目標,當您可以處理更重要的事情時,您可能會浪費時間嘗試尋找更高的效能或更多的最佳化。</p><p>我對此沒有一個好的衡量標準,因為效能最佳化可能會有很大差異,但儘量不要迷失在雜草中。這實際上與專案管理和規劃有關,而不僅僅是編碼解決方案,但在定義最佳化目標時,開發人員的輸入非常重要。正如“替代方案”部分中所建議的,解決方案可能不是“使其更快”。</p><h4> 設定限制</h4><p>就馬特·帕克的情況而言,他<em>最終需要答案</em>,並且不需要將該裝置用於其他任何用途。在我們的世界中,我們經常衡量<em>訪問者表現</em>及其<em>可能的財務影響</em>與<em>開發人員/團隊時間</em>以及您的<em>機會成本</em>,所以措施沒那麼簡單。</p><p>假設我們<em>知道</em>將新增到購物車的時間減少 50% 將使我們的收入增加 10%,但完成這項工作需要兩個月的時間。有什麼比兩個月的最佳化工作產生更大的財務影響嗎?你能在更短的時間內實現一些效益嗎?再說一次,這是關於專案管理而不是程式碼。</p><h3> 隔離複雜性</h3><p>當您確實發現自己需要最佳化程式碼時,也是看看是否可以將該程式碼與專案的其他部分分開的好時機。如果您知道必須編寫複雜的最佳化,這將使程式碼難以理解,那麼將其提取到實用程式或庫可以使其更容易重用,並允許您在需要隨時間變化時在一個地方更新該最佳化。</p><h2> 結論</h2><p>表演是一個複雜的話題,有很多曲折。如果你不小心的話,你可能會投入大量的精力卻收效甚微。好奇心可以是一位好老師,但它並不總是能取得成果。玩弄程式碼效能是有好處的,但也有時間分析專案中緩慢的實際來源並使用可用的工具來幫助解決它們。</p><h2> 資源</h2>登入後複製addy osmani - 使用 devtools flame charts 視覺化 js 處理隨時間的變化站立數學 - 有人將我的程式碼改進了 40,832,277,770%使用 microsoft copilot 製作的標題影像以上就是JavaScript 微觀效能測試、歷史和侷限性的詳細內容,更多請關注我的其它相關文章!

相關文章