什么是虚拟DOM?(vue,react)什么是diff算法?

虚拟DOM


    在这三个框架中(vue,react),都是使用虚拟DOM来提高效率的,那么来说说什么是虚拟DOM?为什么要用?还有它是怎么工作的?

什么是DOM

浏览器中的一个概念,用JS对象来表示页面上的元素,并提供用于操作DOM对象的API

DOM树

一个网页呈现的概念
网页呈现的过程:

  1. 浏览器请求服务器获取页面HTML代码
  2. 浏览器要先在内存中解析DOM结构,并在浏览器内存中渲染出一个DOM树
  3. 浏览器把DOM树呈现在页面上

为什么原生JS会浪费性能?

举个例子:
    我要更新10个DOM节点,浏览器会一个一个的进行更新,但它更新第一个的时候并不知道后面还有9个,所以会一个一个执行,共执行10次。每一次的更新都要去计算,但更新后DOM树变化了,更新第二个的时候,前一次计算的就没法再利用了,还需要再计算。白白浪费性能。

什么是虚拟DOM?

    框架中的概念,用JS对象来模拟页面上DOM和DOM之间的嵌套,本质是一个对象,而且把原生对象中的属性根据需要添加,不是全部存在,更‘轻’。

工作原理

获取内存中的(虚拟)dom树和新生成的(虚拟)dom树,通过diff算法进行对比,得到需要更新的DOM元素
这两颗(虚拟)DOM树都是框架模拟出来的,就是个对象,旧的会被保存在内存中

为什么虚拟DOM性能更优秀?

    还是要更新10个DOM节点,虚拟DOM不会一次一次的去通知浏览器,而是通过diff算法去操作框架造出来的虚拟DOM树(也就是个对象),更新对象速度会很快,然后将修改后的虚拟DOM树一次性的让浏览器进行挂载更新,减少计算的浪费。
    这么一比较,浏览器只是运作了一次,达到高效的更新渲染

什么是diff算法?

    分成三部分tree diff component diff element diff,分别去对比新旧(虚拟)dom树,DOM树中的组件,组件中的元素

tree diff
    新旧两个DOM树,逐层对比的过程,就是tree diff
    当整个DOM树逐层对比完毕,则能找到要被更新的元素
component diff
    在进行tree diff的时候,会对每一层的组件进行对比,如果新旧组件的类型相同,会进行element diff对比,如果不同,直接移除组件更新新组件
element diff
    在进行component diff对比时如果两个组件的类型相同,会对其内部的元素进行对比

总结
    在对比整个DOM树时,先对比页面中的DOM树内容是否有变化,然后对比组件是否一致,不一致的替换,一致的对比组件累的元素是否一致。有次,可以不漏下每一个元素,完成更新

但是,当循环的时候,设置key值有问题会导致diff算法对比失误,下章详解key值得作用,为什么不能使用index当key?

上一篇:git常用命令笔记


下一篇:回溯算法四:子集树、排列树以及组合优化