这是我参与8月更文挑战的第1天,活动详情查看:8月更文挑战
在了解虚拟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算法比较新旧节点的时候,比较只会在同层级进行, 不会跨层级比较
流程:
简述:Vue中当数据发生改变时,set方法会让调用Dep.notify通知所有订阅者Watcher,订阅者就会调用patch给真实的DOM打补丁。
扩展:
vue中key值的作用: 主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。如果不使用 key, Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法 。而使用 key 时,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素