溫馨提示×

溫馨提示×

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

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

怎么優(yōu)化JS代碼

發(fā)布時(shí)間:2021-11-18 12:03:25 來源:億速云 閱讀:156 作者:iii 欄目:web開發(fā)

這篇文章主要講解了“怎么優(yōu)化JS代碼”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“怎么優(yōu)化JS代碼”吧!

1、字符串的拼接

 字符串的拼接在我們開發(fā)中會經(jīng)常遇到,所以我把其放在首位,我們往往習(xí)慣的直接用+=的方式來拼接字符串,其實(shí)這種拼接的方式效率非常的低,我們可以用一種巧妙的方法來實(shí)現(xiàn)字符串的拼接,那就是利用數(shù)組的join方法。

<div class="one" id="one"></div>   <input type="button" value="效率低" onclick="func1()" />   <input type="button" value="效率高" onclick="func2()" />
//效率低的   function func1(){       var start = new Date().getTime();       var template = "";       for(var i = 0; i < 10000; i++){           template += "<input type='button' value='a'>";       }       var end = new Date().getTime();       document.getElementById("one").innerHTML = template;       alert("用時(shí):" + (end - start) + "毫秒");   }   //效率高的   function func2(){       var start = new Date().getTime();       var array = [];       for(var i = 0; i < 10000; i++){           array[i] = "<input type='button' value='a'>";       }       var end = new Date().getTime();       document.getElementById("one").innerHTML = array.join("");       alert("用時(shí):" + (end - start) + "毫秒");   }

我們看看其在不同瀏覽器下執(zhí)行的情況

怎么優(yōu)化JS代碼

我們會發(fā)現(xiàn),在IE6下其差別是相當(dāng)明顯的,其實(shí)這種情況在IE的高版本中體現(xiàn)的也非常明顯,但是在Firefox下卻沒有多大的區(qū)別,相反第二種的相對效率還要低點(diǎn),不過只是差別2ms左右,而Chrome也和Firefox類似。另外在這里順便說明一下,在我們給數(shù)組添加元素的時(shí)候,很多人喜歡用數(shù)組的原生的方法push,其實(shí)直接用arr[i]或者arr[arr.length]的方式要快一點(diǎn),大概在10000次循環(huán)的情況IE瀏覽器下會有十幾毫秒的差別。

2、for循環(huán)

for循環(huán)是我們經(jīng)常會遇到的情況,我們先看看下面例子:

<input type="button" value="效率低" onclick="func1()" />   <input type="button" value="效率高" onclick="func2()" />
var arr = [];   for(var i = 0; i < 10000; i++){       arr[i] = "<div>" + i + "</div>";   }   document.body.innerHTML += arr.join("");       //效率低的   function func1(){       var divs = document.getElementsByTagName("div");       var start = new Date().getTime();       for(var i = 0; i < divs.length; i++){           //"效率低"       }       var end = new Date().getTime();       alert("用時(shí):" + (end - start) + "毫秒");   }   //效率高的   function func2(){       var divs = document.getElementsByTagName("div");       var start = new Date().getTime();       for(var i = 0, len = divs.length; i < len; i++){           //"效率高"       }       var end = new Date().getTime();       alert("用時(shí):" + (end - start) + "毫秒");   }

怎么優(yōu)化JS代碼

由上表可以看出,在IE6.0下,其差別是非常明顯,而在Firefox和Chrome下幾乎沒有差別,之所以在IE6.0下會有這種情況,主要是因?yàn)閒or循環(huán)在執(zhí)行中,第一種情況會每次都計(jì)算一下長度,而第二種情況卻是在開始的時(shí)候計(jì)算長度,并把其保存到一個(gè)變量中,所以其執(zhí)行效率要高點(diǎn),所以在我們使用for循環(huán)的時(shí)候,特別是需要計(jì)算長度的情況,我們應(yīng)該開始將其保存到一個(gè)變量中。但是并不是只要是取長度都會出現(xiàn)如此明顯的差別,如果我們僅僅是操作一個(gè)數(shù)組,取得的是一個(gè)數(shù)組的長度,那么其實(shí)兩種方式的寫法都差不多,我們看下面的例子:

<input type="button" value="效率低" onclick="func1()" />   <input type="button" value="效率高" onclick="func2()" />
var arr2 = [];   for(var i = 0; i < 10000; i++){       arr2[i] = "<div>" + i + "</div>";   }   //效率低的   function func1(){       var start = new Date().getTime();       for(var i = 0; i < arr2.length; i++){           //"效率低"       }       var end = new Date().getTime();       alert("用時(shí):" + (end - start) + "毫秒");   }   //效率高的   function func2(){       var start = new Date().getTime();       for(var i = 0, len = arr2.length; i < len; i++){           //"效率高"       }       var end = new Date().getTime();       alert("用時(shí):" + (end - start) + "毫秒");   }

怎么優(yōu)化JS代碼

