成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

javascript性能優(yōu)化技巧

levinit / 621人閱讀

摘要:語(yǔ)句會(huì)使得局部變量位于作用域第二層,會(huì)使性能下降,所以應(yīng)避免使用。使用事件委托來(lái)減少事件處理器的數(shù)量。把最可能出現(xiàn)的條件放在首位。在進(jìn)行優(yōu)化時(shí),要弄清楚性能瓶頸,然后對(duì)癥優(yōu)化。新看到一篇很棒的文章前端性能優(yōu)化備忘錄如有不對(duì),歡迎指正。

春節(jié)在家,把《高性能的JavaScript》刷了一遍,受益匪淺。本著每看完一本書(shū)都要做讀書(shū)筆記的習(xí)慣,將書(shū)中的知識(shí)點(diǎn)總結(jié)一下。

由于不同瀏覽器使用的JavaScript引擎不同,因此對(duì)JavaScript的優(yōu)化也不盡相同。也因此,有些方法在IE上可能性能相差很大,但在chrome上相差無(wú)幾,也甚至某些方法在IE上最快,但在chrome上卻并不是最優(yōu)的方案,所以,對(duì)性能有極致要求的應(yīng)用,應(yīng)考慮你的產(chǎn)品使用者最常用的瀏覽器。當(dāng)然,下面提到的優(yōu)化方法都是通用法則或者對(duì)大多數(shù)瀏覽器都友好的方法。

JavaScript加載和執(zhí)行

JavaScript的下載和執(zhí)行會(huì)阻塞用戶界面的繪制和其他資源的下載

優(yōu)化方法:

1.阻塞式腳本:合并文件(減少http請(qǐng)求),將script標(biāo)簽放在body尾部(減少頁(yè)面css,html的下載阻塞,減少界面的空白時(shí)間(瀏覽器在解析到script標(biāo)簽之前,不會(huì)渲染頁(yè)面的任何部分))

目前流行的構(gòu)建工具,如webpack,gulp,都有打包、合并文件的功能。

2.無(wú)阻塞式腳本:延遲腳本和動(dòng)態(tài)腳本均不阻塞,即下載過(guò)程不阻塞其他進(jìn)程

延遲腳本:
defer和async屬性:都是并行下載,下載過(guò)程不阻塞,區(qū)別在于執(zhí)行時(shí)機(jī),async是下載完成后立即執(zhí)行;defer是等頁(yè)面加載完成后再執(zhí)行。defer僅當(dāng)src屬性聲明時(shí)才生效(HTML5的規(guī)范)

動(dòng)態(tài)腳本:
動(dòng)態(tài)添加script標(biāo)簽,返回的代碼通常會(huì)立刻執(zhí)行,所以,為了確保腳本下載完成且準(zhǔn)備就緒后才執(zhí)行,須偵聽(tīng)load事件。將script添加到head中比添加到body中更保險(xiǎn)。

//動(dòng)態(tài)添加腳本,當(dāng)腳本下載完成且準(zhǔn)備就緒后執(zhí)行回調(diào)函數(shù)。(這也是推薦的無(wú)阻塞的方法)
function loadScript(url,callback){
    var script=document.creatElement("script");
    script.type="text/javascript";
    if(script.readyState){ //IE
        script.onreadystatechange=function(){
            if(script.readyState == "loaded" || script.readyState == "complete"){
                script.onreadystatechange=null;
                callback();
            }
        }
    }else{  //非IE
        script.onload=function(){
            callback();
        }
    }

    script.src=url;
    document.getElementsByTagName("head")[0].appendChild(script);

}
數(shù)據(jù)存取

將全局變量存儲(chǔ)到局部變量中:因?yàn)槿肿兞靠偸谴嬖谟趫?zhí)行環(huán)境作用域鏈的最末端,所以,訪問(wèn)全局變量是最慢的,訪問(wèn)局部變量是最快的。尤其是對(duì)于未優(yōu)化過(guò)的JavaScript引擎。

