面试官:你了解虚拟DOM和DIFF算法吗,简单描述一下

214 阅读3分钟

本文已参与[新人创作礼]活动,一起开启掘金创作之路

这里只是简单描述,如需详细了解请去往下方链接

juejin.cn/post/700026…

一.虚拟DOM(Virtual DOM)

1.什么是虚拟DOM

是一个用来描述真实DOM的JavaScript对象

(1)真实DOM

  <div> 
    <span>a</span>
  </div>

(2)对应的虚拟DOM

  let vnode = h('div', [
     h('span','a')
  ])

注:h函数为render函数渲染

2.为什么要使用虚拟DOM

MVVM框架解决视图和状态同步问题

模板引擎可以简化试图操作,没办法跟踪状态

虚拟DOM跟踪状态变化

virtual-dom的动机描述

(1)虚拟DOM可以维护程序的状态,跟踪上一次的状态

(2)通过比较前后两次状态差异更新真实DOM

跨平台使用

 (1)浏览器平台渲染DOM
 
 (2)服务端渲染SSR( Nuxt.js/Next.js ),前端是Vue向,后者是react向

 (3)原生应用(Weex/React Native)
 
 (4)小程序(mpvue/uni-app)
 
 真实DOM的属性很多,创建DOM节点开销大
 
 虚拟DOM只是普通的JavaScript对象,描述属性不多,创建开销小
 
 复杂视图情况下提升渲染性能(操作DOM性能消耗大,减少操作DOM的范围可节省性能)

3.使用虚拟DOM就一定比直接渲染真实DOM快吗?

不是的,为什么?

(1)慢

DOM1替换为DOM2
无论是操作真实DOM还是虚拟DOM都是创建一个DOM2替换掉DOM1,同样的结果,结果操作虚
拟DOM还要去创建虚拟DOM+DIFF算法对比,就显得很麻烦

(2)快

DOM树里的某个子节点的内容变更
一个父节点里面有多个子节点,当有一部分子节点内容发生变化时,我们就没必要重新渲染DOM树,
这时候虚拟DOM+DIFF算法去找到改变的子节点去更新它的内容即可,可在复杂视图情况下提升渲
染性能,减少DOM的操作(重绘重排)

4.虚拟DOM

Snabbdom

   Vue2内部使用的虚拟DOM就是改造的Snabbdom
   
   大约200SLOC
   
   通过模块可扩展
   
   源码使用TypeScript开发
   
   最快的Virtual DOM之一
   

virtual-dom

二.DIFF算法

1.简述

DIFF算法其实就是找出新旧两者之间的差异;

DIFF 算法首先要明确一个概念就是DIFF的对象是虚拟DOM(virtual dom),更新真实DOM是DIFF
算法的结果。

2.传统DIFF算法

传统算法查找两颗树每一个节点的差异会运行n1(dom1的节点数)的n2(dom2的节点数)次方去对比,找到差
异的部分再去更新

3.snabbdomDIFF算法优化

Snbbdom根据DOM的特点对传统的diff算法做了优化,DOM操作时候很少会跨级别操作节点,只比较同级
别的节点

4.snabbdom

 init()设置模块,创建patch()函数
 
 使用h()函数创建JavaScript对象(Vnode)描述真实DOM
 
 patch()比较新旧两个Vnode
 
 把变化的内容更新到真实DOM树

5.v-for中的key的作用

(1)DIFF操作可以更加快速,准确(避免渲染错误)

(2)不推荐使用索引作为key(Vue2)

key

使用key来给每个节点做一个唯一标识,DIFF算法就可以正确的识别此节点,找到正确的位置区插入新的节点

index

1)可变列表用indexkey容易出bug,非可变列表用indexkey可以提升性能,index作为key,只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出。

2)应将与元素唯一对应的非索引值作为key,可以最大化利用dom节点,提升性能