我們一直以來(lái)備受DOM操作低效率的困擾,直接把所有責(zé)任都推給DOM是不對(duì)的。在DOM背后還有一個(gè)和它一樣糟糕的家伙在坑效率。這家伙有時(shí)候會(huì)帶來(lái)比DOM本身更嚴(yán)重的問(wèn)題。
DOM的操作本身是同步的,代碼執(zhí)行完的同時(shí)操作也完成了,但這“完成”僅限于DOM本身。DOM操作完成只是在當(dāng)前腳本運(yùn)行所在的消息中,我們?cè)谶@里干的壞事不會(huì)立即遭報(bào)。當(dāng)這個(gè)消息結(jié)束時(shí)候,CSS重新計(jì)算我們對(duì)文檔影響的部分,如果這部分很大就需要大量的時(shí)間。我們可以做這樣的測(cè)試
運(yùn)行<script>
document.onclick=function(){
var i,t,div,body;
t=new Date;
body=document.body;
for(i=0;i<1E4;i++){
div=document.createElement("div");
body.appendChild(div);
};
console.log(new Date-t+" <- DOM操作耗時(shí)");
t=new Date;
setTimeout(function(){
console.log(new Date-t+" <- CSS渲染耗時(shí)");
});
};
</script>
這個(gè)代碼只測(cè)試了1E4個(gè)元素,可把我們的Chrome累壞了,F(xiàn)irefox和IE躲在一旁笑嘻嘻。Chrome的問(wèn)題應(yīng)該是出在它渲染引擎的某些算法上。我做了很多測(cè)試,Chrome的渲染引擎在添加元素的問(wèn)題上是指數(shù)時(shí)間復(fù)雜度,而Firefox和IE則是線性時(shí)間復(fù)雜度。所以元素的數(shù)量一多Chrome就吃不消了。但這篇文章要說(shuō)的關(guān)鍵不是Chrome渲染引擎的BUG,而是渲染本身帶來(lái)的性能開銷。我們看Chrome中對(duì)上面代碼工作的耗時(shí)分布
RecalculateStyle的耗時(shí)是很大的,這個(gè)測(cè)試還是在完全沒有用戶CSS的環(huán)境下測(cè)試的,如果我引入一個(gè)非常復(fù)雜的CSS,那么這個(gè)計(jì)算時(shí)間還得增加許多。當(dāng)然這個(gè)圖是Chrome上的,RecalculateStyle的耗時(shí)比較夸張。但是即使在Firefox和IE上,他們至少也是線性的時(shí)間復(fù)雜度。
很多文章中說(shuō)使用文檔片段(DocumentFragment)來(lái)優(yōu)化DOM操作的性能,這種說(shuō)法是建立在“DOM操作實(shí)時(shí)計(jì)算CSS”的設(shè)想上的。如果DOM操作實(shí)時(shí)計(jì)算CSS,那確實(shí)可以合并這些計(jì)算起到優(yōu)化作用。但實(shí)際上計(jì)算CSS的步驟并不在操作DOM時(shí)進(jìn)行,而是在單獨(dú)的消息中完成的,所以文檔片段在這方面不能帶來(lái)優(yōu)化。
操作DOM和計(jì)算CSS,這兩個(gè)步驟都是必不可少的。線性的時(shí)間復(fù)雜度已經(jīng)是最優(yōu)的了。如果說(shuō)可以優(yōu)化,我們只能針對(duì)Chrome的這個(gè)BUG來(lái)優(yōu)化,解決在Chrome上的問(wèn)題。如果非要對(duì)這整個(gè)問(wèn)題進(jìn)行優(yōu)化就得從問(wèn)題的根本入手,避免大規(guī)模的文檔結(jié)構(gòu)變化。
最后我只想說(shuō),讓文檔變得如此巨大的程序本身就不是好程序!
本文標(biāo)題:DOM操作的額外性能問(wèn)題
URL標(biāo)題:http://jinyejixie.com/news43/317393.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站改版、網(wǎng)站營(yíng)銷、品牌網(wǎng)站制作、動(dòng)態(tài)網(wǎng)站、電子商務(wù)、全網(wǎng)營(yíng)銷推廣
廣告
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源:
創(chuàng)新互聯(lián)