虚拟dom与diff算法总结| 8月更文挑战

537 阅读3分钟

这是我参与8月更文挑战的第1天,活动详情查看:8月更文挑战 p369797017.webp

在了解虚拟dom前,我们先要熟悉下浏览器解析真实DOM的流程,总的来说有下面几步:

构建dom树-构建cssom树-dom树与cssom树结合生成render树-布局-绘制

1.用HTML分析器,分析HTML元素,构建一颗DOM树

2.用CSS分析器,分析CSS文件和元素上的inline样式,生成页面的样式表

3.将DOM树和样式表,关联起来,构建一颗Render树

4.有了Render树,浏览器开始布局,为每个Render树上的节点确定一个在显示屏上出现的精确坐标

5.Render树和节点显示坐标都有了,就调用每个节点paint方法,把它们绘制出来

扩展:

重排:

当改变 DOM 元素位置或大小时,会导致浏览器重新生成渲染树,这个过程叫重排

重绘:

当重新生成渲染树后,就要将渲染树每个节点绘制到屏幕,这个过程叫重绘。不是所有的动作都会导致重排,例如改变字体颜色,只会导致重绘。记住,重排会导致重绘,重绘不会导致重排

什么操作会导致重排?

· 添加或删除可见的 DOM 元素

· 元素位置改变

· 元素尺寸改变

· 内容改变

· 浏览器窗口尺寸改变

什么操作会导致重绘?

改变visibility、outline、背景色、文字颜色等属性

从上述过程就可以知道js操作真实dom略显麻烦,而且浏览器操作真实dom是立刻执行的。每个dom节点的变化伴随着每一次的计算,造成性能上的浪费,频繁操作还会出现页面卡顿,影响用户体验。

为了节省浏览器性能,虚拟dom应运而生:

虚拟dom原理:

1. 用JavaScript模拟DOM树,并渲染这个DOM树

2. 比较新老DOM树,得到比较的差异对象

3. 把差异对象应用到渲染的DOM树

虚拟dom定义:

虚拟dom就是以javascript对象作为基础的树,用对象的属性来描述节点,并且该对象最少包含标签名( tag)、属性(attrs)和子元素对象( children)三个属性。最终可以通过一系列操作使这棵树映射到真实环境上。

虚拟dom的作用:

虚拟DOM在Vue.js主要做了两件事:

提供与真实DOM节点所对应的虚拟节点vnode

将虚拟节点vnode和旧虚拟节点oldVnode进行对比,然后更新视图

diff算法:

是一种对新旧虚拟DOM树进行比较,得出两者差异,确定最小DOM更新操作的算法。

特点:在采取diff算法比较新旧节点的时候,比较只会在同层级进行, 不会跨层级比较

998023-20180519212338609-1617459354.png

流程:

998023-20180519212357826-1474719173.png

简述:Vue中当数据发生改变时,set方法会让调用Dep.notify通知所有订阅者Watcher,订阅者就会调用patch给真实的DOM打补丁。

扩展:

vue中key值的作用: 主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。如果不使用 key, Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法 。而使用 key 时,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素