DOM DIFF 原理解析

324 阅读2分钟
async function async1(){
    console.log('async1 start')
    await async2()
    console.log('async1 end')
}
async function async2(){
    console.log('async2')
}
console.log('script start')
setTimeout(function(){
    console.log('setTimeout') 
},0)  
async1();
new Promise(function(resolve){
    console.log('promise1')
    resolve();
}).then(function(){
    console.log('promise2')
})
console.log('script end')

背景:

现在面试极其热门的一个问题, 希望通过这个分享, 能让大家对DOM DIFF原理有一个更深入的了解

目标:

  1. 了解我们日常使用vnode的渲染原理
  2. 了解dom diff的原理, 能详细的描述其过程
  3. 结合我们的业务应用(json diff)
  4. 了解vue nextTick的原理, 能简单的描述其原理
  5. vue dom diff 和 react dom diff 的区别

dom diff简介

顾名思义, 就是虚拟道木比对(virtual dom diff), 这里简单介绍一下virtual dom的实现原理。

常见的virtual dom库snabbdom, vue的虚拟dom起始就是基于snabbdom来实现的, 不过是在其基础上做了一系列的优化, 稍后我们会介绍

github.com/snabbdom/sn…

下面以snabbdom为例简单介绍一下虚拟dom的渲染原理;

它的核心是由三个核心方法构成的:

  • render: 将虚拟dom 渲染成真实dom
  • h:把传入的参数变为虚拟dom。 虚拟dom入口方法, 用户可以调用这个方法,
  • patch:比对和更新

下面我们来简单分析一下domdiff的渲染流程

实现 h 函数

h函数接受四个参数, 第一个参数是tag, 第二个参数是props, 第三个参数是文字/子节点

起始我们就是需要把传入的参数给格式化, 转化成虚拟dom的形式

​ 这里可以简单测试一下

render函数

render函数的作用是把h函数转化成的vnode, 第一层开始, 一次递归把vnode转化成真实dom

看一下代码

核心patch函数

patch函数的作用就是比较新旧虚拟dom的差异, 做到最小量的更新。 也就是我们所说的dom diff

简单看一下流程图