原文:y3e.cn/T2Fepweb
在建立 Web 應用程序時應始終考慮性能。爲了幫助你開始,本文列舉了有效提升應用程序性能的 12 種方法。算法
性能是建立網頁或應用程序時最重要的一個方面。沒有人想要應用程序崩潰或者網頁沒法加載,或者用戶的等待時間很長。根據 Kissmetrics,47%的訪問者但願網站在不到 2 秒的時間內加載,若是加載過程須要 3 秒以上,則有 40%的訪問者會離開網站。編程
考慮到以上這些數字,你在建立 Web 應用程序時應始終考慮性能。爲了幫助你開始,如下提供了有效提升應用程序性能的 12 種方法:數組
要這樣作有兩種選擇。第一種是使用 JavaScript Cache API,咱們能夠安裝 service worker 來使用它。第二種是使用 HTTP 協議緩存。瀏覽器
訪問某個對象一般要用腳本。經過把重複訪問的對象存儲在用戶定義的變量中,以及在後續對該對象的引用中使用變量,能夠當即實現性能的提高。緩存
爲了有效地衡量你在程序中加入的任何改進,你必須建立一組定義良好的環境,以便測試代碼的性能。性能優化
對全部 Javascript 引擎的全部版本進行性能測試和優化其實是不可行的。可是,在單一的環境中進行測試並不是一個好習慣,由於你可能會獲得片面的結果。所以,創建多個定義良好的環境並測試代碼是否有效很是重要。網絡
此步驟不只會縮短傳輸時間,還會縮短瀏覽器分析和編譯代碼所需的時間。爲此,你必須考慮如下幾點:數據結構
若是你檢測到一個用戶未使用的功能,最好刪除全部與之相關的 JavaScript 代碼,這樣網站的加載速度會更快,用戶也會有更好的體驗。函數
還有可能,你錯誤地加入了一個並不須要的庫,或者你有依賴項,這些依賴項提供的功能在全部瀏覽器中本來就有,那麼你無需再增長多餘的代碼。
你應該始終給內存加一條限制,那就是隻有絕對必須的內容才能使用內存,由於你沒法知道運行應用程序的設備到底須要多少內存。只要你的代碼要求瀏覽器保留新的內存,瀏覽器的垃圾收集器就會被執行,並中止 JavaScript 的運行。若是常常發生這種狀況,頁面將變慢。
用戶但願頁面快速加載,但並不是全部函數都須要在頁面的初始加載時就可用。若是用戶必須執行某個操做才能執行某個函數(例如,經過單擊某個元素或更改選項卡),那麼你能夠將該函數的加載推遲到初始頁面加載以後。
經過這種方式,你能夠避免加載和編譯那些會延遲頁面初始顯示的 JavaScript 代碼。頁面徹底加載後,咱們能夠再開始加載這些功能,以便它們在用戶開始交互時當即可用。在 RAIL 模型中,Google 建議將此延遲加載以 50 毫秒爲單位進行,這樣就不會影響用戶與頁面的交互。
若是內存正在泄漏,則加載的頁面將保留愈來愈多的內存,並最終佔用設備的全部可用內存並嚴重影響性能。你可能見過此類故障(而且可能對此類故障感到懊惱),例如在帶有輪播或圖像滑動條的頁面上。
在 Chrome 開發者工具中,你能夠經過在「性能」標籤中記錄時間線來分析你的網站是否存在內存泄漏。一般,內存泄漏的緣由是,你從頁面中刪除了 DOM,但有一些變量還在引用這些 DOM,所以,垃圾收集器沒法消除它們。
當你執行耗時很長的代碼時,請使用 Web worker。根據 Mozilla 開發人員網絡 (MDN) 文檔:「Web Worker 能夠在與 Web 應用程序的主執行線程分開的後臺線程中運行腳本操做。這樣作的好處是你能夠在一個單獨的線程中執行耗時又費力的的處理,同時讓主(一般爲 UI)線程運行而不被阻塞或減慢。」
Web worker 容許代碼執行處理器密集型計算,而不阻塞用戶界面線程。Web Worker 容許你生成新線程並將工做委託給這些線程以得到高效的性能。這樣,一般會阻礙其餘任務且須要長時間運行的任務將被傳遞給 worker,從而讓主線程能夠在無阻礙的狀況下運行。
訪問 DOM 會很慢。若是要屢次讀取某元素的內容,最好將其保存在局部變量中。但記住重要的是,若是稍後你會刪除 DOM 的值,則應將變量設置爲「null」,否則會致使內存泄漏。
JavaScript 首先搜索以查看變量是否存在於本地,而後纔在更高級別的做用域內逐步搜索到全局變量爲止。將變量保存在本地做用域內能讓 JavaScript 更快地訪問它們。
局部變量是基於最具體的做用域的,而且可能會穿過多個級別的做用域,所以查找這一動做可能致使出現通用的查詢。在一個它前面沒有變量聲明的局部變量中定義函數做用域時,須要在每一個變量以前加上 let 或 const,以便定義當前做用域,防止查找並加速代碼執行。
由於腳本引擎在從函數或其餘做用域內引用全局變量時須要逐一查看做用域,因此當本地做用域丟失時,該變量將被銷燬。若是全局做用域中的變量沒法在腳本的生命週期內持續存在,則性能將獲得改善。
始終使用計算複雜度最低的算法和最佳的數據結構來解決任務。
重寫算法以得到相同的結果和更少的計算。
避免遞歸調用。
給重複的函數加入變量、計算和調用。
分解和簡化數學公式。
使用搜索數組:用它們來獲取基於另外一個的值,而不是使用 switch/case 語句。
使條件老是更有可能爲真,以更好地利用處理器的推測執行。
若是能夠,請使用位級運算符替換某些操做,由於這些運算符的處理週期較短。
Lighthouse 是一個很好的網頁性能工具,它能夠幫助你審覈性能、可訪問性、最佳實踐和 SEO。谷歌 PageSpeed 旨在幫助開發人員瞭解網站的性能優化和潛在可改進的方面。這些組件旨在識別網站是否符合 Google Web 性能最佳實踐,以及將調整過程自動化。
在 Chrome 中,你還可使用主菜單中的「更多工具」選項來查看每一個選項卡使用的內存和 CPU。對於更高級的分析,你可使用 Firefox 或 Chrome 中的開發人員工具「性能」視圖來分析不一樣的指標,例如:
devtools 的性能分析容許你在加載頁面時模擬 CPU 消耗、網絡和其餘指標,以便識別和修復問題。
爲了更深刻地瞭解,建議你使用 JavaScript Navigation Timing API,它容許你詳細測量代碼的每一個部分從編程自己中獲取的內容。
對於基於 Node.js 構建的應用程序,NodeSource Platform 也是一種很是好、影響低的方式,它能夠在很是精細的級別上探索應用程序性能。
全面的 Node.js 指標可幫助你識別內存泄漏源或其餘性能問題,並更快地解決這些問題。
在代碼的可讀性和優化之間保持平衡很重要。代碼由計算機解釋,但咱們須要確保代碼未來能夠由咱們本身或其餘人維護,所以它們須要易於理解。
請記住:應始終考慮性能,但不該將性能凌駕於錯誤檢測和功能添加之上。