虚拟dom-Diff算法
虚拟dom-Diff算法
vue2
diff算法在vue2中就是patch,通过新旧虚拟dom对比,找到最小变化然后进行dom操作
在页面首次渲染的时候会调用一次patch并创建新的vnode,不会进行深层次的比较,然后再组件中数据发生变化的时候,会触发setter然后通过notify通知watcher,对应的watcher会通知更新并执行更新函数,会执行render函数获取新的虚拟dom,然后执行patch对比上次渲染结果的老的dom,计算出最小的变化,根据最小的变化去更新真实的dom
什么是diff算法
diff是新旧内容之间的区别经计算,vue中的diff算法,就是通过一种简单而且高效的手段对比出新旧节点数组之间的区别以便以最小的dom操作来更新页面内容
- 对比的是vnode数组
- 同时存在新旧两组vnode数组
真实的dom节点都是树的形式存在的,根节点都是, 为了保证虚拟节点能和真实dom节点一样,vnode也采用树形结构
如果再组件更新的时候,需要对比全部vnode节点的话,新旧两组节点需要及进行深度遍历和比较,会产生很大的性能开销,所以,vue中默认同层节点比较,多余层级的内容会直接新建或者舍弃,只再同层级进行diff操作
一般来说,diff操作一般发生在v-for循环或者有v-if/v-else,component这类动态生成的节点对象上
diff算法的优化
只会对比同一层级,不会跨级比较

比较标签名
如果同一层级的比较标签名不同,旧直接移除老的虚拟节点

比较key
从标签名相同,key相同,就会被认为是相同节点,也不继续按照这个树状结果做深度比较,比如写v-for的时候会比较key,不写key就会报错

在不使用key或者列表的index作为key的时候,每个元素对应的位置关系都是index,如果没有key的话,后续的li都会重新渲染。如果使用key的话,后续会判断li3和li4没有发生变化,所以不会重新渲染。
- key的作用是为了更加搞笑的更新虚拟dom,因为可以非常精确的找到相同节点
- vue在patch过程中会判断两个节点是不是相同节点,key是一个必要条件。如果在渲染列表的时候,不写key,vue在比较的时候,导致频繁更新元素,使得整个patch比较低效
- 避免使用数组下标作为key,因为key值不是唯一的话,可能导致出现上图的bug。
- vue判断两个节点是否相同的时候需要主动判断两者的元素类型和key,如果不设置key,就可能被认为两个相同的节点,只能做更新操作,造成大量不必要的dom更新操作。
双端diff
简单diff算法: 通过暴力手段直接遍历两个数组。双端就是从两端开始分别从中间进行遍历对比的算法
- 新旧头相等
- 新旧尾相等
- 旧头等于新尾
- 旧尾等于新头
- 四者互不相等
新头旧尾

头头相等

尾尾比较

新尾旧头

循环比较

增删
循环没有找到

头头,尾尾,头尾, 尾头没有匹配到,然后循环遍历,如果循环遍历没有找到,则生成这个节点。
children内增加节点
头头

尾尾

children内减少节点

增加整个children

删除整个children

vue3
什么时候用到了diff算法
存在children的vnode类型,element类型中vnode中存在children
flagment碎片类型vnode,可以创建一个具有多个dom节点的组件的方法就是创建一个没有底层vue实例的功能组件
<template><span>1</span><span>2</span><span>3</span>
</template>
// flagment出现就是看起来像一个普通的dom元素,但是是虚拟的,不会在dom树中呈现
<Fragment><span>1</span><span>2</span><span>3</span>
</Fragment>
patchChildren根据是否存在key进行真正的diff或者直接patch
diff算法
头和头比
尾和尾比
基于最长递增子序列进行移动/添加/删除
先进行头和头比较,发现不同旧结束循环
然后进行尾和尾比较,发现不同就结束循环
在保存没有比较过的节点,并通过newIndexToOldIndexMap拿到数组里面对应的下标,生成数组,-1是老数组里没有的就是说明是新增
然后取出数组里面的最长递增子序列,
然后只需要把其他的剩余节点,基于最长子序列的位置进行移动新增和删除就可以了
比较新老children的length获取最小值,然后对于公共部分,重新进行patch工作
如果老节点数量大于新的节点数量,移除多出来的节点
如果新的节点数量大于老的节点数量,重新mountChildren新增的节点


