刷面试题,刷到了diff算法,其中虚拟dom仔细品了一下,记录下
首先,虚拟dom就是把网页结构变成一个对象树,其中tag、props、children 三个属性。tag代表了标签的类型,props则储存了包括id,class等标签上的属性,children则指向下级子标签。试列如下
//html
<div id="app">
<p class="text">hello world!!!</p>
</div>
//虚拟dom
{
tag: 'div',
props: {
id: 'app'
},
chidren: [
{
tag: 'p',
props: {
className: 'text'
},
chidren: [
'hello world!!!'
]
}
]
}
可以从上面看出,虚拟dom就是一个树状结构的对象,而这个对象包含了整个DOM结构的信息。
我们为什么需要虚拟dom呢?参考csdn的一篇文章(16条消息) 虚拟dom (virtual dom)(vnode)_一月清辉的博客-CSDN博客
降低浏览器性能消耗
因为Javascript的运算速度远大于DOM操作的执行速度,因此,运用patching算法来计算出真正需要更新的节点,最大限度地减少DOM操作,从而提高性能。
> **在vnode技术出现之前**,我们要改变页面展示的内容**只能通过遍历查询 dom 树**的方式找到需要修改的 dom,然后修改样式行为或者结构,来达到**更新 ui** 的目的。这种方式**相当消耗计算资源**,因为每次查询 dom 几乎都需要遍历整颗 dom树。
> **在vnode技术出现之后**,我们建立一个**虚拟 dom 对象来对应真实的 dom 树**,那么**每次 dom 的更改就变成了 js 对象的属性的更改** ,这样一来就能查找 js 对象的属性变化要比查询 dom 树的 性能开销小。
diff算法,减少回流和重绘
通过diff算法,优化遍历,对真实dom进行打补丁式的新增、修改、删除,实现局部更新,减少回流和重绘。
> vnode优化性能核心思想,就是每次**更新 dom 都尽量避免刷新整个页面**,而是有针对性的 去**刷新那被更改的一部分** ,来释放掉被无效渲染占用的 gpu,cup性能。同时,也减少了大量的dom操作,减少了浏览器的回流和重绘。
跨平台
虚拟 DOM 本质上是 JavaScript 对象,而 DOM 与平台强相关,相比之下虚拟 DOM ,可以进行更方便地跨平台操作,例如:服务器渲染、weex 开发等等
当然虚拟dom也有缺点:
首次显示要慢些:
首次渲染大量DOM时,由于多了一层虚拟DOM的计算, 会比innerHTML插入慢
-
无法进行极致优化:
虽然虚拟 DOM + 合理的优化,足以应对绝大部分应用的性能需求,但在一些性能要求极高的应用中 无法进行针对性的极致优化。那么虚拟dom的实现原理是什么?
既然知道了虚拟DOM的原理,那就不得不说diff算法,引用(16条消息) 前端框架通识:Virtual DOM(虚拟 DOM)_An_s的博客-CSDN博客