利用虚拟DOM能够提高页面的渲染效率,目前流行的前端框架React和Vue都引用了虚拟DOM。下面整理了一下关于虚拟DOM的相关内容
关于DOM
DOM(Document Object Modal)文档对象模型就是页面上的元素节点。
原生JS是命令式的开发,如果需要改变DOM只能一步步的对DOM进行增删改查,可能很多代码都在操作DOM。
React是声明式开发。它有响应式的设计,定义好数据和模板,React会自动渲染DOM,只需要改变数据它就会帮我们改变DOM。
虚拟DOM
Virtual DOM 本质上是Javascript对象,是对真实DOM的一种描述方式。是JS对象模拟的DOM结构,将DOM变化的对比放在JS层来做。
React可以自动渲染出DOM结构,但是当数据改变时,React就会重新渲染DOM,JS对DOM的操作很消耗性能的,如果只改了一小部分的数据就要重新渲染整个DOM树,在性能上是极大的浪费。所以React引入了虚拟DOM的概念。
虚拟DOM是JS中的一个对象,是根据数据和模板生成的对象,包含了整个DOM结构。
1 | ['div', {id: "id"}, ['p', {class: 'description', 'hello world'}]] |
上面代码就相当于一个虚拟的DOM,div里面有个p标签,p标签里面写了hello world,当然也包含元素上的各个属性 。
有了虚拟DOM后,当我们改变数据,React会根据当前的数据和模板生成一个虚拟DOM,然后和上一次生成的虚拟DOM进行比对,找出差异,然后根据差异对DOM进行渲染,当然它不会重新渲染,只会渲染被改变的部分。而虚拟DOM只是JS里面的一个对象,JS对对象的操作是非常快的。所以这种方式极大的提高了性能。
虚拟dom中的diff算法
React中Diff算法运用在比较原始虚拟DOM和新的虚拟DOM的比对中。两个虚拟DOM的对比就叫Difference算法,大大提高了效果。当调用setState()的时候,就会发生虚拟DOM的对比。setState()是异步函数。
为什么给dom的key值赋值时候,不建议使用index?
循环遍历DOM的时候要给DOM设置一个key值,就相当于给每个dom起了一个名字。在做虚拟dom对比的时候,我们只需要按名字对比,不需要通过dom内容现找到对应的dom再进行对比,这样就节省了新能。index不具备稳定性,当你删除某一个dom后,可能你整个dom树的key值都会发生变化。使用dom的内容去做key,内容改变时对应的dom就需要重新渲染。
为什么使用虚拟DOM
虚拟DOM最大的特点是将页面的状态抽象为 JS 对象的形式,配合不同的渲染工具,使跨平台渲染成为可能。如 React 就借助 虚拟DOM 实现了服务端渲染、浏览器渲染和移动端渲染等功能。
在进行页面更新的时候,借助虚拟DOM,DOM 元素的改变可以在内存中进行比较,再结合框架的事务机制将多次比较的结果合并后一次性更新到页面,从而有效地减少页面渲染的次数,提高渲染效率。