溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

十四個(gè)JavaScript的優(yōu)化代碼建議是怎樣的

發(fā)布時(shí)間:2021-09-30 11:44:26 來(lái)源:億速云 閱讀:126 作者:柒染 欄目:web開(kāi)發(fā)

今天就跟大家聊聊有關(guān)十四個(gè)JavaScript的優(yōu)化代碼建議是怎樣的,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

JavaScript 已經(jīng)成為當(dāng)下最流行的編程語(yǔ)言之一。根據(jù) W3Tech,全世界幾乎 96%  的網(wǎng)站都在使用它。關(guān)于網(wǎng)站,你需要知道的最關(guān)鍵的一點(diǎn)是,你無(wú)法控制訪問(wèn)你網(wǎng)站的用戶(hù)的硬件設(shè)備規(guī)格。訪問(wèn)你的網(wǎng)站的終端用戶(hù)也許使用了高端或低端的設(shè)備,用著好的或差的網(wǎng)絡(luò)連接。這意味著你必須確保你的網(wǎng)站是盡可能優(yōu)化的,你能夠滿足任何用戶(hù)的要求。

這里有一些技巧,可以幫助你更好地優(yōu)化 JavaScript 代碼,從而提高性能。

1. 刪除不使用的代碼和功能

程序包含越多的代碼,給客戶(hù)端傳遞的數(shù)據(jù)就越多。瀏覽器也需要更多的時(shí)間去解析和編譯代碼。

有時(shí),代碼里也許會(huì)包含完全未使用到的功能,最好只將這些額外的代碼保留在開(kāi)發(fā)環(huán)境中,并且不要把它們留到生產(chǎn)環(huán)境中,因?yàn)闊o(wú)用的代碼可能會(huì)增加客戶(hù)端瀏覽器的負(fù)擔(dān)。

經(jīng)常問(wèn)自己那個(gè)函數(shù)、特性或代碼是否是必需的。

你可以手動(dòng)的刪掉無(wú)用的代碼,也可以用工具 Uglify 或 谷歌開(kāi)發(fā)的 Closure Compiler 幫你刪。你甚至可以使用一種叫做 tree  shaking 的技術(shù)來(lái)刪除程序中未使用的代碼。例如打包工具 Webpack 就提供了它。你可以在 這里 了解更多關(guān)于 tree shaking  信息。還有,如果你想刪掉未使用的 npm 包,你可以輸入命令 npm prune 。

2. 盡可能緩存

緩存通過(guò)減少等待時(shí)間和網(wǎng)絡(luò)請(qǐng)求提高了網(wǎng)站的速度和性能,因此減少了展示資源的時(shí)間??梢越柚?緩存 API 或 HTTP 緩存  實(shí)現(xiàn)它。你也許好奇當(dāng)內(nèi)容改變時(shí)發(fā)生了什么。上述緩存機(jī)制能夠在滿足某些條件(如發(fā)布新內(nèi)容)時(shí)處理和重新生成緩存。

3. 避免內(nèi)存泄漏

作為一種高級(jí)語(yǔ)言,JS  負(fù)責(zé)幾個(gè)低級(jí)別的管理,比如內(nèi)存管理。對(duì)于大多數(shù)編程語(yǔ)言來(lái)說(shuō),垃圾回收是一個(gè)常見(jiàn)的過(guò)程。通俗地說(shuō),垃圾回收就是簡(jiǎn)單地收集和釋放,那些已經(jīng)分配給對(duì)象,但目前又不被程序任一部分使用的內(nèi)存。在像  C 這樣的編程語(yǔ)言中,開(kāi)發(fā)者必須使用 malloc() 和 dealloc() 函數(shù)來(lái)處理內(nèi)存分配和回收。

盡管垃圾回收是 JavaScript 自動(dòng)執(zhí)行的,但在某些情況下,它可能并不完美。在 JavaScript ES6 中,Map 和 Set  與它們的“weaker”兄弟元素一起被引入?!皐eaker”對(duì)應(yīng)著 WeakMap 和  WeakSet,持有的是每個(gè)鍵對(duì)象的“弱引用”。它們?cè)试S對(duì)未引用的值進(jìn)行垃圾收集,從而防止內(nèi)存泄漏。了解更多關(guān)于 WeakMaps 的信息。

