hgq's docs
主页
ES6-阮一峰 (opens new window)
Vue文档 (opens new window)
Axios文档 (opens new window)
Vue Router (opens new window)
Vuex文档 (opens new window)
面试题-Vue (opens new window)
面试题-JS (opens new window)

guoguoqiqi

漫不经心的向往
主页
ES6-阮一峰 (opens new window)
Vue文档 (opens new window)
Axios文档 (opens new window)
Vue Router (opens new window)
Vuex文档 (opens new window)
面试题-Vue (opens new window)
面试题-JS (opens new window)
  • Vue 生命周期
  • v-model 的原理
  • Vue 组件间通信有哪几种方式
  • v-for给每一项加个key的作用
  • v-if与v-show的区别
  • computed 和 watch 的区别
  • 对 SPA 单页面的理解,它的优缺点分别是什么
  • 为什么不建议v-if和v-for一起使用
  • Vue的内置指令
  • MVVM的理解
  • keep-alive 的了解
  • Vue身上set方法的实现原理,为什么能实现视图的更新
  • mixin的用法
  • Vuex 为什么要分模块并且加命名空间
  • vue-router 路由钩子函数是什么 执行顺序是什么
  • Vuex 页面刷新数据丢失怎么解决
  • vue-router的hash和history模式
  • vue-router 路由模式有几种
  • vue-router 中常用的 hash 和 history 路由模式实现原理
  • 动态绑定Class和Style
  • 服务端渲染SSR
  • 对Diff算法的认识
    • 对虚拟DOM的认识
    • 在组件上使用v-model
    • 路由有哪几种导航守卫
    • 在哪个生命周期内调用异步请求
    • 怎么理解Vue中的单向数据流
    • 组件中 data 为什么是一个函数
    • 通过数组下标或者长度无法触发更新
    • 路由懒加载是什么意思
    • 父组件监听子组件的生命周期
    • 父子组件生命周期钩子函数执行顺序
    • Vue项目的SEO优化
    • Vue项目的优化
    • Vue2的响应式原理的基本实现
    • Vue2和Vue3的响应式原理的区别
    • axios简单配置
    • Vuex的使用
    • 相关面试题集合
    • 对函数式组件的认识
    • Vue extend 作用和原理
    • 自定义指令的使用
    • 模板编译的原理
    • Vue是怎样进行依赖收集的
    • Vue生命周期钩子是如何实现的
    • 说明nextTick的原理
    • 请描述组件的渲染流程
    • Vue的普通Slot以及作用域Slot的区别
    • Vue use方法的作用及原理
    • Vue中的修饰符
    • Vue如何兼容ie的问题
    • Vue中style标签的scoped的作用及原理
    • Vue路由传参数
    • Vue事件绑定原理
    • 如何设计一个比较友好的Header组件
    • Vue-router守卫
    • scoped样式穿透
    • Vue是如何重写数组的方法的
    • scoped的情况下无法修改element的样式问题
    • 修改element ui的样式
    • 强制刷新组件的方式有哪些
    • vue组件的设计原则
    • 一个组件的渲染流程
    • 默认插槽、具名插槽和作用域插槽
    • Vue组件的name的作用
    • 为什么Vue被称为“渐进框架”
    • 怎么做Vue项目的SEO优化
    • vue推荐的风格指南
    • 如何重置data
    • vuex中actions和mutations有什么区别
    • 说说你对vue的错误处理的了解
    • 说一说递归组件
    • 对于vue双向数据绑定的理解
    • 说一说vue中template模板的编译过程
    • 说一说nextTick的作用
    • Vue为何采用异步渲染
    • vue-router有几种钩子函数?具体是什么及执行流程是怎样的
    • vue中mixin各个选项的合并策略
    • vue中一个组件模板为什么只能由一个根元素
    • vue中的watch和created哪个先执行
    • vue中编辑页面如果判断是否编辑过并在离开时提示保存
    • vue修饰符sync的作用及原理
    • vue中如何批量引入组件
    • vue使用axios如何取消请求
    • vue项目如何实现国际化(多语言)
    • vue中定义全局方法有哪几种方式
    • 跟keep-alive组件相关的生命周期钩子有哪些
    • 如何响应路由参数变化
    • vue中父子组件生命周期的执行顺序
    • 内置组件keep-alive的实现原理
    • mixins和extends的使用及区别
    • vue自定义指令
    • vue的事件绑定原理
    • vue权限控制一般怎么做
    • vue的动态路由怎么配置使用
    • vuex数据持久化怎么做
    • Vue
    guoguoqiqi
    2022-02-19

    对Diff算法的认识

    概念

    diff算法是一种优化手段,将前后两个模块进行差异对比,修补(更新)差异的过程叫做patch(打补丁)

    为什么vue,react这些框架中都会有diff算法呢? 我们都知道渲染真实dom的开销是很大的,这个跟性能优化中的重绘重排意义类似, 回到正题来, 有时候我们修改了页面中的某个数据,如果直接渲染到真实DOM中会引起整棵数的重绘重排, 那么我们能不能只让我们修改的数据映射到真实DOM, 做一个最少化重绘重排呢,说到这里你应该对为什么使用diff算法有一个简单的概念了

    # virtual DOM和真实DOM的区别

    一句话概括吧,virtual DOM是将真实的DOM的数据抽取出来,以对象的形式模拟树形结构, diff 算法比较的也是virtual DOM

    <div>
      <p>
        JS每日一题
      </p>
    </div>
    
    // 转换成VNode 类似于下面这种
    const Vnode = {
      tag: 'div',
      children: [
        { tag: 'p', text: 'JS每日一题' }
      ]
    };
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    # diff是怎么比较的

    简单的说就是新旧虚拟dom 的比较,如果有差异就以新的为准,然后再插入的真实的dom中,重新渲染

    特点

    • 只会做同级比较,不做跨级比较

    • 比较后几种情况

      • if(oldVnode===vnode),他们的引用一致,可以认为没有变化。

      • if(oldVnode.text!==null&&vnode.text!==null&&oldVnode.text!==vnode.text),文本节点的比较,需要修改,则会调用 Node.textContent=vnode.text。

      • if(oldCh&&ch&&oldCh!==ch), 两个节点都有子节点,而且它们不一样,这样我们会调用 updateChildren函数比较子节点,这是diff的核心

      • elseif(ch),只有新的节点有子节点,调用 createEle(vnode), vnode.el已经引用了老的dom节点, createEle函数会在老dom节点上添加子节点。

      • elseif(oldCh),新节点没有子节点,老节点有子节点,直接删除老节点。

    # key的作用

    设置key和不设置key的区别:

    不设key,newCh和oldCh只会进行头尾两端的相互比较,设key后,除了头尾两端的比较外,还会从用key生成的对象 oldKeyToIdx中查找匹配的节点,所以为节点设置key可以更高效的利用dom

    如我们希望可以在B和C之间加一个F,Diff算法默认执行起来是这样的:

    image

    即把C更新成F,D更新成C,E更新成D,最后再插入E,是不是很没有效率?

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

    image image

    所以一句话,key的作用主要是为了高效的更新虚拟DOM。 另外vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的也是为了让vue可以区分它们,否则vue只会替换其内部属性而不会触发过渡效果

    # 总结

    • 尽量不要跨层级的修改dom

    • 在开发组件时,保持稳定的 DOM 结构会有助于性能的提升

    • 设置key可以让diff更高效

    # 参考文章链接

    15 张图,20 分钟吃透 Diff 算法核心原理,我说的!!! (opens new window)
    diff 算法深入一下? (opens new window)
    深入剖析:Vue核心之虚拟DOM (opens new window)

    ← 服务端渲染SSR 对虚拟DOM的认识→

    最近更新
    01
    vuex数据持久化怎么做
    05-22
    02
    vue的动态路由怎么配置使用
    05-22
    03
    vue权限控制一般怎么做
    05-22
    更多文章>
    Theme by Vdoing | Copyright © 2022-2022 Guoquoqiqi | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式