Dom树
-
浏览器收到一个html页面是如何解析成页面呈现给用户
- 浏览器使用html解析器解析html,解析后构建dom树,也可能是边解析边沟检查
- css解析器解析css生成样式表
- 构建render树(渲染树、呈现树),也就是解析生成样式表将样式应用到dom节点上
- 布局,通过计算将每一个dom节点精确呈现在屏幕上的相应位置
- 绘制render树在屏幕上
-
为什么操作真实DOM的成本比较高?
- dom 树的实现模块和 js 模块是分开的这些跨模块的通讯增加了成本
- dom 操作引起的浏览器的重排和重绘,使得性能开销巨大。原本在 pc 端是没有性能问题的,因为pc端的计算能力强,但是随着移动端的发展,越来越多的网页在智能手机上运行,而手机的性能参差不齐,会有性能问题。我们之前用jquery在pc端写那些商城页面都没有问题,但放到移动端浏览器访问之后会发现除了首页会出现白屏之外在其他页的操作并不流畅。
-
什么是回流和重绘?
- 回流 reflow(重排):当呈现树renderTree中的一部分或全部因为尺寸、布局、隐藏等改变改重新构建,称之为回流。
- 重绘:当呈现树renderTree中的一部分元素需要更新属性,而属性只会影响外观、风格而不影响布局,比如颜色、字体大小等,则称之为重绘。重绘的历史
-
虚拟dom和真实dom的区别?
- 虚拟dom不会进行重排和重绘
- 虚拟dom大大提高了真实dom处理的效率和浏览器的效率,即减少了真实dom重排和重绘的次数
-
虚拟dom是如何更新真实dom的
- 虚拟dom树的节点被改变时,会生成一颗新的虚拟dom树,diff算法会计算出被改变的部分
- 根据被改变的部分更新真实DOM
-
Diff算法
-
三种策略,顺序执行:Tree diff、Component Diff、Element Diff
-
Tree Diff:对树的每一层进行遍历,找出不同的,只会同层比较
-
Component Diff:
- 如果都是同一类型的组件(即:两节点是同一个组件类的两个不同实例,比如: 与 ),按照原策略继续比较Virtual DOM树即可
- 如果出现不是同一类型的组件,则将该组件判断为dirty component,从而替换整个组件下的所有子节点
-
Element Diff:
-
当节点处于同一层级时,diff 提供三种节点操作:
INSERT_MARKUP(插入):如果新的组件类型不在旧集合里,即全新的节点,需要对新节点执行插入操作。
MOVE_EXISTING (移动):旧集合中有新组件类型,且 element 是可更新的类型,generatorComponentChildren 已调用 receiveComponent,这种情况下 prevChild=nextChild,就需要做移动操作,可以复用以前的 DOM 节点。
REMOVE_NODE (删除):旧组件类型,在新集合里也有,但对应的 elememt 不同则不能直接复用和更新,需要执行删除
-
-