聯(lián)系電話
186 9846 8112
Copyright ? 2014-2025 航佳網(wǎng)絡(luò)科技有限公司 m.century21dg.cn All Rights Reserved.
移動版
關(guān)注微信
當前位置:首頁 > 新聞關(guān)注 > 網(wǎng)站優(yōu)化 > 14 個 JavaScript 代碼優(yōu)化技巧
發(fā)布時間:2020-08-19關(guān)注:6797編輯:內(nèi)蒙古航佳網(wǎng)絡(luò)科技有限公司標簽: 網(wǎng)站優(yōu)化
本文初發(fā)布于 Medium 網(wǎng)站,經(jīng)原作者由 InfoQ 中文站翻譯并分享。
JavaScript 已經(jīng)成為有史以來受歡迎的編程語言之一。根據(jù) W3Tech 的數(shù)據(jù),全將近 96%的網(wǎng)站都在使用它。關(guān)于 Web 有一個關(guān)鍵的事實是,你無法控制訪問網(wǎng)站的用戶所用設(shè)備的硬件規(guī)格。終用戶訪問你的網(wǎng)站時,使用的可能是高端設(shè)備也可能是低端設(shè)備,網(wǎng)絡(luò)連接條件也有好有差。這意味著你必須盡可能優(yōu)化自己的網(wǎng)站,以滿足用戶的需求。
這篇文章列舉了一些技巧,可幫助你寫出更好的 JavaScript 代碼,從而提高性能。
附帶提一下,請共享和重用你的 JS 組件,以在高質(zhì)量代碼(寫起來需要花費時間)和合理的交付時間之間保持適當?shù)钠胶?。你可以使?Bit 等流行工具將項目中的組件(普通 JS、TS、React、Vue 等)共享到 Bit 的組件中心,用不了多大功夫
1、刪除未使用的代碼和功能
你的應(yīng)用程序包含的代碼越多,就需要將更多的數(shù)據(jù)傳輸?shù)娇蛻舳?。瀏覽器也需要更多時間來分析和解釋代碼。
有時,你可能打包了很多根本用不到的功能。好只在開發(fā)環(huán)境中保留這些額外的代碼,而不要將其推送到生產(chǎn)環(huán)境中,以免給客戶端的瀏覽器增加負擔。
要不斷問自己,某個功能或代碼段是否是必要的。
你可以手動移除未使用的代碼,也可以使用 Uglify 或谷歌的 Closure Compiler 之類的工具刪除它們。你甚可以使用一種稱為搖樹優(yōu)化的技術(shù)從應(yīng)用程序中刪除未使用的代碼。Webpack 這類打包軟件提供了這種技術(shù),詳情可以參考這里。如果要刪除未使用的npm 軟件包,可以使用令npm prune,詳細信息參考 NPM 文檔。
2、盡可能緩存緩存
可以減少延遲和網(wǎng)絡(luò)流量,從而減少了顯示資源表示所需的時間,以提高網(wǎng)站的速度和性能。緩存可以借助 Cache API 或 HTTP caching 來實現(xiàn)。你可能想知道內(nèi)容更改時會發(fā)生什么。當滿足某些條件(例如發(fā)布新內(nèi)容)時,上述緩存機制能夠處理和重成緩存。
3、避免內(nèi)存泄漏
作為一種語言,JS 會負責一些底層管理工作,例如內(nèi)存管理。垃圾回收是大多數(shù)編程語言共有的過程。用外行術(shù)語來說,垃圾收集就是收集并釋放已分配給對象,但目前尚未在程序的部分中使用的內(nèi)存。在 C 這樣的編程語言中,開發(fā)人員必須使用 malloc() 和 dealloc() 函數(shù)來處理內(nèi)存分配和釋放作。
雖然在 JavaScript 中垃圾回收是自動執(zhí)行的,但在某些情況下它也不是的。在 JavaScript ES6 中,引入了 Map 和 Set 及其“weaker”的同級對象。被稱為 WeakMap 和 WeakSet 的“較弱”對應(yīng)項持有對對象的“弱”引用。它們使未引用的值能夠被垃圾回收,從而防止內(nèi)存泄漏。你可以在此處閱讀有關(guān) WeakMaps 的更多信息。
4、盡早打破循環(huán)
超大循環(huán)肯定會消耗很多寶貴的時間,所以你應(yīng)該盡早打破它們。你可以用 break 關(guān)鍵字和 continue 關(guān)鍵字來做這件事。編寫高效的代碼是你的責任。
在下面的示例中,如果你沒有從循環(huán)中 break,則你的代碼將循環(huán)運行 1000000000 次,顯然會過載的。
你可以在此處詳細了解循環(huán)和性能的關(guān)系。
5、小化變量計算的次數(shù)
為了減少計算變量的次數(shù),可以使用閉包。通俗來說,JavaScript 中的閉包使你可以從內(nèi)部函數(shù)訪問外部函數(shù)作用域。每次創(chuàng)建函數(shù)(不調(diào)用)時都會創(chuàng)建閉包。內(nèi)部函數(shù)將有權(quán)訪問外部作用域的變量,即使在返回外部函數(shù)之后也是如此。
我們來看兩個例子。這些示例均來自 Bret 的博客。
如果你多次調(diào)用上面的函數(shù),那么每次都會創(chuàng)建一個新對象。每次調(diào)用時,變量 texasCustomers 和 californiaCustomers 都會導(dǎo)致不必要的內(nèi)存重分配。
在上面的示例中,借助于閉包,返回到變量 cityOfCustomer 的內(nèi)部函數(shù)可以訪問外部函數(shù) findCustomerCity() 的常量。而且,每當以傳遞的名稱作為參數(shù)調(diào)用內(nèi)部函數(shù)時,都無需再次實例化常量。要了解關(guān)于閉包的更多信息,建議你閱讀 Prashant 的博客文章。
6、盡量減少 DOM 訪問
與其他 JavaScript 語句相比,訪問 DOM 的速度很慢。如果你對 DOM 進行更改,觸發(fā)了布局的重新繪制,那么就得等好一陣子了。
為了減少訪問 DOM 元素的次數(shù),請先訪問一次,然后將其用作局部變量。完成需求后,請一定將其設(shè)置為 null 來移除該變量的值。這將防止內(nèi)存泄漏,因為這會觸發(fā)垃圾回收過程。
7、壓縮文件
通過壓縮方法(例如 Gzip)可以減小 JavaScript 文件的大小。較小的文件會你的網(wǎng)站性能,因為瀏覽器只需下載較小的資產(chǎn)即可。
這類壓縮手段多可以減少 80%的文件大小。在此處閱讀有關(guān)壓縮的更多信息。
8、縮小終代碼
有人認為縮小和壓縮是相同的,其實不然。在壓縮中,我們使用特殊算法來改變文件的輸出大?。辉诳s小時,我們需要刪除 JavaScript 文件中的注釋和多余的空格??梢栽诰W(wǎng)上找到許多工具和軟件包來幫助完成這一過程。縮小已成為頁面優(yōu)化的標準做法,也是前端優(yōu)化的主要步驟之一。
縮小可以讓文件大小多減少 60%。你可以在此處閱讀有關(guān)縮小的更多信息。
9、使用 Throttle(節(jié)流)和 Debounce(防抖)
我們可以使用這兩種技術(shù)來嚴格控制代碼需要處理事件的次數(shù)。
節(jié)流是指定函數(shù)可以超時的大次數(shù)。例如,“每 1000 毫秒多執(zhí)行一次 onkeyup 事件函數(shù)”。也就是說哪怕你每秒敲 20 個鍵,該事件每秒也只會觸發(fā)一次。這將減少代碼的負擔。
另一方面,防抖是指定自上次執(zhí)行相同函數(shù)以來再次運行該函數(shù)的短持續(xù)時間。換句話說,“上次調(diào)用函數(shù)后過少 600 毫秒才執(zhí)行此函數(shù)”。要了解有關(guān)節(jié)流和防抖的更多信息,這里有一篇快速入門。
你可以實現(xiàn)自己的防抖和節(jié)流函數(shù),也可以從Lodash 和Underscore 之類的庫中導(dǎo)入它們。
10、避免使用 Delete
關(guān)鍵字delete 關(guān)鍵字用于從對象中刪除屬性。這個關(guān)鍵字的性能表現(xiàn)不怎么好,預(yù)計它將在未來的更新中。
或者,你可以簡單地將不需要的屬性設(shè)置為 undefined。
你還可以使用 Map 對象,Bret 認為它的 delete 方法會更快。
11、使用異步代碼防止線程阻塞
你應(yīng)該知道 JavaScript 默認情況下是同步的和單線程的。但是在某些情況下,你的代碼需要很大的計算量。代碼本質(zhì)上是同步的,意味著一段代碼運行時將阻止其他代碼語句運行,直到前者完成執(zhí)行為止。這會整體性能。
但是我們可以通過異步代碼來避免這種情況。異步代碼以前以回調(diào)的形式編寫,但是 ES6 引入了一種處理異步代碼的新樣式。這種新樣式被稱為 Promise。你可以在 MDN 的官方文檔中了解有關(guān)回調(diào)和 Promise 的更多信息。
可是等等……
JavaScript 默認情況下是同步的,并且也是單線程的。
如何在單個線程上運行異步代碼呢?這是很多人感到困惑的地方。做到這一點,主要依賴運行在瀏覽器后臺的 JavaScript 引擎。JavaScript 引擎是執(zhí)行 JavaScript 代碼的計算機程序或解釋器。JavaScript 引擎可以用多種語言編寫。例如,支持 Chrome 瀏覽器的 V8 引擎是用 C++ 編寫的,而支持 Firefox 瀏覽器的 SpiderMonkey 引擎是用 C 和 C++ 編寫的。
這些 JavaScript 引擎可以在后臺處理任務(wù)。根據(jù) Brian 的說法,調(diào)用棧可以識別 Web API 的函數(shù),并將其交給瀏覽器處理。瀏覽器完成這些任務(wù)后,它們將返回并作為回調(diào)被推上堆棧。
你可能想知道 Node.js 是怎么做這些工作的,畢竟它沒有瀏覽器的幫助。實際上,支持 Chrome 的那個 V8 引擎也是 Node.js 背后的支撐。這里有 Salil 的一篇很棒的博客文章,解釋了Node 生態(tài)系統(tǒng)中的這一過程。
12、使用代碼拆分
如果你有使用 Google Light House 的經(jīng)驗,肯定會熟悉一種稱為“first contentful paint”的指標。它是 Lighthouse 報告的 Performance 部分中跟蹤的六個指標之一。
First Contentful Paint(FCP)衡量用戶轉(zhuǎn)到你的頁面后瀏覽器渲染段 DOM 內(nèi)容所花費的時間。頁面上的圖像、非白色<canvas>元素和 SVG 被視為 DOM 內(nèi)容;iframe 內(nèi)部不包含內(nèi)容。
獲得更高的 FCP 分數(shù)的佳方法之一是使用代碼拆分。代碼拆分是一種在傳輸開始時僅將必要的模塊發(fā)送給用戶的技術(shù)。通過減小初發(fā)送的載荷大小,這將極大地影響 FCP 分數(shù)。
流行的模塊打包器(例如 webpack)可為你提供代碼拆分功能。你還可以利用原生 ES 模塊來單獨加載各個模塊。你可以在此處詳細了解有關(guān)原生 ES 模塊的信息。
13、使用 async 和 defer
在現(xiàn)代網(wǎng)站中,腳本比 HTML 更為密集,其大小更大且消耗更多的處理時間。默認情況下,瀏覽器必須等待腳本下載和執(zhí)行完畢后,再處理頁面的其余部分。
于是笨重的腳本可能會阻止網(wǎng)頁的加載。為了避免這種情況,JavaScript 為我們提供了兩種分別稱為 async 和 defer 的技術(shù)。你只需將這些屬性添加到<script>標記中即可。
Async 會讓瀏覽器在不影響渲染的情況下加載腳本。換句話說,頁面不會等待 async 腳本,而是先處理和顯示內(nèi)容。
Defer 是讓瀏覽器在渲染完成后加載腳本。如果同時指定它們兩者,則 async 在現(xiàn)代瀏覽器上更優(yōu)先,而支持 defer 但不支持 async 的老式瀏覽器將回退為 defer。
這兩個屬性可以幫助你大幅減少頁面加載時間。我強烈建議你閱讀 Flavio 的這篇博客文章。
14、使用 Web Workers 在后臺運行 CPU 密集型任務(wù)
Web Worker 允許你在后臺線程中運行腳本。如果你有一些高強度的任務(wù),可以將它們分配給 Web Worker,這些 WebWorker 可以在不干擾用戶界面的情況下運行它們。創(chuàng)建后,Web Worker 可以將消息發(fā)布到該代碼指定的事件處理程序來與 JavaScript 代碼通信,反之亦然。
要了解有關(guān) Web Worker 的更多信息,建議你閱讀 MDN 文檔。
感謝閱讀,歡迎評論,編程愉快!延伸閱讀https://blog.bitsrc.io/14-javascript-code-optimization-tips-for-front-end-developers-a44763d3a0da
文章來源:https://www.infoq.cn/article/MwyrfzDPdRpkzfbW7NwW
內(nèi)蒙古網(wǎng)絡(luò)公司航佳網(wǎng)絡(luò)網(wǎng)站建設(shè)為您提供網(wǎng)站運營、網(wǎng)站制作、網(wǎng)站優(yōu)化、網(wǎng)站優(yōu)化推廣知識,有何疑問就趕緊咨詢我們,銷售電話:18698468112
相關(guān)新聞
用戶操作的目的也會比較強。為了方便用戶操作,應(yīng)用頁面顯示...
時間:2016/10/06
要建立視覺層次,才能讓網(wǎng)站有一個明晰的脈絡(luò)。重要的是要記...
時間:2016/10/10
網(wǎng)頁設(shè)計、前端設(shè)計、后臺維護等眾多工序都可以交給網(wǎng)絡(luò)公司...
時間:2016/09/02
每一種設(shè)計樣式的存在都是有理由的,在設(shè)計之前需要定義好整...
時間:2016/11/23
傳遞信息的視覺要素包括版式、文字、圖像和動畫、色彩等,網(wǎng)...
時間:2016/10/15
內(nèi)蒙古網(wǎng)絡(luò)公司航佳網(wǎng)絡(luò)專業(yè)服務(wù)呼和浩特網(wǎng)站建設(shè)、呼和浩特網(wǎng)絡(luò)推廣、呼和浩特網(wǎng)頁設(shè)計、呼和浩特建網(wǎng)站,呼和浩特做網(wǎng)站,做網(wǎng)站還是選擇呼和浩特網(wǎng)絡(luò)公司、呼市網(wǎng)絡(luò)公司航佳網(wǎng)絡(luò)。| |