如果老节点是否全部patch,新节点没有被patch完,创建新的vnode
如果新节点全部被patch,老节点有剩余,那么卸载所有老节点
最长子序列
这个核心,后续回写
相关文章:
虚拟dom-Diff算法
虚拟dom-Diff算法 vue2 diff算法在vue2中就是patch,通过新旧虚拟dom对比,找到最小变化然后进行dom操作 在页面首次渲染的时候会调用一次patch并创建新的vnode,不会进行深层次的比较,然后再组件中数据发生变化的时候,…...
01创建型设计模式——单例模式
一、单例模式简介 单例模式(Singleton Pattern)是一种创建型设计模式(GoF书中解释创建型设计模式:一种用来处理对象的创建过程的模式),单例模式是其中的一种,它确保一个类只有一个实例ÿ…...
图像分割(一)
一、概述 语义分割:是把每个像素都打上标签(这个像素点是人、树、背景等) 实例分割:不光要区别类别,还要区分类别中的每一个个体 损失函数:逐像素的交叉熵;样本均衡问题 MIOU指标:…...
C++ 新经典:设计模式 目录(先留框架,慢慢来~)
C 新经典:设计模式 C 新经典:设计模式 C 新经典:设计模式第1章 设计模式与软件开发思想、编程环境介绍第2章 模板方法模式第3章 工厂模式、原型模式、建造者模式第4章 策略模式第5章 观察者模式第6章 装饰模式第7章 单件模式第8章 外观模式第…...
go之命令行工具urfave-cli
一、urfave/cli urfave/cli 是一个声明性的、简单、快速且有趣的包,用于用 Go 构建命令行工具。 二、快速使用 2.1 引入依赖 go get github.com/urfave/cli/v2 2.2 demo package mainimport ("fmt""log""os""github.com/ur…...
四种应用层协议——MQTT、CoAP、WebSockets和HTTP——在工业物联网监控系统中的性能比较
目录 摘要(Abstract) 实验设置 实验结果 节选自《A Comparative Analysis of Application Layer Protocols within an Industrial Internet of Things Monitoring System》,作者是 Jurgen Aquilina、Peter Albert Xuereb、Emmanuel Francalanza、Jasmine Mallia …...
MySQL的脏读、不可重复读、幻读与隔离级别
脏读/不可重复读/幻读 脏读 脏读(Dirty Read)发生在一个事务读取了另一个事务尚未提交的数据。如果第二个事务失败并回滚,第一个事务读到的数据就是错误的。这意味着数据从一开始就是不稳定或者“脏”的。 举例 事务A读取了某条记录的值为X。事务B修改该记录的值…...
程序员前端开发者的AI绘画副业之路:在裁员危机中寻找新机遇
正文: 在这个充满变数的时代,作为一名前端开发者,我经历了行业的起伏,见证了裁员危机和中年失业危机的残酷。在这样的背景下,我开始了利用AI绘画作为副业的探索,不仅为了寻求经济上的稳定,更是为…...
Burp Suite的使用和文件上传漏洞靶场试验
第一步:分析如何利用漏洞,通过对代码的查阅发现,代码的逻辑是先上传后删除,意味着,我可以利用webshell.php文件在上传到删除之间的间隙,执行webshell.php的代码,给上级目录创建一个shell.php木马…...
如何在Ubuntu中安装deepin wine版的企业微信
如何在Ubuntu中安装deepin wine版的企业微信 运行如下一条命令将移植仓库添加到系统中 wget -O- https://deepin-wine.i-m.dev/setup.sh | sh自此以后,你可以像对待普通的软件包一样,使用apt-get系列命令进行各种应用安装、更新和卸载清理了。 安装企业…...
案例:Nginx + Tomcat集群(负载均衡 动静分离)
目录 案例 案例环境 案例步骤 部署Tomcat服务器 部署Nginx服务器 实现负载均衡和读写分离 日志控制 案例 案例环境 操作系统 IP 地址 角色 CentOS 192.168.10.101 Nginx服务器(调度器) CentOS 192.168.10.102 Tomcat服务器① CentOS 1…...
【密码学】密码协议的分类:②认证协议
密码协议的分类有很多种方式,这里我采取的是基于协议实现的目的来分类。可以将密码协议分成三类:认证协议、密钥建立协议、认证密钥建立协议。 一、认证协议是什么? 认证协议都在认证些什么东西呢?认证一般要认证三个东西&#x…...
异步编程(Promise详解)
目录 异步编程 回调函数 回调地狱 Promise 基本概念 Promise的特点 1.Promise是一种构造函数 2.Promise接收函数创建实例 3.Promise对象有三种状态 4.Promise状态转变不可逆 5.Promise 实例创建即执行 6.Promise可注册处理函数 7.Promise支持链式调用 Promise的静…...
DjangoORM注入分享
DjangoORM注入 简介 这篇文章中,分享一些关于django orm相关的技术积累和如果orm注入相关的安全问题讨论。 攻击效果同数据库注入 从Django-Orm开始 开发角度 Django ORM(Object-Relational Mapping)是Django框架中用于处理数…...
【HBZ分享】Redis各种类型的数据结构应用场景
String(字符串类型) 计数器: incr / decr, 比如商品库存,业务号的发号器业务数据key-value缓存, 缓存结果数据,提高网站性能,缓解DB压力分布式session会话, 集群环境下存储token鉴权信息分布式锁ÿ…...
anaconda创建并且配置pytorch(完整版)
📚博客主页:knighthood2001 ✨公众号:认知up吧 ** 🎃知识星球:【认知up吧|成长|副业】介绍** ❤️如遇文章付费,可先看看我公众号中是否发布免费文章❤️ 🙏笔者水平有限,欢迎各位大…...
高级java每日一道面试题-2024年8月10日-网络篇-你对跨域了解多少?
如果有遗漏,评论区告诉我进行补充 面试官: 你对跨域了解多少? 我回答: 跨域问题,即Cross-Origin Resource Sharing(CORS),是现代Web开发中一个非常重要的概念,涉及到浏览器的安全策略——同源策略(Same…...
AtCoder Beginner Contest 365 A~E
A.Leap Year(思维) 题意: 给你一个介于 1583 1583 1583和 2023 2023 2023之间的整数 Y Y Y。 求公历 Y Y Y年的天数。 在给定的范围内, Y Y Y年的天数如下: 如果 Y Y Y不是 4 4 4的倍数,则为 365 365 …...
多机部署, 负载均衡-LoadBalance
目录 1.负载均衡介绍 1.1问题描述 1.2什么是负载均衡 1.3负载均衡的一些实现 服务端负载均衡 客户端负载均衡 2.Spring Cloud LoadBalancer 2.1快速上手实现负载均衡 2.2负载均衡策略 自定义负载均衡策略 3.服务部署(Linux) 3.1服务构建打包…...
(回溯) LeetCode 78. 子集
原题链接 一. 题目描述 给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的 子集 (幂集)。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1: 输入:nums [1,2,3] 输出&…...
OpenSSL实战:从零构建私有CA体系及多级证书签发指南
1. 为什么需要私有CA体系? 在日常开发中,我们经常遇到需要HTTPS加密通信的场景。比如微服务之间的API调用、内部系统的数据传输、物联网设备的安全连接等。虽然可以使用公共CA机构颁发的证书,但在以下场景中,自建CA体系会更加灵活…...
Pixel Script Temple 企业知识库图解:将文档内容自动转化为像素示意图
Pixel Script Temple 企业知识库图解:将文档内容自动转化为像素示意图 1. 企业知识管理的痛点与机遇 技术文档和操作手册是企业知识管理的重要组成部分,但传统文档形式存在明显的可读性问题。密密麻麻的文字说明、复杂的流程图和晦涩的专业术语&#x…...
终极指南:gh_mirrors/log/log构建流程解析:从CoffeeScript到Grunt自动化
终极指南:gh_mirrors/log/log构建流程解析:从CoffeeScript到Grunt自动化 【免费下载链接】log Console.log with style. 项目地址: https://gitcode.com/gh_mirrors/log/log 如何快速构建优雅的控制台日志工具?gh_mirrors/log/log项目…...
SolveSpace:参数化 CAD 软件网页版的实验性突破
【导语:SolveSpace 作为一款参数化二维/三维 CAD 软件,推出了实验性网页版。虽存在速度损失和未解决的 bug,但处理小模型时体验不错,为 CAD 软件的使用带来新可能。】小巧 CAD 软件的网页版尝试SolveSpace 主要以普通桌面软件形式…...
掌握LiteDB.Studio:嵌入式文档数据库可视化管理工具全攻略
掌握LiteDB.Studio:嵌入式文档数据库可视化管理工具全攻略 【免费下载链接】LiteDB.Studio A GUI tool for viewing and editing documents for LiteDB v5 项目地址: https://gitcode.com/gh_mirrors/li/LiteDB.Studio 在现代软件开发中,嵌入式数…...
避开生产计划大坑:不懂MPS和MRP的区别,你的SAP PP模块白学了
避开生产计划大坑:不懂MPS和MRP的区别,你的SAP PP模块白学了 在制造业数字化转型的浪潮中,SAP PP模块作为生产计划的核心枢纽,常常成为企业运营的"隐形战场"。许多实施顾问和计划专员在MD41和MD02这两个相似的事务码前陷…...
程序替换与shell
程序替换函数execlexeclpexecvexecvpexecvpeexecle一共介绍七个函数 这里全都是以exec开头的 执行任何程序, 需要: 1.找到它 加载它(路劲加程序名) 2.怎么执行(例如ls,你想带什么选项呀,如 -l -a -d之类&a…...
PIPAL数据集实战:如何用Elo评分系统提升图像质量评估的准确性
PIPAL数据集实战:如何用Elo评分系统提升图像质量评估的准确性 在计算机视觉领域,图像质量评估(IQA)一直是算法研发的关键环节。随着生成对抗网络(GAN)等技术的突破,传统IQA方法逐渐暴露出局限性…...
DLSS状态指示器配置完全指南:实用监控工具深度解析
DLSS状态指示器配置完全指南:实用监控工具深度解析 【免费下载链接】dlss-swapper 项目地址: https://gitcode.com/GitHub_Trending/dl/dlss-swapper 在追求极致游戏体验的路上,你是否曾疑惑DLSS是否真正生效?DLSS Swapper作为一款专…...
HALCON实战:从一维码到复杂OCR,图像增强与运算的工业视觉全流程解析
1. 工业视觉检测的挑战与HALCON解决方案 在自动化产线上,产品表面的一维码、二维码和字符识别是质量控制的关键环节。我曾在某电子元件生产线遇到这样的场景:传送带以每秒3米的速度移动,产品表面既有激光刻印的微小点阵字符,又有喷…...