在JavaScript中,只有2個(gè)語(yǔ)句可以在執(zhí)行時(shí)臨時(shí)改變作用域鏈:with語(yǔ)句和try-catch的catch子句。with語(yǔ)句會(huì)使得局部變量位于作用域第二層,會(huì)使性能下降,所以應(yīng)避免使用。try-catch權(quán)衡使用(因?yàn)榭深A(yù)測(cè)的錯(cuò)誤說(shuō)明代碼有問(wèn)題,應(yīng)及早修復(fù))。

盡量避免使用with,try-catch,eval等動(dòng)態(tài)作用域語(yǔ)句,因?yàn)镴avaScript引擎無(wú)法通過(guò)靜態(tài)分析的方法進(jìn)行優(yōu)化。

閉包會(huì)影響性能(作用域鏈加深)和可能導(dǎo)致內(nèi)存泄漏(IE中)

總結(jié):

使用對(duì)象字面量代替對(duì)象

使用局部變量存儲(chǔ)全局變量和對(duì)象成員

盡量不用with,eval語(yǔ)句,try-catch的catch子句要謹(jǐn)慎使用

嵌套越深,性能越差,盡量少用。

DOM編程

DOM和JavaScript是2個(gè)獨(dú)立的功能,只通過(guò)API連接,用JavaScript操作DOM天生就慢,所以應(yīng)盡量減少用JavaScript操作DOM。

原則:

1.減少訪問(wèn)DOM的次數(shù),把運(yùn)算盡量留在ECMAScript這一端處理。
2.innerHTML在絕大多數(shù)瀏覽器中比原生DOM方法要快(最新版的chrome除外),推薦使用。
3.用element.cloneNode()代替document.createElement(),稍快一些。
4.緩存HTML集合的length.

//這會(huì)是一個(gè)死循環(huán),因?yàn)槿TML集合的length會(huì)重復(fù)執(zhí)行查詢的過(guò)程。
    var addDivs=document.getElementsByTagName("div");
    for(var i=0,len=addDivs.length;i

5.使用children代替childNodes,因?yàn)閏hildNodes會(huì)包含文本節(jié)點(diǎn)(空格)和注釋節(jié)點(diǎn),還需要自己額外過(guò)濾這些節(jié)點(diǎn),children已經(jīng)幫我們過(guò)濾掉這些節(jié)點(diǎn)了,而且使用的過(guò)濾方法效率很高。
6.原生選擇器API:querySelectorAll()和querySelector() ,IE8及以上支持
querySelectorAll()返回的是個(gè)nodelist(也是類數(shù)組),不是HTML集合(與getElenmentsByTagName等不同)。
7.減少重繪和重排:
在修改樣式的過(guò)程中,最好避免使用下面的屬性,因?yàn)樗鼈儠?huì)刷新渲染隊(duì)列,盡量少查詢下列屬性,可以用局部變量緩存結(jié)果。

offsetTop,offsetLeft,offsetWidth,offsetHeight,
scrollTop,scrollLeft,scrollWidth,scrollHeight
clientTop,clientLeft,clientWidth,clientHeight
getComputedStyle()  (currentStyle in IE)

8.合并多次對(duì)DOM和樣式的修改:

el.style.cssText+=";border-left:2px;";
JavaScript改變class

9.批量修改DOM時(shí),使用document fragment:文檔片段是一個(gè)輕量級(jí)的document對(duì)象,它本身就是為了更新和移動(dòng)節(jié)點(diǎn)設(shè)計(jì)的。

var fragement=document.createDocumentFragment();
var li=document.createElement("li");
fragement.appendChild(li);
document.body.appendChild(fragement);

10.動(dòng)畫(huà)中使用絕對(duì)定位,使用拖放代理。
11.使用事件委托來(lái)減少事件處理器的數(shù)量。

ps:個(gè)人覺(jué)得,原生方法和庫(kù)封裝的方法并不沖突,應(yīng)根據(jù)實(shí)際情況和個(gè)人的技能掌握情況選擇最合適的方法。