4. 盡早跳出循環(huán) Try to Break Out of Loops  Early

執(zhí)行循環(huán)在代碼量大的循環(huán)中肯定會(huì)消耗大量寶貴的時(shí)間,這就是為什么要盡早打破循環(huán)的原因。你可以使用 break 關(guān)鍵字和continue  關(guān)鍵字跳出循環(huán)。編寫(xiě)最有效的代碼是開(kāi)發(fā)者們的責(zé)任。

在下面的例子中,如果你不在循環(huán)中使用 break ,你的代碼將運(yùn)行循環(huán) 1000000000 次,顯然是超出負(fù)荷的。

let arr = new Array(1000000000).fill('----'); arr[970] = 'found'; for (let i = 0; i < arr.length; i++) {   if (arr[i] === 'found') {         console.log("Found");         break;     } }

在下面的例子中,當(dāng)不滿足條件時(shí)如果你不使用 continue,那么將執(zhí)行函數(shù) 1000000000  次。而我們只處理了位于偶數(shù)位置的數(shù)組元素,就將循環(huán)執(zhí)行減少了近一半。

let arr = new Array(1000000000).fill('----'); arr[970] = 'found'; for (let i = 0; i < arr.length; i++) {   if(i%2!=0){         continue;     };     process(arr[i]); }

5. 最小化變量的計(jì)算次數(shù)

要減少計(jì)算變量的次數(shù),可以使用閉包。JavaScript  中的閉包允許你從內(nèi)部函數(shù)訪問(wèn)外部函數(shù)作用域。每次創(chuàng)建一個(gè)函數(shù)時(shí)都會(huì)創(chuàng)建閉包&mdash;&mdash;但不調(diào)用。內(nèi)部函數(shù)可以訪問(wèn)外部作用域的變量,即使外部函數(shù)已經(jīng)調(diào)用結(jié)束。

讓我們看兩個(gè)例子,看看這是怎么回事。這些例子的靈感來(lái)自 Bret 的博客。

function findCustomerCity(name) {   const texasCustomers = ['John', 'Ludwig', 'Kate'];    const californiaCustomers = ['Wade', 'Lucie','Kylie'];      return texasCustomers.includes(name) ? 'Texas' :      californiaCustomers.includes(name) ? 'California' : 'Unknown'; };

如果我們多次調(diào)用上述函數(shù),每次都會(huì)創(chuàng)建一個(gè)新對(duì)象。對(duì)于每個(gè)調(diào)用,不會(huì)將內(nèi)存重新分配給變量 texasCustometrs 和  californiaCustomers。

通過(guò)使用帶有閉包的解決方案,我們只能實(shí)例化變量一次。讓我們看看下面的例子。

function findCustomerCity() {   const texasCustomers = ['John', 'Ludwig', 'Kate'];    const californiaCustomers = ['Wade', 'Lucie','Kylie'];      return name => texasCustomers.includes(name) ? 'Texas' :      californiaCustomers.includes(name) ? 'California' : 'Unknown'; };  let cityOfCustomer = findCustomerCity();  cityOfCustomer('John');//Texas cityOfCustomer('Wade');//California cityOfCustomer('Max');//Unknown

上述例子中,在閉包的幫助下,返回給變量 cityOfCustomer 的內(nèi)部函數(shù)可以訪問(wèn)外部函數(shù) findCustomerCity()  的常量。并且當(dāng)調(diào)用內(nèi)部函數(shù)并傳參 name 時(shí),不需要再次實(shí)例化這些常量。

6. 最小化 DOM 的訪問(wèn)

與其他 JavaScript 語(yǔ)句相比,訪問(wèn) DOM 要慢一些。如果你要操作  DOM,從而觸發(fā)重繪布局,那么操作會(huì)變得相當(dāng)緩慢。

要減少訪問(wèn) DOM 元素的次數(shù),請(qǐng)?jiān)L問(wèn)它一次,并將其作為局部變量使用。當(dāng)需求完成時(shí),確保通過(guò)將變量設(shè)置為 null  來(lái)刪除該變量的值。這將防止內(nèi)存泄漏,因?yàn)樗试S垃圾回收。

