虚拟DOM -Virtual Dom

为什么使用Virtual Dom?
a)纯JS的东西比DOM操作快,DOM设计的很复杂
b)从总的时间成本来说,批量接口都是比多次调用单个接口的总和要节省的
c)用户操作数据,感觉是在操作DOM,达到虚拟的目的了
1.如何操作DOM
传统的直接操作DOM太慢了。比如我要在页面上实现一个如下代码:

<button id="change" onclick="changeCourse2()">数字增加</button>
    <ul id="d-list">
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <script type="text/javascript">
        var str = '';
        function getNo(){
        	var key1 = Math.floor(Math.random() * 100) + 1;
            var key2 = Math.floor(Math.random() * 100) + 1;
            var key3 = Math.floor(Math.random() * 100) + 1;
            var course = [key1, key2, key3];
            return course;
        }
        function changeCourse(){
        	var course = getNo();
            for(var i =0;i < course.length; i++){
                var li = document.createElement('li');
                li.innerHTML = course[i];
                document.getElementById('d-list').appendChild(li);
            }
        }
        function changeCourse2(){
            var course = getNo();
            for(var i =0;i < course.length; i++){
                str += '<li>' + course[i] + '</li>';
            }
            document.getElementById('d-list').innerHTML = str;
        }
    </script>

如上代码changeCourse比changeCourse2(合并操作)执行慢.
如上,还有很多类似的例子,当然操作可能不只是增加元素,有可能是替换,有可能是移动。纯js的实现比操作DOM快的多,所以React里是操作的js数据,由React进行DOM的渲染、修改,而React内部用了一系列的算法来实现最优最快的DOM操作。所以你只是提供数据,至于UI什么样由React给产生。
一般我们认为把整个DOM删了,然后根据给的数据重新生成一个DOM是最简单的操作DOM的方法,但是这样对大型视图显然是个灾难了。而Virtual DOM就是React采用的一个办法。
引入了Virtual DOM之后,React是这么干的:
你给我一个数据,我根据这个数据生成一个全新的Virtual DOM,然后跟我上一次生成的Virtual DOM去 diff,得到一个Patch,然后把这个Patch打到浏览器的DOM上去。完事。
整个流程如下:
假设在任意时候有,VirtualDom1 == DOM1 (组织结构相同)当有新数据来的时候,我生成VirtualDom2,然后去和VirtualDom1做diff,得到一个Patch。然后将这个Patch去应用到DOM1上,得到DOM2。如果一切正常,那么有VirtualDom2 == DOM2。

其实virtual Dom就是一种数据-dom结构的映射。缓存初始数据,新数据进来时,与旧数据对比,找到差异,根据差异本身的性质进行dom操作;无差异,则不作为。
React在呈现html的过程中,会首先根据render的结果将这个树状结构在js里创建出来(注意,这个时候并没有操作DOM),这个树状结构就是虚拟DOM层。这时再根据这个虚拟DOM渲染成实际DOM。如果数据变化了怎么办?React会将这个新的虚拟DOM和正在呈现的虚拟DOM进行对比,并找出其中的差异,然后用最少的DOM操作完成这个更新。
这里需要注意到,以上这些操作都是在js里完成的(生成虚拟DOM,比对),并没有实际操作DOM元素,比对完毕后找出的差异才会实际操作DOM元素,比如移除掉一个节点,更新其他节点的属性。对比angularjs,没有比对的这个过程,直接移除掉所有模板元素的DOM,再重新添加。所以angulajs会有一段时间的空白。
在vm中批量,可是在webkit渲染时也是批量吗,同时给你蹭出来10个标签?c++它还是要给循环遍及,递归生成标签对象,然后添加dom中。这种的高效是在于实现了一个真正状态机,摆脱了dom操作,伟大在于此。
参考文章:
如何理解虚拟DOM?

此条目发表在JavaScript分类目录。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。 必填项已用*标注