算法和流程控制

for...in的循環(huán)性能最差(因?yàn)樗枰阉鲗?shí)例和原型上的所有屬性),除非,你需要遍歷一個(gè)屬性數(shù)量未知的對(duì)象,否則不要使用它。
更不要用它遍歷數(shù)組成員。其余的循環(huán)性能都差不多。

倒序循環(huán),把減法操作放到控制條件中,例如:k--,這樣只是比較“它是true嗎?”速度更快。

forEach()比數(shù)組循環(huán)慢,如果對(duì)性能有極致要求,還是用數(shù)組循環(huán)好。

當(dāng)判斷值多于2個(gè)時(shí),使用switch,否則用if-else (數(shù)量少時(shí),性能差別不大,可根據(jù)個(gè)人喜好使用)。若判斷值很多,且沒(méi)有什么復(fù)雜的操作,可以用數(shù)組代替switch。
在JavaScript中,switch使用全等操作符,不會(huì)發(fā)生類型轉(zhuǎn)換的損耗。

把最可能出現(xiàn)的條件放在首位。

調(diào)用棧溢出錯(cuò)誤基本都是由遞歸導(dǎo)致的:不正確的終止條件;包含了太多遞歸,超過(guò)了瀏覽器的調(diào)用棧限制。把遞歸算法改用迭代算法實(shí)現(xiàn)是避免調(diào)用棧溢出錯(cuò)誤的解決方法之一。

緩存:避免重復(fù)性工作,手動(dòng)實(shí)現(xiàn)緩存(Vue源碼中就有很多緩存)

function memfactorial(n){
    if(!memfactorial.cache){
        memfactorial.cache={
            "0":1,
            "1":1
        }
    }

    if(!memfactorial.cache.hasOwnProperty(n)){
        memfactorial.cache[n]=n* memfactorial(n-1);
    }

    return memfactorial.cache[n];
  }
字符串和正則表達(dá)式

字符串拼接推薦用+ +=,推薦寫法:str=str+"one"+"two";(將str寫在左側(cè))

書(shū)上說(shuō):在大多數(shù)瀏覽器中,Array.prototype.join()比其他字符串連接方法更慢,但在IE7及早期的瀏覽器中,在合并大量字符串時(shí)是最高效的途徑。

每個(gè)瀏覽器都有它自己的正則表達(dá)式引擎,它們有著各自的優(yōu)勢(shì)。

提高正則表達(dá)式效率的方法

關(guān)注如何讓匹配更快失敗

正則表達(dá)式以簡(jiǎn)單,必需的字元開(kāi)始:例如:起始標(biāo)記是^,特定字符串,[a-z]或者d等,避免以分組或選擇字元開(kāi)頭,避免/one|two/頂層分支。

減少分支數(shù)量,縮小分支范圍:例如:將cat|bat 替換為:[cb]at ;將red|read 替換為:rea?d 將red|raw 替換為:r(?:ed|aw) 將(.|r|n)替換為:[sS]。

當(dāng)分支必不可少時(shí),將常用分支放到前面。

使用非捕獲組

合理使用捕獲:如果需要引用匹配的一部分,應(yīng)用捕獲,然后引用那部分

暴露必須的字元:用/^(ab|cd)/代替/(^ab|^cd)/

使用合適的量詞:貪婪和惰性量詞的匹配過(guò)程不一樣,視情況選擇使用。

將正則表達(dá)式賦值給變量(以避免對(duì)正則重新編譯)并重用它們。

將復(fù)雜的正則拆分為簡(jiǎn)單的片段:如果太復(fù)雜,可以先用條件判斷分割

//去除字符串首尾空格的方法,推薦寫法
if(!String.prototype.trim){    //防止覆蓋原生方法
        String.prototype.trim=function(){
            return this.replace(/^s+/,"").replace(/s+$/,"");
        }
   }

