Vue中的diff算法

文章目录

  • diff算法是什么
  • 比较方式
  • 源码分析
    • patch
    • patchVnode
    • updateChildren
    • 小结
  • Vue3中diff算法优化

diff算法是什么

diff算法是一种通过同层的树节点进行比较的高效算法

其有两个特点:

  • 比较只会在同层级进行,不会跨层级比较
  • 在dff比较的过程中,循环从两边向中间比较(首位交叉对比

diff算法在很多场景下都有应用,在Vue中,作用于虚拟dom渲染成真实dom的新旧VNode节点比较

比较方式

diff整体策略为:深度优先,同层比较

  1. 比较只会在同层级进行,不会跨层级比较
    在这里插入图片描述
  2. 比较的过程中,循环从两边向中间收拢
    在这里插入图片描述
    下面举个vue通过diff算法更新的例子:
    新旧VNode节点如下图所示:
    在这里插入图片描述
    第一次循环后,发现旧节点D与新节点D相同,直接复用引旧节点D作为diff后的第一个真实节点,同时旧节点endIndex移动到C,新节点的startIndex移动到了C
    在这里插入图片描述
    第二次循环后,同样是旧节点的末尾和新节点的开头(都是C)相同,同理,diff后创建了C的真实节点插入到第一次创建的D节点后面。同时旧节点的endIndex移动到了B,新节点的startIndex移动到了E
    在这里插入图片描述
    第三次循环中,发现E没有找到,这时候只能直接创建新的真实节点E,插入到第二次创建的C节点之后。同时新节点的startIndex移动到了A。旧节点的startIndex和endIndex都保持不动。
    在这里插入图片描述

源码分析

当数据发生改变时,set方法会调用Dep.notify通知所有订阅者Watcher,订阅者就会调用patch给真实的DOM打补丁,更新相应的视图
源码位置:src/core/vdom/patch.js

patch

function patch(oldVnode, vnode, hydrating, removeOnly) {if (isUndef(vnode)) { // destoryif (isDef(oldVnode)) invokeDestroyHook(oldVnode)return}let isInitialPatch = falseconst insertedVnodeQueue = []if (isUndef(oldVnode)) {isInitialPatch = truecreateElm(vnode, insertedVnodeQueue) // dom} else {const isRealElement = isDef(oldVnode.nodeType)if (!isRealElement && sameVnode(oldVnode, vnode)) {// patchVnodepatchVnode(oldVnode, vnode, insertedVnodeQueue, null, null, removeOnly)} else {// domif (isRealElement) {if (oldVnode.nodeType === 1 && oldVnode.hasAttribute(SSR_ATTR)) {oldVnode.removeAttribute(SSR_ATTR)hydrating = true}if (isTrue(hydrating)) {if (hydrate(oldVnode, vnode, insertedVnodeQueue)) {invokeInsertHook(vnode, insertedVnodeQueue, true)return oldVnode}}oldVnode = emptyNodeAt(oldVnode)}return vnode.elm}}
}

patch函数前两个参数位为oldVnodeVnode,分别代表新的节点和之前的旧节点,主要做了四个判断:

  • 没有新节点,直接触发旧节点的destory钩子
  • 没有旧节点,说明是页面刚开始初始化的时候,此时,根本不需要比较了,直接全是新建,所以只调用createElm
  • 旧节点和新节点自身一样,通过sameVnode判断节点是否一样,一样时,直接调用patchVnode去处理这两个节点
  • 旧节点和新节点自身不一样,当两个节点不一样的时候,直接创建新节点,删除旧节点

patchVnode

function patchVnode(oldVnode, vnode, insertedVnodeQueue, removeOnly) {// 如果新旧节点一致,什么都不做if (oldVnode === vnode) {return

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/48976.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于神经网络的聚类分析

神经网络是一种非常有用的机器学习模型,具有无数的应用。今天,我们将分析一个数据集,看看我们是否可以通过应用无监督聚类技术来查找数据中的模式和隐藏分组,从而获得新的见解。 我们的目标是对复杂数据进行降维,以便…

mysql面试(一)

前言 从今天开始,更新一些mysql的基础知识,面试会遇到的知识点之类的内容。比如四个隔离级别,mvcc机制,三大日志,索引,B树的形成等等,从数据库的底层来剖析索引和树是怎么形成的,以…

接口自动化测试框架实战-0-项目功能概览

熟悉我CSDN的朋友们应该知道,之前已经更新了requests、pytest、allure2、yaml、jenkins、postman等基础知识的合集。相信大家对接口测试已经有了全面的认识,现在应该迫不及待地想要一个实战项目了。接下来的文章中,我们将把这些知识点串联起来…

C++学习笔记02-结构基础(问题-解答自查版)

前言 以下问题以Q&A形式记录,基本上都是笔者在初学一轮后,掌握不牢或者频繁忘记的点 Q&A的形式有助于学习过程中时刻关注自己的输入与输出关系,也适合做查漏补缺和复盘。 本文对读者可以用作自查,答案在后面&#xff0…

【Linux】HTTP 协议

目录 1. URL2. HTTP 协议2.1. HTTP 请求2.2. HTTP 响应 1. URL URL 表示着是统一资源定位符(Uniform Resource Locator), 就是 web 地址,俗称“网址”; 每个有效的 URL 可以通过互联网访问唯一的资源, 是互联网上标准资源的地址; URL 的主要由四个部分组成: sche…

学习测试10-3自动化 web自动化

web自动化 chrome驱动下载地址: https://registry.npmmirror.com/binary.html?pathchromedriver/ https://googlechromelabs.github.io/chrome-for-testing/#stable观察Google版本,下相应的驱动 运行代码试试,成功Google就会弹出 from se…

华为OD机试2024年C卷D卷 - 山脉的个数/攀登者1 (Java)

华为OD机试(C卷D卷)2024真题目录 题目描述 攀登者喜欢寻找各种地图,并且尝试攀登到最高的山峰。 地图表示为一维数组,数组的索引代表水平位置,数组的元素代表相对海拔高度。其中数组元素0代表地面。 例如&#xff…

ARM 单片机裸机任务调度框架

前言: 在没有使用操作系统的情况下,一个合理的裸机任务调度方式,可以更好的提供数据的处理,和用户体验,有多种任务调度的方式。 方案 1: 从上到下的任务调度方式,C语言程序的代码是在main函数…

K8S 上部署 Prometheus + Grafana

文章目录 一、使用 Helm 安装 Prometheus1. 配置源2. 下载 prometheus 包3. 安装 prometheus4. 卸载 二、使用 Helm 安装 Grafana1. 配置源2. 安装 grafana3. 访问4. 卸载 一、使用 Helm 安装 Prometheus 1. 配置源 地址:https://artifacthub.io/packages/helm/pro…

[路由器]IP-MAC的绑定与取消

背景:当公司的网络不想与外部人员进行共享,可以在路由器页面配置IP-MAC的绑定,让公司内部人员的手机和电脑的mac,才能接入到公司。第一步:在ARP防护中,启动IP-MAC绑定选项,必须启动仅允许IP-MAC…

linux、windows、macos清空本地DNS缓存

文章目录 Linux:Windows:macOS: Linux: 对于使用systemd的操作系统(如CentOS 7、Ubuntu 16.04),可以使用以下命令重启systemd-resolved服务来清除缓存: sudo systemctl restart sys…

【ELK】window下ELK的安装与部署

ELK的安装与部署 1. 下载2. 配置&启动2.1 elasticsarch2.1.1 生成证书2.1.2 生成秘钥2.1.3 将凭证迁移到指定目录2.1.4 改配置2.1.5 启动2.1.6 访问测试2.1.7 生成kibana账号 2.2 kibana2.2.1 改配置2.2.2 启动2.2.3 访问测试 2.3 logstash2.3.1 改配置2.3.2 启动 2.4 file…

你了解你的GD32 MCU系统主频是多少吗 ?

系统时钟是GD32 MCU的时基,可以理解为系统的心跳,片上所有的外设以及CPU最原始的时钟都来自于系统时钟,因而明确当前系统时钟是多少非常重要,只有明确了系统时钟,才能够实现准确的定时、准确的采样间隔以及准确的通信速…

通过QT基于C++实现串口通信

1.软件下载 本文所用到的所有软件都在以下连接可以下载 QT下载(注意下载路径最好全英,不要出现中文容易有bug) 链接:https://pan.baidu.com/s/1XCPlTBQ8fBOKBYO-H0mSVg?pwdm28f 提取码:m28f 串口工具下载 链接&…

二十、Qt位置相关函数

目录 一、函数概述 二、函数实践 三、总结 一、函数概述 Qt 提供了很多关于获取窗体位置及显示区域大小的函数,如 x()、y()和 pos()、react()、size()、geometry()等,统称为“位置相关函数”或“位置函数”, 如下图所示是几种主要的位置函数…

JS 鼠标拖动实现移动滚动条的滚动效果

效果 现在很多场景都以移动端为基本开发,比如说需要隐藏滚动条,在pc上实现鼠标拖动和手机触摸拖动差不多的效果。 实现 以mdn的overflow属性中范例为基础,内容溢出时候可使用overflow: auto;和overflow: scroll;实现滚动效果。 要实现鼠标…

华为防火墙总部与分支机构建立IPsec VPN涉及NAT穿越

一、IPsec VPN基本概念 1、隧道建立方式:分为手动建立和IKE自动协商,手动建立需要人为配置指定所有IPsec建立的所有参数信息,不支持为动态地址的发起方,实际网络中很少应用;IKE协议是基于密钥管理协议ISAKMP框架设计而…

一文看懂AI的 Transformer 架构!

1 AI的转换器是啥? 转换器,一种将输入序列转换或更改为输出序列的神经网络架构。它们通过学习上下文和跟踪序列组件之间的关系来做到这一点。例如,请考虑以下输入序列:“天空是什么颜色的?” 转换器模型会使用内部数学…

C4D2024软件下载+自学C4D 从入门到精通【学习视频教程全集】+【素材笔记】

软件介绍与下载: 链接: 链接:https://pan.baidu.com/s/1n8cripcv6ZTx4TBNj5N04g?pwdhfg5 提取码:hfg5 基础命令的讲解: 掌握软件界面和基础操作界面。学习常用的基础命令,如建模、材质、灯光、摄像机…

TypeScript体操(一):从基础到进阶

目录 前言Utility Types 是什么?常用 Utility Types前置知识typeofkeyoftypeof 和 keyof 的区别never 关键字extends 关键字结合条件判断infer 类型推断(模式匹配)判断是与非判断两个类型是否相等或兼容 循环递归嵌套字符串数组协变&#xff…