注:本文观点只针对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
打赏
微信扫一扫,打赏作者吧~