盡管正則很強(qiáng)大,但也不是任何時(shí)候都要用正則。對(duì)于字面量字符串的操作,字符串原生的方法就很快,例如:indexOf,slice,substring等。

其他

建議定時(shí)器最小延遲時(shí)間是25ms.小于10ms時(shí),各瀏覽器表現(xiàn)不一致。

多個(gè)定時(shí)器時(shí),用setInterval()代替多個(gè)setTimeout()

使用動(dòng)態(tài)腳本注入(json-p),要小心第三方域代碼的安全性。不要把敏感信息編碼在json-p中。即便是帶有隨機(jī)URL或做了cookie判斷。

圖片信標(biāo):只是用來(lái)發(fā)送簡(jiǎn)單數(shù)據(jù)

  //只是創(chuàng)建一個(gè)Image對(duì)象,并不把img插入DOM中。
(new Image()).src=url+params.join("&");

盡可能使用JOSN.parse()解析json字符串,該方法可以捕獲json字符串中的詞法錯(cuò)誤,并允許傳入一個(gè)函數(shù)用來(lái)過(guò)濾或轉(zhuǎn)換解析結(jié)果。

ajax類庫(kù)的局限:ajax類庫(kù)為了兼容瀏覽器,所以不能訪問(wèn)XMLHttpRequests的完整功能。例如不能直接訪問(wèn)readystatechange事件,所以要了解原生的寫法。
所以,要知道何時(shí)使用成熟的類庫(kù),何時(shí)編寫自己的底層代碼。

縮短頁(yè)面的加載時(shí)間,頁(yè)面主要內(nèi)容加載完成后,再用ajax獲取那些次要的文件。(首頁(yè)優(yōu)化)

通過(guò)正確設(shè)置響應(yīng)頭來(lái)緩存JavaScript文件。

使用位操作,速度快。

    i%2   
    //可以改寫成位運(yùn)算 &1 :
    if(i&1){ 
        //奇數(shù)
    }else{ 
        //偶數(shù)
    }
    //位掩碼:后臺(tái)常用的按位打標(biāo),
    var ops=op_a | op_b | op_c;  
    if(ops & op_a){ 
        //op_a存在
    }
個(gè)人感想

性能提升有多方面:客戶端性能,網(wǎng)絡(luò)情況,服務(wù)器性能,在具體解決及分析問(wèn)題時(shí),要從各個(gè)方面考慮,JavaScript代碼質(zhì)量,http請(qǐng)求數(shù)也只是其中一部分而已,要全面考慮。在進(jìn)行優(yōu)化時(shí),要弄清楚性能瓶頸,然后對(duì)癥優(yōu)化。

新看到一篇很棒的文章:
前端性能優(yōu)化備忘錄:https://www.w3ctech.com/topic...

ps:如有不對(duì),歡迎指正。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/81436.html