7. 壓縮文件

通過(guò)使用諸如 Gzip 之類(lèi)的壓縮方法,可以減小 JavaScript  文件的大小。這些較小的文件將提升網(wǎng)站性能,因?yàn)闉g覽器只需要下載較小的資源。

這些壓縮可以減少多達(dá) 80% 的文件大小。在這里了解更多關(guān)于  壓縮:https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/optimize-encoding-and-transfer#text_compression_with_gzip。

十四個(gè)JavaScript的優(yōu)化代碼建議是怎樣的

8. 縮小你的最終代碼

有些人認(rèn)為縮小和壓縮是一樣的。但卻相反,它們是不同的。在壓縮中,使用特殊的算法來(lái)改變輸出文件的大小。但在縮小中,需要?jiǎng)h除  JavaScript  文件中的注釋和額外的空格。這個(gè)過(guò)程可以在網(wǎng)上找到的許多工具和軟件包的幫助下完成??s小已經(jīng)成為頁(yè)面優(yōu)化的標(biāo)準(zhǔn)實(shí)踐和前端優(yōu)化的主要組成部分。

縮小可以減少你的文件大小高達(dá) 60%。

9. 使用節(jié)流 throttle 和防抖 debounce

通過(guò)使用這兩種技術(shù),我們可以嚴(yán)格執(zhí)行代碼需要處理事件的次數(shù)。

節(jié)流是指函數(shù)在指定時(shí)間內(nèi)被調(diào)用的最大次數(shù)。例如,“最多每 1000 毫秒執(zhí)行一次 onkeyup 事件函數(shù)”。這意味著如果你每秒輸入 20  個(gè)鍵,該事件將每秒只觸發(fā)一次。這將減少代碼的加載。

另一方面,防抖是指函數(shù)在上次觸發(fā)后再次觸發(fā)要間隔的最短時(shí)間。換句話說(shuō),“僅當(dāng)經(jīng)過(guò) 600  毫秒而沒(méi)有調(diào)用該函數(shù)時(shí)才執(zhí)行該函數(shù)”。這將意味著,你的函數(shù)將不會(huì)被調(diào)用,直到 600  毫秒后,最后一次執(zhí)行相同的函數(shù)。要了解更多關(guān)于節(jié)流和防抖的知識(shí),這里有一個(gè)快速閱讀。

你可以實(shí)現(xiàn)自己的防抖和節(jié)流函數(shù),也可以從 Lodash 和 Underscore 等庫(kù)導(dǎo)入它們。

10. 避免使用 delete 關(guān)鍵字

delete 關(guān)鍵字用于從對(duì)象中刪除屬性。關(guān)于這個(gè) delete 關(guān)鍵字的性能,已經(jīng)有一些爭(zhēng)議。你可以在 此處 和  [此處](https://stackoverflow.com/questions/43594092/slow-delete-of-object-  propertieses-in-js-in-v8/44008788) 中查看它們。這個(gè)問(wèn)題有望在未來(lái)的更新中得到解決。

As an alternative, you can simply to set the unwanted property as undefined.  另一種選擇是,你可以直接將將不想要的屬性設(shè)置為 undefined。

const object = {name:"Jane Doe", age:43}; object.age = undefined;

你還可以使用 Map 對(duì)象,因?yàn)楦鶕?jù) Bret,Map 的 delete 方法被認(rèn)為更快。

11. 使用異步代碼防止線程阻塞

你應(yīng)該知道 JavaScript  是同步的,也是單線程的。但是在某些情況下,可能會(huì)花費(fèi)大量的時(shí)間來(lái)執(zhí)行一段代碼。在本質(zhì)上同步意味著,這段代碼將阻止其他代碼語(yǔ)句的運(yùn)行,直到它完成執(zhí)行,這會(huì)降低代碼的整體性能。

但其實(shí),我們可以通過(guò)實(shí)現(xiàn)異步代碼來(lái)避免這種情況。異步代碼以前是以回調(diào)的形式編寫(xiě)的,但是在 ES6 中引入了一種處理異步代碼的新風(fēng)格。這種新風(fēng)格被稱(chēng)為  promises。