從上表可以看出,如果僅僅是一個(gè)數(shù)組的話,我們看到其實(shí)兩種寫法都是差不多的,其實(shí)如果我們把循環(huán)再上調(diào)到100000次的話,也僅僅是差別幾毫秒而已,所以在數(shù)組的情況下,我認(rèn)為都是一樣的。對于for循環(huán)的優(yōu)化,也有人提出很多點(diǎn),有人認(rèn)為用-=1,或者從大到小的方式循環(huán)等等,我認(rèn)為是完全沒有必要的,這些優(yōu)化往往實(shí)際情況下根本沒有表現(xiàn)出來,換句話說只是計(jì)算機(jī)級別的微小的變化,但是給我們帶來的卻是代碼的可讀性大大的降低,所以實(shí)在是得不償失。

3、減少頁面的重繪

減少頁面重繪雖然本質(zhì)不是JS本身的優(yōu)化,但是其往往是由JS引起的,而重繪的情況往往是嚴(yán)重影響頁面性能的,所以完全有必要拿出來,我們看下面例子:

<div id="demo"></div>   <input type="button" value="效率低" onclick="func1()" />   <input type="button" value="效率高" onclick="func2()" />
var str = "<div>這是一個(gè)測試字符串</div><div>這是一個(gè)測試字符串</div><div>這是一個(gè)測試字符串</div><div>這是一個(gè)測試字符串</div><div>這是一個(gè)測試字符串</div><div>這是一個(gè)測試字符串</div><div>這是一個(gè)測試字符串</div><div>這是一個(gè)測試字符串</div><div>這是一個(gè)測試字符串</div><div>這是一個(gè)測試字符串</div><div>這是一個(gè)測試字符串</div><div>這是一個(gè)測試字符串</div><div>這是一個(gè)測試字符串</div>";   //效率低的   function func1(){       var obj = document.getElementById("demo");       var start = new Date().getTime();       for(var i = 0; i < 100; i++){           obj.innerHTML += str + i;       }       var end = new Date().getTime();       alert("用時(shí) " + (end - start) + " 毫秒");   }   //效率高的   function func2(){       var obj = document.getElementById("demo");       var start = new Date().getTime();       var arr = [];       for(var i = 0; i < 100; i++){           arr[i] = str + i;       }       obj.innerHTML = arr.join("");       var end = new Date().getTime();       alert("用時(shí) " + (end - start) + " 毫秒");   }

在例子中,我只是用了100次的循環(huán),因?yàn)槿绻?0000次循環(huán)的話,瀏覽器基本上就卡住不動了,但是即使是100次的循環(huán),我們看看下面的執(zhí)行結(jié)果。

怎么優(yōu)化JS代碼

可以看到的是,這簡直是一個(gè)驚人的結(jié)果,僅僅100次的循環(huán),不管是在什么瀏覽器下,都出現(xiàn)了如此之大的差別,另外我們還發(fā)現(xiàn),在這里,IE6的執(zhí)行效率居然比起Firefox還要好很多,可見Firefox在頁面重繪這方面并沒有做一些的優(yōu)化。這里還要注意的是,一般影響頁面重繪的不僅僅是innerHTML,如果改變元素的樣式,位置等情況都會觸發(fā)頁面重繪,所以在平時(shí)一定要注意這點(diǎn)。

4、減少作用域鏈上的查找次數(shù)

我們知道,js代碼在執(zhí)行的時(shí)候,如果需要訪問一個(gè)變量或者一個(gè)函數(shù)的時(shí)候,它需要遍歷當(dāng)前執(zhí)行環(huán)境的作用域鏈,而遍歷是從這個(gè)作用域鏈的前端一級一級的向后遍歷,直到全局執(zhí)行環(huán)境,所以這里往往會出現(xiàn)一個(gè)情況,那就是如果我們需要經(jīng)常訪問全局環(huán)境的變量對象的時(shí)候,我們每次都必須在當(dāng)前作用域鏈上一級一級的遍歷,這顯然是比較耗時(shí)的,我們看下面的例子:

