vue 核心之虚拟DOM

浏览器渲染引擎工作流程大致分为5步:

创建DOM树 —— 创建StyleRules(cssom树) —— 创建Render树 —— 布局 —— 绘制

1. 用HTML分析器,分析HTML元素,构建一颗DOM树(标记化和树构建)

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

3.将DOM树和样式表关联起来,构建一颗render树。每个dom节点都有attach方法,接受样式信息,返回一个render对象。这些对象最终会被构建成一颗render树

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

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

 

注意: 

1.DOM树的构建是文档加载完成才开始的吗?

  构建DOM树是一个渐进的过程,为达到更好的用户体验,渲染引擎会尽快将内容显示在屏幕上。它不必等到整个HTML文档解析完毕之后才开始构建render数和布局

2.Render树是DOM树和CSSOM树构建完毕才开始构建的吗?

  这三个过程在实际进行时不是完全独立,而是会有交叉。会造成一边加载,一边解析,一边渲染的工作现象

3.CSS的解析是从右往左逆向解析的

  从DOM树的下 —— 上 解析比 从上 —— 下解析效率高。 嵌套标签越多,解析越慢

4.JS操作真实DOM的代价

  传统的开发模式,利用JS或者JQ操作dom时,浏览器会从构建DOM树开始从头到尾执行一遍流程。例如,在一次操作过程中,我需要更新十次dom节点,浏览器收到第一个dom请求后并不知道还有之后的9次更新操作。因此马上执行流程,最终会执行10次。那第一次执行完毕,紧接着下一次dom更新请求,dom节点的坐标就变了,前一次计算都是无用功。计算dom节点坐标值都是白白浪费性能。即使计算机性能硬件在不断的更新升级,但是操作dom的代价仍旧是非常昂贵的,会出现页面卡顿,影响用户体验的情况。

5.引入虚拟DOM的原因,它有什么优势

  虚拟DOM就是为了解决浏览器性能问题而被设计出来的。

  第四点提到的例子,若是一次操作中有10次更新的动作,虚拟dom不会立即操作dom,而是将这十次更新的内容保存到本地一个JS对象中,最终将这个JS对象一次性attach到dom树上,再进行后续的操作,避免大量无谓的计算量。因此,页面的更新可以先全部反映在JS对象上,操作内存中的JS对象的速度显然要更快,等更新完后,再将最终的JS对象映射成真实的DOM,交给浏览器去绘制。

 

# Diff 算法

数据发生变化时,vue 是先根据真实 DOM 生成一颗 virtual DOM ,当 virtual DOM 某个节点的数据改变后会生成一个新的 Vnode ,然后 Vnode 和 oldVnode 作对比,发现有不一样的地方就直接修改在真实的 DOM 上,然后使 oldVnode 的值为 Vnode ,来实现更新节点。

        当数据发生改变时,set方法会让调用 Dep.notify 通知所有订阅者Watcher,订阅者就会调用 patch 给真实的DOM打补丁,更新相应的视图。

        (1)先做父节点同级比较,没变的话再去比较子节点,递归比较子节点
        (2)先去判断一方有子节点一方没有子节点的情况,再比较都有子节点的情况
        (3)两头往中间找
        (4)调换的内容,先把头往后移,再尾往前移,先头后尾(双指针遍历的方式)
        (5)新增节点会做旧节点的遍历,没有的话,就往上新增节点
        (6)删除操作也一样,对旧节点遍历,老的有新的没有的话就删除当前节点
        (7)平移操作会做整体的平移。

        比较时的细节:

            响应式数据更新后,触发了渲染 Watcher  的回调函数 vm._update(vm._render())去驱动视图更新
            _render() 其实生成的就是 vnode,而 vm._update 就会带着新的 vnode 去走触发 __patch__ 过程

            在进行节点比较时,是通过patch这个方法实现,其中如果不是真实元素并且用sameVnode看两个是否是同一个元素,如果是然后会调用patchVnode进行比较,比较的是虚拟节点不是真实节点,如果不值得去比较则用 Vnode 替换 oldVnode。patchVnode会比较这两个节点,判断 Vnode 和 oldVnode 是否指向同一个对象,如果是,那么直接 return,复用老的真实元素。如果不是会用新的子节点和旧的字节做比较。

 

posted @ 2023-02-01 17:44  felix的小黑屋  阅读(754)  评论(0)    收藏  举报