實(shí)現(xiàn)高性能javascript的注意事項(xiàng)
1.少用全局變量
原因:因?yàn)樽饔糜蜴準(zhǔn)且粋€(gè)堆棧的結(jié)構(gòu),所以遵循先進(jìn)先出的原則,而javascript引擎在解析代碼的時(shí)候,將全局對(duì)象放在棧底,然后向上依次出現(xiàn)的是不同作用域的活動(dòng)對(duì)象(這些活動(dòng)對(duì)象除了閉包沒(méi)有相互依賴(lài)的關(guān)系),所以在查找變量的時(shí)候會(huì)從該活動(dòng)對(duì)象開(kāi)始,然后是閉包它的活動(dòng)對(duì)象,最后是全局對(duì)象,如果全局變量過(guò)多就會(huì)影響獲得變量時(shí)的速度,所以不要過(guò)多使用全局變量。
2.盡量使用局部變量封裝全局變量
原因:正如前面所說(shuō),活動(dòng)對(duì)象在棧的頂端,所以最先查找它的內(nèi)容,當(dāng)我們將document封裝成局部變量后就會(huì)減少深層次查找的次數(shù),使性能提高。
3.操作數(shù)組長(zhǎng)度、對(duì)象屬性時(shí),盡量使用局部變量封裝。
原因:IE、opera存取數(shù)組比對(duì)象屬性快,而FF chrome safari正好相反,所以兼顧這些,我們最好封裝一下。
4.盡量減少對(duì)象屬性的深度
原因:深度太大,會(huì)增加javascript引擎對(duì)取得值的地址查找的開(kāi)銷(xiāo),相當(dāng)于增加了多層嵌套的指針,導(dǎo)致性能損失。
5.在for循環(huán)中盡量使用局部變量封裝條件項(xiàng)
原因:例如for(var i=0;i<divs.length;i++) 的時(shí)候,如果divs為document.getElementsByTagName('div'),這樣在每次循環(huán)判斷條件的時(shí)候都會(huì)對(duì)DOM文檔進(jìn)行一次遍歷求得長(zhǎng)度,所以講length封裝起來(lái),會(huì)提升性能。
6.謹(jǐn)慎的處理HTMLcollection對(duì)象(比如childNodes getElementsByTagName等取得DOM元素集合的對(duì)象),最好將其封裝到數(shù)組里操作。
原因:還是因?yàn)椴僮鱀OM元素需要遍歷DOM文檔,而非DOM元素則不用遍歷,所以請(qǐng)盡量減少對(duì)DOM的操作,而將DOM集合放到數(shù)組中去。
7.在針對(duì)safari瀏覽器的開(kāi)發(fā)過(guò)程中,請(qǐng)盡量使用“.”獲取對(duì)象屬性而不是用“[]”。
8.建議在少于兩次判斷的環(huán)境下使用if-else,而大于三次的就用switch吧。而超過(guò)10次的時(shí)候,還是使用數(shù)組或json對(duì)象來(lái)通過(guò)索引來(lái)查找吧(這種模式相對(duì)簡(jiǎn)單)
9.如果循環(huán)數(shù)組的順序從低到高或從高到低沒(méi)有差別,那么還是從高到低比較好,比如我們循環(huán)輸出一個(gè)數(shù)組中的內(nèi)容:
var arr=[1,2,3,4,5]; var i=0; while(i<arr.length){ alert(arr[i]); }//這樣開(kāi)銷(xiāo)會(huì)比較大,因?yàn)槊看味家闅v求出數(shù)組元素的長(zhǎng)度 //---------------------------------- var i=arr.length; while(i--){ alert(arr[i]); }//使用局部變量保存數(shù)組長(zhǎng)度,然后該變量自減,連while中的判斷都省了,因?yàn)?轉(zhuǎn)換為布爾值就是false。
10.盡量少使用for-in循環(huán),將其盡量改造成while 或for循環(huán)。
11.處理大數(shù)組時(shí),請(qǐng)遵循duff策略。
duff策略:將大數(shù)組的個(gè)數(shù)拆分成8個(gè)一組,對(duì)這8個(gè)為一個(gè)單位的數(shù)組的操作不用循環(huán)處理,而是不怕繁瑣的寫(xiě)出8行處理數(shù)組元素的代碼,這樣會(huì)提升大數(shù)組操作的性能。
12.用函數(shù)處理大數(shù)組的每個(gè)元素時(shí),盡量使用定時(shí)器將每次操作掛起,時(shí)間設(shè)定在50-100ms比較合理
原因:如果簡(jiǎn)單的用循環(huán)來(lái)處理數(shù)組中的每個(gè)元素,如果是大數(shù)組,會(huì)造成頁(yè)面的凍結(jié)和假死,給用戶(hù)不好的體驗(yàn),而用setTimeout,就會(huì)把每次操作都暫時(shí)掛起,讓javascript引擎有其他的時(shí)間去處理隊(duì)列中的其他函數(shù),有效的防止了凍結(jié)和假死,而在設(shè)定的延遲時(shí)間之后,有可能javascript引擎是空閑的狀態(tài),可以更好的處理這些數(shù)組操作。相當(dāng)于虛擬了一個(gè)后臺(tái)操作。下面是zakas提出的解決方案:
function chunk(array,func,context){ setTimeout(function(){ var arr=array.shift(); func.call(context,item); if(array.length>0){ setTimeout(arguments.callee,100);//遞歸循環(huán)這個(gè)過(guò)程 arguments.callee為chunk這個(gè)函數(shù)對(duì)象 } },100); }
13.在使用iframe的時(shí)候注意window onload的阻塞
原因:iframe的加載會(huì)對(duì)window onload進(jìn)行阻塞,導(dǎo)致有些window unload事件中加載的代碼在用戶(hù)關(guān)掉頁(yè)面的時(shí)候可能不被執(zhí)行,所以需要我們最好在window onload時(shí)間發(fā)生時(shí)動(dòng)態(tài)為iframe設(shè)定src屬性。
PS:能不用iframe就不用。
14.CSS選擇符的優(yōu)化
原因:CSS選擇符的讀取方式為從右至左,所以在寫(xiě)的時(shí)候盡可能右邊規(guī)則詳細(xì),而且盡量少用子選擇符合后代選擇符標(biāo)簽選擇符。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
微信小程序?qū)崿F(xiàn)拉鏈?zhǔn)降幕瑒?dòng)驗(yàn)證
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)拉鏈?zhǔn)降幕瑒?dòng)驗(yàn)證,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05微信端調(diào)取相冊(cè)和攝像頭功能,實(shí)現(xiàn)圖片上傳,并上傳到服務(wù)器
這篇文章主要介紹了微信端調(diào)取相冊(cè)和攝像頭功能圖片上傳服務(wù)器,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05JavaScript高級(jí)程序設(shè)計(jì) 讀書(shū)筆記之十 本地對(duì)象Date日期
本地對(duì)象Date日期操作實(shí)現(xiàn)方法,需要的朋友可以參考下2012-02-02ES6中的class是如何實(shí)現(xiàn)的(附Babel編譯的ES5代碼詳解)
這篇文章主要介紹了ES6中的class是如何實(shí)現(xiàn)的?(附Babel編譯的ES5代碼詳解),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-05-05