等等&hellip;

  • JavaScript默認(rèn)是同步的,也是單線程的。

為什么在單一線程上運(yùn)行,還能運(yùn)行異步代碼?這是很多人感到困惑的地方。這要?dú)w功于瀏覽器外殼下運(yùn)行的 JavaScript 引擎。JavaScript  引擎是執(zhí)行 JavaScript 代碼的計(jì)算機(jī)程序或解釋器。JavaScript 引擎可以用多種語(yǔ)言編寫(xiě)。例如,支持 Chrome 瀏覽器的 V8 引擎是用  c++ 編寫(xiě)的,而支持 Firefox 瀏覽器的 SpiderMonkey 引擎是用 C 和 C++ 編寫(xiě)的。

這些 JavaScript 引擎可以在后臺(tái)處理任務(wù)。根據(jù) Brian,調(diào)用棧識(shí)別 Web API  的函數(shù),并將它們交給瀏覽器處理。一旦瀏覽器處理完成這些任務(wù),它們將返回并作為回調(diào)推到堆棧上。

你有時(shí)可能想知道,Node.js 在沒(méi)有瀏覽器幫助的情況下是如何運(yùn)行的。事實(shí)上,為 Chrome 提供動(dòng)力的 V8 引擎同樣也為 Node.js  提供動(dòng)力。

12. 使用代碼分割

如果你有使用 Google Light House 的經(jīng)驗(yàn),你就會(huì)熟悉一個(gè)叫做“first contentful  paint”的度量。它是 Lighthouse 報(bào)告的性能部分跟蹤的六個(gè)指標(biāo)之一。

First Contentful Paint(FCP)測(cè)量用戶(hù)導(dǎo)航到頁(yè)面后瀏覽器渲染 DOM 第一個(gè)內(nèi)容所花費(fèi)的時(shí)間。頁(yè)面上的圖像、非白色獲得更高 FCP 分?jǐn)?shù)的最好方法之一是使用代碼分割。代碼分割是一種在開(kāi)始時(shí)只向用戶(hù)發(fā)送必要模塊的技術(shù)。減少最初傳輸?shù)挠行?nèi)容的大小,會(huì)顯著地影響 FCP  得分。

流行的模塊打包工具(如 webpack)提供了代碼分割功能。你可以在原生 ES 模塊的幫助下,加載各個(gè)模塊。

13. 使用異步 async 和延遲 defer

在現(xiàn)代網(wǎng)站中,腳本比 HTML  更密集,它們的尺寸更大,消耗更多的處理時(shí)間。默認(rèn)情況下,瀏覽器必須等待腳本下載、執(zhí)行,然后處理頁(yè)面的其余部分。

龐大的腳本可能會(huì)阻塞網(wǎng)頁(yè)的加載。為了避免這種情況,JavaScript 提供了兩種技術(shù),即異步和延遲。你只需將這些屬性添加到  < script > 標(biāo)簽。

異步是告訴瀏覽器在不影響頁(yè)面渲染的情況下加載腳本。換句話說(shuō),頁(yè)面不需要等待異步腳本,內(nèi)容就會(huì)被處理和顯示。

延遲是在呈現(xiàn)完成后告訴瀏覽器加載腳本的地方。如果你同時(shí)指定了兩者,async 在現(xiàn)代瀏覽器中優(yōu)先執(zhí)行,而只支持 defer 但不支持 async 的舊瀏覽器將退回到 defer。

這兩個(gè)屬性可以極大地幫助你減少頁(yè)面加載時(shí)間。

14. 使用 Web Workers 在后臺(tái)運(yùn)行 CPU 密集型任務(wù)

Web Workers  允許在后臺(tái)線程中運(yùn)行腳本。如果你有一些高度密集的任務(wù),你可以將任務(wù)分配給 web workers, web workers  將運(yùn)行它們而不干擾用戶(hù)界面。創(chuàng)建之后,web worker 可以通過(guò)向 JavaScript 代碼指定的事件處理程序發(fā)送消息來(lái)與 JavaScript  代碼通信。反之亦然。

看完上述內(nèi)容,你們對(duì)十四個(gè)JavaScript的優(yōu)化代碼建議是怎樣的有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI