深入Vue2 Diff算法

一文读懂《Vue2 Diff算法》 diff 算法是用于比较两颗虚拟 DOM 树的差异,并生成最小化 DOM 操作指令的算法。它的核心目标是高效更新视图,避免全量渲染的性能浪费。虚拟 DOM:用 Javascript 对象来描述真实 DOM 结构(如 Vue 中的 VNode)diff 算法是一种对比虚拟 DOM 树的差异,计算最小 DOM 更新步骤的算法。diff 算法只在同层级比较,不跨层级比较diff 算法过程中,先使用头尾双指针进行两端对比,再配合查找复用法匹配节点diff 算法中的key。 阅读详情

作者简介:汪玉林,高级工程师,增值产品部前端Leader,目前团队负责手Q游戏中心、手Q游戏运营、手Q阅读等项目,有丰富的Web前端架构经验。

一、前言

Vue的核心是双向绑定和虚拟DOM(下文我们简称为vdom),关于双向绑定可以参阅木琴的文章《剖析Vue原理&实现双向绑定MVVM》,vdom是树状结构,其节点为vnode,vnode和浏览器DOM中的Node一一对应,通过vnode的elm属性可以访问到对应的Node。

vdom因为是纯粹的JS对象,所以操作它会很高效,但是vdom的变更最终会转换成DOM操作,为了实现高效的DOM操作,一套高效的虚拟DOM diff算法显得很有必要。

Vue的diff算法是基于snabbdom改造过来的,感兴趣的朋友可以选择查阅。

在这里插入图片描述

这是一张很经典的图,出自《React’s diff algorithm》,Vue的diff算法也同样,即仅在同级的vnode间做diff,递归地进行同级vnode的diff,最终实现整个DOM树的更新。那同级vnode diff的细节又是怎样的呢?正是本文所要讲的。

二、例子

我们在下文中将使用这个简化的例子来讲述diff的过程

在这里插入图片描述

如上图的例子,更新前是1到10排列的Node列表,更新后是乱序排列的Node列表。罗列一下图中有以下几种类型的节点变化情况:

(1)、头部相同、尾部相同的节点:如1、10

(2)、头尾相同的节点:如2、9(处理完头部相同、尾部相同节点之后)

(3)、新增的节点:11

(4)、删除的节点:8

(5)、其他节点:3、4、5、6、7

三、简单的diff

简单的diff算法可以这样设计:

逐个遍历newVdom的节点,找到它在oldVdom中的位置,如果找到了就移动对应的DOM元素,如果没找到说明是新增节点,则新建一个节点插入。遍历完成之后如果oldVdom中还有没处理过的节点,则说明这些节点在newVdom中被删除了,删除它们即可。

仔细思考一下,几乎每一步都要做移动DOM的操作,这在DOM整体结构变化不大时的开销是很大的,实际上DOM变化不大的情况现实中经常发生,很多时候我们只需要变更某个节点的文本而已。

接下来我们看一下Vue的diff实现

四、Vue的diff实现

上图例子中我画上了oldStart+oldEnd,newStart+newEnd这样2对指针,分别对应oldVdom和newVdom的起点和终点。起止点之前的节点是待处理的节点,Vue不断对vnode进行处理同时移动指针直到其中任意一对起点和终点相遇。处理过的节点Vue会在oldVdom和newVdom中同时将它标记为已处理(标记方法后文中有介绍)。Vue通过以下措施来提升diff的性能。

(一)、优先处理特殊场景

(1)、头部的同类型节点、尾部的同类型节点

这类节点更新前后位置没有发生变化,所以不用移动它们对应的DOM

(2)、头尾/尾头的同类型节点

这类节点位置很明确,不需要再花心思查找,直接移动DOM就好

处理了这些场景之后,一方面一些不需要做移动的DOM得到快速处理,另一方面待处理节点变少,缩小了后续操作的处理范围,性能也得到提升

(二)、“原地复用”
“原地复用”是指Vue会尽可能复用DOM,尽可能不发生DOM的移动。**Vue在判断更新前后指针是否指向同一个节点,其实不要求它们真实引用同一个DOM节点,实际上它仅判断指向的是否是同类节点(比如2个不同的div,在DOM上它们是不一样的,但是它们属于同类节点),如果是同类节点,那么Vue会直接复用DOM,这样的好处是不需要移动DOM。**再看上面的实例,假如10个节点都是div,那么整个diff过程中就没有移动DOM的操作了。

“原地复用”在Vue的官方文档中有提到,虽然带来了好处,但是也会产生一些问题,朋友们可以复习一下

https://cn.vuejs.org/v2/guide/list.html#key

https://cn.vuejs.org/v2/guide/conditional.html#用-key-管理可复用的元素

五、按步解剖实例

(一)、整体视图
在这里插入图片描述

先看一张整体视图,整个diff分两部分:

(1)、第一部分是一个循环,循环内部是一个分支逻辑,每次循环只会进入其中的一个分支,每次循环会处理一个节点,处理之后将节点标记为已处理(oldVdom和newVdom都要进行标记,如果节点只出现在其中某一个vdom中,则另一个vdom中不需要进行标记),标记的方法有2种,当节点正好在vdom的指针处,移动指针将它排除到未处理列表之外即可,否则就要采用其他方法,Vue的做法是将节点设置为undefined。

(2)、循环结束之后,可能newVdom或者oldVdom中还有未处理的节点,如果是newVdom中有未处理节点,则这些节点是新增节点,做新增处理。如果是oldVdom中有这类节点,则这些是需要删除的节点,相应在DOM树中删除之

整个过程是逐步找到更新前后vdom的差异,然后将差异反应到DOM树上(也就是patch),特别要提一下Vue的patch是即时的,并不是打包所有修改最后一起操作DOM(React则是将更新放入队列后集中处理),朋友们会问这样做性能很差吧?实际上现代浏览器对这样的DOM操作做了优化,并无差别。

(二)、逐步解析

(1)、处理头部的同类型节点,即oldStart和newStart指向同类节点的情况,如下图中的节点1

这种情况下,将节点1的变更更新到DOM,然后对其进行标记,标记方法是oldStart和newStart后移1位即可,过程中不需要移动DOM(更新DOM或许是要的,比如属性变更了,文本内容变更了等等)

在这里插入图片描述

(2)、处理尾部的同类型节点,即oldEnd和newEnd指向同类节点的情况,如下图中的节点10

与情况(1)类似,这种情况下,将节点10的变更更新到DOM,然后oldEnd和newEnd前移1位进行标记,同样也不需要移动DOM

在这里插入图片描述

(3)、处理头尾/尾头的同类型节点,即oldStart和newEnd,以及oldEnd和newStart指向同类节点的情况,如下图中的节点2和节点9

先看节点2,其实是往后移了,移到哪里?移到oldEnd指向的节点(即节点9)后面,移动之后标记该节点,将oldStart后移1位,newEnd前移一位

在这里插入图片描述

操作结束之后情况如下图

在这里插入图片描述

同样地,节点9也是类似的处理,处理完之后成了下面这样

在这里插入图片描述

(4)、处理新增的节点

newStart来到了节点11的位置,在oldVdom中找不到节点11,说明它是新增的

那么就创建一个新的节点,插入DOM树,插到什么位置?插到oldStart指向的节点(即节点3)前面,然后将newStart后移1位标记为已处理(注意oldVdom中没有节点11,所以标记过程中它的指针不需要移动),处理之后如下图

在这里插入图片描述

(5)、处理更新的节点

经过第(4)步之后,newStart来到了节点7的位置,在oldVdom中能找到它而且不在指针位置(查找oldVdom中oldStart到oldEnd区间内的节点),说明它的位置移动了

那么需要在DOM树中移动它,移到哪里?移到oldStart指向的节点(即节点3)前面,与此同时将节点标记为已处理,跟前面几种情况有点不同,newVdom中该节点在指针下,可以移动newStart进行标记,而在oldVdom中该节点不在指针处,所以采用设置为undefined的方式来标记(一定要标记吗?后面会提到)

在这里插入图片描述

处理之后就成了下面这样

在这里插入图片描述

(6)、处理3、4、5、6节点

经过第(5)步处理之后,我们看到了令人欣慰的一幕,newStart和oldStart又指向了同一个节点(即都指向节点3),很简单,按照(1)中的做法只需移动指针即可,非常高效,3、4、5、6都如此处理,处理完之后如下图

在这里插入图片描述

(7)、处理需删除的节点

经过前6步处理之后(实际上前6步是循环进行的),朋友们看newStart跨过了newEnd,它们相遇啦!而这个时候,oldStart和oldEnd还没有相遇,说明这2个指针之间的节点(包括它们指向的节点,即上图中的节点7、节点8)是此次更新中被删掉的节点。

OK,那我们在DOM树中将它们删除,再回到前面我们对节点7做了标记,为什么标记是必需的?标记的目的是告诉Vue它已经处理过了,是需要出现在新DOM中的节点,不要删除它,所以在这里只需删除节点8。
在应用中也可能会遇到oldVdom的起止点相遇了,但是newVdom的起止点没有相遇的情况,这个时候需要对newVdom中的未处理节点进行处理,这类节点属于更新中被加入的节点,需要将他们插入到DOM树中。

在这里插入图片描述

至此,整个diff过程结束了

Vue的diff算法与动态规划算法中的经典案例“计算a到b的最小编辑距离”看上去有些相似,实际完全不同,Vue的diff相对来说轻量很多,感兴趣的朋友可以查阅相关资料进行了解。

好啦,感谢你的阅读,希望能帮助你理解Vue的diff算法,在阅读过程中遇到的问题也欢迎一起交流!

Vue2.x-虚拟DOM和diff算法(笔记) 虚拟DOM和diff算法虚拟DOM和diff算法简述snabbdom简介安装测试环境搭建虚拟 DOM 和 h 函数虚拟 DOMh 函数基本使用嵌套使用手写 h 函数diff 算法例子diff 处理新旧节点不是同一个节点时diff 处理新旧节点是同一个节点时手写新旧节点text的不同情况尝试书写 diff 更新子节点diff 算法的子节点更新策略手写子节点更新策略 虚拟DOM和diff算法 简述 diff 算法 以装修房子为例,如果我们仅需要在客厅新添一座沙发或者将卧室的床换个位置。那么将整个房子重新 阅读详情

相关推荐

Vue2和vue3diff算法

目录 一、是什么 二、比较方式 三、原理分析 小结 一、是什么 diff算法是一种通过同层的树节点进行比较的高效算法 其有两个特点: 比较只会在同层级进行, 不会跨层级比较 在diff比较的过程中,循环从两边向中间比较 diff算法的在很多场景下都有应用,在vue中,作用于虚拟dom渲染成真实dom的新旧VNode节点比较 二、比较方式 diff整体策略为:深度优先,同层比较 比较只会在同层级进行, 不会跨层级比较 比较的过程中,循......

高山景行,一尘不染 1578

Vue2 Diff算法总结(图文结合)

Vue2 Diff算法

weixin_42125732的博客 1688

Pintos project 1 实验报告(代码分享)

任务一 Alarm Clock 用到的相干目录有: pintos/src/devices time.h && time.c pintos/src/threads thread.h && thread.c 预期pass希望:暂无,安装pintos之后,第一次对threads进行make check操作,可以发现以alarm--开头的前六个文件,以及mlfqs-fair-2和mlfqs-fair-20文件,一开始就测试成功pass。但是为了避免对后期的修改有影响,这里还是要

m0_53112875的博客 6851

vue中的diff算法

一、是什么diff算法 diff 算法是一种通过同层的树节点进行比较的高效算法 其有两个特点: 比较只会在同层级进行, 不会跨层级比较 在diff比较的过程中,循环从两边向中间比较 diff 算法的在很多场景下都有应用,在 vue 中,作用于虚拟 dom 渲染成真实 dom 的新旧 VNode 节点比较 二、比较方式 diff整体策略为:深度优先,同层比较 比较只会在同层级进行, 不会跨层级比较 比较的过程中,循环从两边向中间收拢 下面举个vue通过diff算法更新的例子: 新旧VNode节

田兴的博客 2万+

​苹果开发者账号推送证书配置详细指南​

推送证书的配置是iOS应用实现消息推送的核心步骤。通过生成证书、配置描述文件、集成到服务器三大环节,开发者可快速为App启用APNs服务。建议优先使用更灵活的APNs Auth Key替代传统证书,以减少维护成本。确保拥有有效的苹果开发者账号(个人/公司账号),年费已缴纳。

2320

手把手教你用微信小程序实现智能硬件音视频通话(含Linux/RTOS适配)

本文详细介绍了如何利用微信小程序硬件框架(WMPF)和音视频SDK,在智能硬件(包括Linux与RTOS设备)上实现音视频通话功能。文章从架构设计、设备端SDK集成、小程序VOIP插件开发到跨平台调试与性能优化,提供了全链路实战指南,帮助开发者打通微信小程序与嵌入式设备间的实时音视频通信。

ooo22的博客 321

详解vue的diff算法

前言 目标是写一个非常详细的关于diff的干货,所以本文有点长。也会用到大量的图片以及代码举例,一起来get吧。 先来了解几个点... 1. 当数据发生变化时,vue是怎么更新节点的? 要知道渲染真实DOM的开销是很大的,比如有时候我们修改了某个数据,如果直接渲染到真实dom上会引起整个dom树的重绘和重排,有没有可能我们只更新我们修改的那一小块dom而不要更新整个dom呢?diff算法能够帮助我...

weixin_34319817的博客 954

YOLOv12改进策略【Neck】| arXiv 2024 MAFPN:多分支辅助特征金字塔网络 | 通过双向辅助融合与异构卷积机制,解决传统PAFPN多尺度特征融合不充分与小目标检测不足问题

本文记录的是利用MAFPN颈部结构改进YOLOv12的目标检测网络模型。通过引入双向辅助融合机制优化特征处理流程,在自底向上路径利用 SAF 模块融合主干浅层特征与颈部输出,并保留浅层空间信息,为小目标检测提供更丰富细节;自顶向下路径通过 AAF 模块建立密集连接,聚合浅层高 / 低分辨率层、同级层及前层特征,均衡各层通道数后实现多向梯度信息交互,增强中 / 大目标特征表达。将其应用到中,解决传统特征金字塔在多尺度信息整合中的不足,提升多尺度目标检测的精度与特征表达的丰富性。Multi-Branch Aux

Limiiiing的博客 1251

vue的diff算法详解(看完谁问都不慌了)

diff算法是一种通过同层的树节点进行比较的高效算法,其有两个特点: 1.比较只会在同层级进行, 不会跨层级比较 2.在diff比较的过程中,循环从两边向中间比较 diff算法在很多场景下都有应用,在vue中,作用于虚拟dom渲染成真实dom的新旧VNode节点比较

常来常往,共同成长 1万+

【Java开发者必看】LangChain4j实战指南:使用AIService轻松集成聊天记忆Chat Memory到SpringBoot应用,通过封装多轮复杂对话,使聊天记忆的实现变得简单

聊天记忆是指在与用户的多轮对话过程中,能够记住之前的交互内容,从而提供更加连贯和个性化的回复。LangChain4j支持通过ChatMemoryProvider接口实现聊天记忆功能。

Spring Boot-Common On With You 437

LDRA Testbed软件静态分析_操作指南

从本文起,将开始LDRA Testbed(TBrun)教程的系列文章,包括软件静态分析、单元测试、集成测试,以及基于Testbed的自动化工具开发、持续集成、常见问题解答等。LDRA公司是专业的软件测试工具与测试技术、咨询服务提供者,其总部位于英国利物浦。其旗舰产品Testbed/TBrun功能全面、易于使用,不仅适合于主机平台软件测试,同时适合于嵌入式软件测试。不仅能进行软件静态测试,还能进行软件单元测试、软件集成测试,在白盒测试领域运用比较广泛。

文章主要涉及嵌入式软件开发、测试、项目管理等,欢迎交流,共同进步。 1万+

42.VueJS学习-Vue 2 中的 diff 算法

在 Vue 2 中,diff 算法用于比较新旧虚拟 DOM 树的差异,并根据差异进行最小化的 DOM 操作,以提高性能。

qq_34334992的博客 700

ESP8266-Arduino网络编程实例-异步TCP客户端

本次实例将使用ESPAsyncTCP库实现一个简单的客户端。

视觉与物联智能 1734

Vue2和Vue3中的diff算法

Vue2和Vue3中的diff算法

weixin_45231569的博客 3169

XRoboToolkit —— 基于 PICO 4 Ultra 的机器人遥操作方案(一)

视觉-语言-动作模型(Vision-Language-Action models)的快速发展催生了对大规模、高质量机器人演示数据集的迫切需求。尽管遥操作是数据采集的主要方法,但现有方法存在可扩展性有限、设置流程复杂以及数据质量不佳等问题。本文提出XRoboToolkit,这是一个基于OpenXR标准的跨平台扩展现实(XR)机器人遥操作框架。该系统具备低延迟立体视觉反馈、基于优化的逆运动学算法,并支持多种跟踪模态,包括头部、控制器、手部及辅助运动追踪器。

2506_90492529的博客 3283

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

43.VueJS学习-如何优化 Vue 2 中 diff 算法

通过以上方法,可以有效地优化 Vue 2 中 diff 算法的性能,提高应用的响应速度和用户体验。2.选择合适的key值。

qq_34334992的博客 599

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Vue2 的 diff 算法

Vue2 的 diff 算法

m0_74076766的博客 2050

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Vue3、 Vue2 Diff算法比较

oldCh和newCh;有下面几个变量:oldStartIdx 初始值=0oldStartVnode 初始值=oldCh[0]oldEndIdx 初始值=oldCh.length - 1oldEndVnode 初始值=oldCh[oldEndIdx]newStartIdx 初始值=0newStartVnode 初始值=newCh[0]newEndIdx 初始值=newCh.length - 1newEndVnode. 初始值=newCh[newEndIdx]对比流程。

weixin_51225684的博客 1421

vue-vue2和vue3的diff算法

乱序部分,采用最长递增子序列的算法,最大递增子序列的作用就是通过新旧节点变化前后的映射,创建一个递增数组,这样就可以知道哪些节点在变化前后相对位置没有发生变化,哪些节点需要进行移动,如下图计算出E、F、Y、J 是不需要操作的节点,直接复用,然后移动K节点,即可完成一次更新;若新的比老的长,创建,可以看到下图新的比老的多,新的多了一个D,多出来的这个节点就需要创建并添加到尾部。老的比新的长,删除,可以看到下图老的比新的多了个C,多出来的这个节点需要删除。

weixin_42855188的博客 3500

【VUE面试】Vue2和Vue3的diff算法中,key的作用分别是什么?

在 Vue2 和 Vue3 的 Diff 算法里,`key` 都起着关键作用,但由于两个版本的 Diff 算法实现有所不同,`key`的具体作用和使用场景也存在一些差异。以下详细介绍:

学无止境 946

vue2 vue3 diff算法比较

简单来说,就是先老节点与新节点,头对头->尾对尾->头对尾->尾对头,再不行就从根据新节点key值,找对应的老节点,找到更新对应的真实dom.以上五步是不符合条件依次往下,符合条件,新老节点的startIndex或endIndex会向中间靠拢,进行下一节点的对比。5. “完全乱序”,(如下图七):头对不上头,尾对不上尾,头尾交叉也对不上,那就根据key值来找,newStart的key,按顺序从老节点中找到key值对应的节点,从oldStart开始哈,找到后渲染出来,就继续头对头,,,比下去。

2401_84435838的博客 1249

Vue2中、Vue3中的diff算法的区别是什么?

根据多方学习和总结,了解到的Vue2、Vue3中关于diff算法 思路还有想法,再此记录,因为没有对于写博客相关而言是纯新手,所以求大家轻喷,都是干货,特别特别实在的那种

weixin_44004878的博客 1495

Vue2 diff 算法

从源码 ➕ 实验让读者对 Diff 算法有更加深刻的理解

ox4f5da2的博客 570

vue2与vue3的diff算法有什么区别

在 Vue 中,虚拟 DOM 是一种重要的概念,它通过将真实的 DOM 操作转化为对虚拟 DOM 的操作,从而提高应用的性能。Vue 框架在虚拟 DOM 的更新过程中采用了 Diff 算法,用于比较新旧虚拟节点树,找出需要更新的部分,并最小化 DOM 操作。Vue2 和 Vue3 在 Diff算法上有所不同,下面我们就说说这两者的具体区别。

SailingCoder的博客 4267

Vue2的 双端 diff算法 与 Vue3 的 快速diff 算法

Vue Diff算法通过虚拟DOM对比高效更新真实DOM,核心策略包括同层比较、类型识别和Key值复用。Vue 2采用双端Diff算法,通过四种指针匹配减少操作;Vue 3优化为快速Diff算法,结合预处理和最长递增子序列(LIS)最小化DOM移动。Key的重要性体现在精准匹配节点和保持组件状态,应避免使用index作为Key。算法执行分为判断节点、更新属性和对比子节点三个阶段,Vue 3通过建立新旧节点映射表、标记移动节点等步骤,最终基于LIS实现最优DOM更新方案。

qq_49581491的博客 1463
上一篇: Vue简介
下一篇: Vue生命周期
The  丶
博客等级 码龄7年 1粉丝 6原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值