相關(guān)文章

  • 前端資源系列(4)-前端學(xué)習(xí)資源分享&前端面試資源匯總

    摘要:特意對(duì)前端學(xué)習(xí)資源做一個(gè)匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 特意對(duì)前端學(xué)習(xí)資源做一個(gè)匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 本以為自己收藏的站點(diǎn)多,可以很快搞定,沒(méi)想到一入?yún)R總深似海。還有很多不足&遺漏的地方,歡迎補(bǔ)充。有錯(cuò)誤的地方,還請(qǐng)斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應(yīng)和斧正,會(huì)及時(shí)更新,平時(shí)業(yè)務(wù)工作時(shí)也會(huì)不定期更...

    princekin 評(píng)論0 收藏0
  • 2017文章總結(jié)

    摘要:歡迎來(lái)我的個(gè)人站點(diǎn)性能優(yōu)化其他優(yōu)化瀏覽器關(guān)鍵渲染路徑開(kāi)啟性能優(yōu)化之旅高性能滾動(dòng)及頁(yè)面渲染優(yōu)化理論寫法對(duì)壓縮率的影響唯快不破應(yīng)用的個(gè)優(yōu)化步驟進(jìn)階鵝廠大神用直出實(shí)現(xiàn)網(wǎng)頁(yè)瞬開(kāi)緩存網(wǎng)頁(yè)性能管理詳解寫給后端程序員的緩存原理介紹年底補(bǔ)課緩存機(jī)制優(yōu)化動(dòng) 歡迎來(lái)我的個(gè)人站點(diǎn) 性能優(yōu)化 其他 優(yōu)化瀏覽器關(guān)鍵渲染路徑 - 開(kāi)啟性能優(yōu)化之旅 高性能滾動(dòng) scroll 及頁(yè)面渲染優(yōu)化 理論 | HTML寫法...

    dailybird 評(píng)論0 收藏0
  • 2017文章總結(jié)

    摘要:歡迎來(lái)我的個(gè)人站點(diǎn)性能優(yōu)化其他優(yōu)化瀏覽器關(guān)鍵渲染路徑開(kāi)啟性能優(yōu)化之旅高性能滾動(dòng)及頁(yè)面渲染優(yōu)化理論寫法對(duì)壓縮率的影響唯快不破應(yīng)用的個(gè)優(yōu)化步驟進(jìn)階鵝廠大神用直出實(shí)現(xiàn)網(wǎng)頁(yè)瞬開(kāi)緩存網(wǎng)頁(yè)性能管理詳解寫給后端程序員的緩存原理介紹年底補(bǔ)課緩存機(jī)制優(yōu)化動(dòng) 歡迎來(lái)我的個(gè)人站點(diǎn) 性能優(yōu)化 其他 優(yōu)化瀏覽器關(guān)鍵渲染路徑 - 開(kāi)啟性能優(yōu)化之旅 高性能滾動(dòng) scroll 及頁(yè)面渲染優(yōu)化 理論 | HTML寫法...

    hellowoody 評(píng)論0 收藏0
  • 2017文章總結(jié)

    摘要:歡迎來(lái)我的個(gè)人站點(diǎn)性能優(yōu)化其他優(yōu)化瀏覽器關(guān)鍵渲染路徑開(kāi)啟性能優(yōu)化之旅高性能滾動(dòng)及頁(yè)面渲染優(yōu)化理論寫法對(duì)壓縮率的影響唯快不破應(yīng)用的個(gè)優(yōu)化步驟進(jìn)階鵝廠大神用直出實(shí)現(xiàn)網(wǎng)頁(yè)瞬開(kāi)緩存網(wǎng)頁(yè)性能管理詳解寫給后端程序員的緩存原理介紹年底補(bǔ)課緩存機(jī)制優(yōu)化動(dòng) 歡迎來(lái)我的個(gè)人站點(diǎn) 性能優(yōu)化 其他 優(yōu)化瀏覽器關(guān)鍵渲染路徑 - 開(kāi)啟性能優(yōu)化之旅 高性能滾動(dòng) scroll 及頁(yè)面渲染優(yōu)化 理論 | HTML寫法...

    wwolf 評(píng)論0 收藏0
  • JavaScript 性能優(yōu)化技巧分享

    摘要:即使這些動(dòng)畫(huà)庫(kù)使用轉(zhuǎn)換,合成屬性和,但是它們?nèi)匀贿\(yùn)行在的主線程上。另一方面,動(dòng)畫(huà)和轉(zhuǎn)換會(huì)在主線程中運(yùn)行,如果能夠高效執(zhí)行,則能避免重新布局重排的情況出現(xiàn)。是一個(gè)即將到來(lái)的功能集,它能夠脫離主線程執(zhí)行高性能的動(dòng)畫(huà)。 JavaScript 作為當(dāng)前最為常見(jiàn)的直譯式腳本語(yǔ)言,已經(jīng)廣泛應(yīng)用于 Web 應(yīng)用開(kāi)發(fā)中。為了提高Web應(yīng)用的性能,從 JavaScript 的性能優(yōu)化方向入手,會(huì)是一個(gè)很...

    shixinzhang 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<