20190125

Vue中的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每日一题' }]
};
diff 是如何比较的?

源码太多了,就不贴了, 有兴趣的可以自己看看 https://github.com/vuejs/vue/...

简单的说就是新旧虚拟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的核心
    • else if (ch),只有新的节点有子节点,调用createEle(vnode)vnode.el已经引用了老的dom节点,createEle函数会在老dom节点上添加子节点。
    • else if (oldCh),新节点没有子节点,老节点有子节点,直接删除老节点。
key的作用

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

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

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

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



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

总结

  • 尽量不要跨层级的修改dom
  • 在开发组件时,保持稳定的 DOM 结构会有助于性能的提升
  • 设置key可以让diff更高效

关于JS每日一题

JS每日一题可以看成是一个语音答题社区
每天利用碎片时间采用60秒内的语音形式来完成当天的考题
群主在次日0点推送当天的参考答案

  • 注 绝不仅限于完成当天任务,更多是查漏补缺,学习群内其它同学优秀的答题思路

点击加入答题

JS每日一题:Vue中的diff算法?相关推荐

  1. JS每日一题:vue中keepalive怎么理解?

    20190212问 vue中keepalive怎么理解? 说在前面: keep-alive是vue源码中实现的一个组件, 感兴趣的可以研究源码 https://github.com/vuejs/vue ...

  2. [Vue][面试]你怎么理解vue中的diff算法?

    你怎么理解vue中的diff算法? #####源码分析1:必要性,lifecycle.js–mountComponent() vue中一个组件一个watcher实例,而组件中可能存在很多个data中的 ...

  3. Vue中的Diff算法 patch函数-简单Diff算法-双端Diff算法-快速Diff算法-当数据发生改变,视图如何更新?

    文章目录 Vue中的Diff算法 概述 前置知识 patch方法 简单Diff算法 总结 双端Diff算法 --vue2 快速Diff算法 --vue3 vue2和vue3 Diff算法的区别 当数据 ...

  4. vue中的diff算法

    一.是什么diff算法 先来一句概念: diff算法就是进行虚拟节点对比,并返回一个patch对象,用来存储两个节点不同的地方,最后用patch记录的消息去局部更新Dom. 换句人话 diff的过程就 ...

  5. 【面试】以面试者的角度回答Vue中的diff算法(附图示diff运算过程)

    文章目录 面试者角度回答 图示diff运算过程 掘金同人账号:

  6. JS每日一题:new Vue()中发生了什么?

    20190214问 new Vue()中发生了什么? 先从语法上分析,new关键字在js语言中代表实例化一个对象, 而Vue实际上是一个类, 我们简单看一下源码 源码地址 https://github ...

  7. JS每日一题: 小程序页面之间如何通信?

    20190227 小程序页面之间如何通信? 首先将通信的模型列举出来, 分为以下几种 兄弟页面间通信 父路径页面向子路径页面通信 子路径页面向父路径页面通信 通信的方式 localStorage 本地 ...

  8. React中的Diff算法——Christopher Chedeau(原文翻译)

    React's diff algorithm是了解React中的Diff算法必读的文章之一,以下内容是我在阅读过程中边看边翻译的,非科班渣翻请谅解.强烈建议阅读英文原文. 原文地址: React's ...

  9. 通过几个问题深入分析Vue中的diff原理

    遇到的问题 在使用Vue渲染"可删减"的列表时,错误的使用index作为key,导致列表视图出现错乱. 点击查看问题 复现步骤:右侧有两行,在第一行的Input里输入1,在第二行I ...

最新文章

  1. LINUX动态链接库的创建与使用
  2. Spring Boot下的Tomcat,你真的会用吗?
  3. js list添加元素_JS基础与常用函数
  4. php中mysql,PHP中的mysql
  5. 工业机器人电柜布线_协作并联,重新注解并联机器人
  6. Go + Excel 学习 Excelize rows.go
  7. [Regular] 2、正则表达式基础元字符及分组、捕获
  8. 记录我开发工作中遇到HTTP跨域和OPTION请求的一个坑
  9. 深度学习之循环神经网络(4)RNN层使用方法
  10. css的z-index属性,div折腾了好久
  11. 编写脚本常用的几种语句
  12. Angularjs中设置cookies的过期时间
  13. 财务报表分析-损益表,资产负债表,现金流,回报率
  14. java用什么软件_Java编程什么软件最好用?
  15. python读取excel合并单元_python读取excel合并方法
  16. 大数据时代下的SQL Server第三方负载均衡方案----Moebius测试
  17. 实现qq的在线聊天技术
  18. 华为招聘实习生~base深圳,坂田总部
  19. ubuntu18升级/安装cmake 超详细(亲测成功,2022年7月13日)
  20. 【RNN从入门到实战】GRU入门到实战——使用GRU预测股票。

热门文章

  1. Python3 系列之 可变参数和关键字参数
  2. 英语发音规则---发/i:/的字母及字母组合
  3. React项目开发中的数据管理
  4. 20172329 2017-2018-2 《程序设计与数据结构》实验四报告
  5. Spring MVC的框架组件
  6. python--open用法
  7. Android问题-DelphiXE8安装后编译Android提示SDK无法更新问题(XE10也可以解决)
  8. ubuntu16.04 + Kdevelop + ROS开发
  9. cb-A10系统优化之(一):去除自启动软件
  10. SQL SERVER 用sql语句将一列数据拼接成一个字符串