Vue虚拟DOM理解及Diff算法(面试版)

最近准备秋招,复习之前收藏的大佬文章,决定借鉴并浓缩一下用于面试回答。

这里标注大佬原文出处:http://t.csdn.cn/4xp8k

1.什么是虚拟DOM?为什么需要虚拟DOM?

首先明确:虚拟dom就是一个普通的js对象。是一个用来描述真实dom结构的js对象,因为他不是真实dom,所以才叫虚拟dom。它的存在是为了提高渲染性能。

传统dom数据(即原生js操作数据)发生变化的时候,我们需要不断操作dom,才能更新dom的数据,相比而言严重影响渲染性能。

而虚拟dom可以很好的跟踪当前dom状态。因为他会根据当前数据生成一个描述当前dom结构的虚拟dom,当数据发生变化时,又会生成一个新的虚拟dom,这两个虚拟dom保存了变化前后的状态。然后通过diff算法,计算出两个前后两个虚拟dom之间的差异,得出一个更新的最优方法(哪些发生改变,就更新哪些),明显的提升渲染效率。

2.Diff算法

用于比较新旧两个虚拟dom之间差异的一种算法。

比较规则

  • diff 比较两个虚拟dom只会在同层级之间进行比较,不会跨层级进行比较。
  • 采用先序深度优先遍历方式进行节点比较。即当比较某个节点时,如果该节点存在子节点,那么会优先比较他的子节点,直到所有子节点全部比较完成,才会开始去比较改节点的下一个同层级节点。
  • 比较两个节点是否是相同节点,判断是否是相同节点的条件是,key和sel(选择器)
  • 如果节点相同,那么进去第二部分,即比较两个节点的属性是否相同,节点是否存在文本,文本是否相同。是否存在子节点,子节点是否相同。这部分主要在patchVnode中执行
  • 最后一部分主要在updateChildren函数中执行,主要用于比较某个节点下的子节点差异。

要搞清楚Vue虚拟dom的Diff算法,我们需要搞清楚几个核心的方法:

  • h函数   在Vue生命周期的created–>beforeMount之间将模板编译成某种格式放在render函数内 。h函数内调用了vnode函数生成虚拟dom,并返回生成结果,故虚拟dom首次生成。之后,当数据发生变化时会重新编译生成一个新vdom。
  • patch函数
  • patchVnode函数  用于比较两个相同节点的子级(文本,或子节点)的一个函数
  • updateChildren函数

patch是比较的开始,相当于是diff的入口,diff就是从这一步开始的。那么既然是开始,说明patch函数比较的肯定就是两个新旧vdom的根节点了。所以,两个vdom直接的比较,patch是只会触发一次的。

总结:

  1. 比较两个虚拟dom树,对根节点root进行执行patch(oldVnode,newVnode)函数,比较两个根节点是否是相同节点。如果不同,直接替换(新增新的,删除旧的)
  2. 如果相同,对两个节点执行patchVnode(oldVnode, newVnode),比较属性,文本,已经子节点。此时,要么新增,要么删除。要么直接修改文本内容。只有当都存在子节点时,并且oldVnode === newVnode 为false时。会执行updateChildren函数,去进一步比较他们的子节点。

本文为阅读大佬文章浓缩后为面试准备的,原文更加深入且通俗易懂,感兴趣的可以去看看大佬文章:http://t.csdn.cn/4xp8k

你可能感兴趣的:(前端面试必备,vue.js,前端)