浅谈patch,以及里面的diff算法

前言:

从上面的几个篇章中我们介绍了从模板渲染到真实dom的全过程,现在我们来进行回顾一下:

template-------------------->AST---------------------------->渲染函数------------->vnode------------真实dom

在我们进行写代码的时候,会对里面的元素进行更新,删除,增加。

如果去操作Dom的话会进行大量的操作,速度非常的缓慢,性能也不好。

但是去操作Js对象,在操作Dom,1000次才能解决问题,操作Js对象一次就可以了。

虚拟节点本身就是一个js对象。

在这里就涉及到了Diff算法。

在第一次进行渲染的时候

将页面的所有节点挂载到页面上去,对应的页面也会有一套属于自己的虚拟dom

当页面进行更新的时候。

此时会产生一份新的虚拟DOM我们暂且称他为Vnode,原本的页面也会对应着一份oldVnode。

更新的时候,就不存在删除某个节点和添加某个节点,只是做一个更新。

   <ul>
      <li>苹果</li>
      <li>橘子</li>
      <li>香蕉</li>
    </ul>

举个例子。

view图:

假设这是上述对象的一份vnode。

const  dom={
  type:'div'
  children:{
    type:"li",
    text:'苹果'
    type:"li",
    text:'橘子'
    type:"li",
    text:'香蕉'
  }
 }

将香蕉改成西红柿。这个时候如果去操作dom进行修改极其的繁琐,只改一个节点还好,如果是100个,1000个 ,会造成性能不佳。

现在改西红柿,产生一份新的Js对象。

const  dom={
  type:'div'
  children:{
    type:"li",
    text:'苹果'
    type:"li",
    text:'橘子'
    type:"li",
    text:'西红柿'
  }
 }

此时Vnode和newVnode 会进行对比,两者肯定以新的Vnode作为最终要渲染到页面上的Vnode。

当页面进行添加的时候。

同样也会产一份新的Vnode, 和上一份oldVnode进行比较,然后进行相应的添加,最终将Vnode渲染成真实的Dom

当页面进行删除的时候。

同样也会产一份新的Vnode, 和上一份oldVnode进行比较,然后进行相应的删除,最终将Vnode渲染成真实的Dom

Diff算法。

在我们使用V-for的时候我们会去使用V-for进行渲染。

代码:

<template>
  <div class="">
    <ul>
      <li v-for="(item, index) in arr" :key="index">{
   
   { item }}</li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      arr: [1, 2, 3, 4],
    };
  },
  name: "",
  methods: {},
};
</script>

<style scoped></style>

在索引为2的位置添加数字5。

1.在无key的情况下

view图:

这显然不是我们要的最理想的结果。

给key帮上id之后就会达到最佳渲染的状态。

通过图形可以判断下方的渲染比上方少渲染了节点,提升了性能。

猜你喜欢

转载自blog.csdn.net/qq_59076775/article/details/124429340