注:本文观点只针对web,不针对使用react等js技术开发的app,没测试这里,断不敢乱下结论!
Virtual dom 虚拟dom 真的快吗???
虚拟dom真的像说的那么美好吗???
1,先在内存中构造虚拟dom D1
2,构造变化后的虚拟dom D2
3,比较D2 D1,得到diff
4,将diff应用到原来的dom上
一切看起来都很美好,diff算法很牛逼,效率杠杠的;但是,但是,最后一句话“4,将diff应用到原来的dom上” 还是要操作dom;
下面我们就看看两种做法在web效率上的差异,一定是做了你才知道,部分代码截取,后边有完整代码演示;
1,构造原始dom数据,limit =5000,5000个dom,对其中1/3做特殊化处理
var getRandIndex=function(){
var d='div,li,span,textarea,span,h1,h2,font,ol,p'.split(',');
var num =parseInt(limit/3);
var rand={};
for(var i =0;i<num;i++){
var bc="rgba("+parseInt(Math.random()*255)+","+parseInt(Math.random()*255)+","+parseInt(Math.random()*255)+",100)";
var k=parseInt(Math.random()*limit);
rand[k]={
dom:d[parseInt(Math.random()*d.length)],
val:'II-'+k,
attr:{'data-aa':'aa-'+k,'data-bb':'bb-'+k},
style:{"border-width":"1px","background-color":bc,"border-color":bc}
};
}
return rand;
};
var olddata=getRandIndex();
2,构造差异数据(diff后的数据),对olddata处理,形成差异数据
var getNewData=function(){
var tmp=clone(olddata);
for(var k in tmp){
var bc="rgba("+parseInt(Math.random()*255)+","+parseInt(Math.random()*255)+","+parseInt(Math.random()*255)+",100)";
tmp[k].val='XX-'+k;
tmp[k].attr={'xx-data-aa':'aa-'+k,'xx-data-bb':'bb-'+k};
tmp[k].style={"background-color":bc,"border-color":bc}
}
return tmp;
};
var newdata=getNewData();
3,虚拟dom方式采用操作dom方式将diif变更
function updateVirtualDom(){
var d = new Duration("将改变应用到dom上");
d.start();
var cn=$vdom.childNodes;
for(var i in newdata){
var _dom=cn[i];
if(_dom.tagName=="INPUT"){
_dom.value=newdata[i].val;
}else{
_dom.innerHTML=newdata[i].val;
}
for(var s in newdata[i].style){
//if(styleName.indexOf(s)<0)continue;
var style_s=s;
if(s.indexOf('-')>0){
var _s=s.split('-');
style_s=_s[0]+_s[1][0].toUpperCase()+_s[1].substr(1);
}
var k='_dom.style.'+style_s+'="'+newdata[i].style[s]+'";';
eval(k);
}
for(var x in newdata[i].attr){
_dom[x]=newdata[i].attr[x];
}
}
d.end();
$vdom_info.innerText=d.getTime();
}
4,原始方式采用清空dom重建方式
function clearReCreateDom(){
var d = new Duration("清空后重建");
d.start();
var html = '';
for(var i=0;i<limit;i++){
var diy=newdata[i]?newdata[i]:{dom:"li",val:i,attr:{'data-val-i':i}};
html+=oneDom(diy);
}
$rdom.innerHTML=html;
d.end();
$rdom_info.innerText=d.getTime();
}
5,比较时间
虚拟dom耗时80~90毫秒
原始删空重建50毫秒
演示代码地址 http://vking.wang/1.0/doc/javascript/virtual-dom.html
关于演示代码中为什么使用innerHTML 而不是用new请看这里 http://vking.wang/1.0/doc/javascript/dom.html
打赏
微信扫一扫,打赏作者吧~