X
    Categories: js

Virtual dom 虚拟dom 真的快吗???

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