<div id="demo"></div>   <input id="but1" type="button" onclick="func1()" value="效率低"/>   <input id="but2" type="button" onclick="func2()" value="效率高"/>
function func1(){       var start = new Date().getTime();       for(var i = 0; i < 10000; i++){           var but1 = document.getElementById("but1");           var but2 = document.getElementById("but2");           var inputs = document.getElementsByTagName("input");           var divs = document.getElementsByTagName("div");           var but1 = document.getElementById("but1");           var but2 = document.getElementById("but2");           var inputs = document.getElementsByTagName("input");           var divs = document.getElementsByTagName("div");           var but1 = document.getElementById("but1");           var but2 = document.getElementById("but2");           var inputs = document.getElementsByTagName("input");           var divs = document.getElementsByTagName("div");           var but1 = document.getElementById("but1");           var but2 = document.getElementById("but2");           var inputs = document.getElementsByTagName("input");           var divs = document.getElementsByTagName("div");           var but1 = document.getElementById("but1");           var but2 = document.getElementById("but2");           var inputs = document.getElementsByTagName("input");           var divs = document.getElementsByTagName("div");           var but1 = document.getElementById("but1");           var but2 = document.getElementById("but2");           var inputs = document.getElementsByTagName("input");           var divs = document.getElementsByTagName("div");       }       var end = new Date().getTime();       alert("用時(shí) " + (end - start) + " 毫秒");   }   function func2(){       var start = new Date().getTime();       var doc = document;       for(var i = 0; i < 10000; i++){           var but1 = doc.getElementById("but1");           var but2 = doc.getElementById("but2");           var inputs = doc.getElementsByTagName("input");           var divs = doc.getElementsByTagName("div");           var but1 = doc.getElementById("but1");           var but2 = doc.getElementById("but2");           var inputs = doc.getElementsByTagName("input");           var divs = doc.getElementsByTagName("div");           var but1 = doc.getElementById("but1");           var but2 = doc.getElementById("but2");           var inputs = doc.getElementsByTagName("input");           var divs = doc.getElementsByTagName("div");           var but1 = doc.getElementById("but1");           var but2 = doc.getElementById("but2");           var inputs = doc.getElementsByTagName("input");           var divs = doc.getElementsByTagName("div");           var but1 = doc.getElementById("but1");           var but2 = doc.getElementById("but2");           var inputs = doc.getElementsByTagName("input");           var divs = doc.getElementsByTagName("div");           var but1 = doc.getElementById("but1");           var but2 = doc.getElementById("but2");           var inputs = doc.getElementsByTagName("input");           var divs = doc.getElementsByTagName("div");       }       var end = new Date().getTime();       alert("用時(shí) " + (end - start) + " 毫秒");   }

上面代碼中,第二種情況是先把全局對象的變量放到函數(shù)里面先保存下來,然后直接訪問這個(gè)變量,而第一種情況是每次都遍歷作用域鏈,直到全局環(huán)境,我們看到第二種情況實(shí)際上只遍歷了一次,而第一種情況卻是每次都遍歷了,所以我們看看其執(zhí)行結(jié)果:

怎么優(yōu)化JS代碼

從上表中可以看出,其在IE6下差別還是非常明顯的,而且這種差別在多級作用域鏈和多個(gè)全局變量的情況下還會表現(xiàn)的非常明顯。

5、避免雙重解釋

雙重解釋的情況也是我們經(jīng)常會碰到的,有的時(shí)候我們沒怎么考慮到這種情況會影響到效率,雙重解釋一般在我們使用eval、new Function和setTimeout等情況下會遇到,我們看看下面的例子:

<div id="demo"></div>   <input id="but1" type="button" onclick="func1()" value="效率低"/>   <input id="but2" type="button" onclick="func2()" value="效率高"/>
var sum, num1 = 1, num2 = 2;   function func1(){       var start = new Date().getTime();       for(var i = 0; i < 10000; i++){           var func = new Function("sum+=num1;num1+=num2;num2++;");           func();       }       var end = new Date().getTime();       alert("用時(shí) " + (end - start) + " 毫秒");   }       function func2(){       var start = new Date().getTime();       for(var i = 0; i < 10000; i++){           sum+=num1;           num1+=num2;           num2++;       }       var end = new Date().getTime();       alert("用時(shí) " + (end - start) + " 毫秒");   }

第一種情況我們是使用了new Function來進(jìn)行雙重解釋,而第二種是避免了雙重解釋,我們看看在不同瀏覽器下的表現(xiàn):

怎么優(yōu)化JS代碼

可以看到,在所有的瀏覽器中,雙重解釋都是有很大開銷的,所以在實(shí)際當(dāng)中要盡量避免雙重解釋。

感謝"SeaSunK"對第四點(diǎn)測試報(bào)告錯(cuò)誤的指正,現(xiàn)在已經(jīng)修改過來了。至于最后一點(diǎn)提出的func1每次都初始化,沒有可比性,所以我給換了eval,結(jié)果發(fā)現(xiàn),在IE6.0下還是有影響,而且在Firefox下,使用eval對效率的影響程度更加厲害,在Firefox下,如果10000次循環(huán),需要十多秒的時(shí)間,所以我把循環(huán)都變成了1000次??创a和報(bào)告。

var sum, num1 = 1, num2 = 2;   function func1(){       var start = new Date().getTime();       for(var i = 0; i < 1000; i++){           eval("sum+=num1;num1+=num2;num2++;");       }       var end = new Date().getTime();       alert("用時(shí) " + (end - start) + " 毫秒");   }   function func2(){       var start = new Date().getTime();       for(var i = 0; i < 1000; i++){           sum+=num1;           num1+=num2;           num2++;       }       var end = new Date().getTime();       alert("用時(shí) " + (end - start) + " 毫秒");   }

怎么優(yōu)化JS代碼

感謝各位的閱讀,以上就是“怎么優(yōu)化JS代碼”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對怎么優(yōu)化JS代碼這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!

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

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

js
AI