浅谈 React 与 Vue 更新机制的差异

news2024/11/27 10:44:30

前言

哈喽,大家好,我是 Baker !🎉

对于前端的 Vue 和 React 相信大家并不陌生,这两个库有着截然不同的设计思想和发展目标,对于我们上层使用者来说,研究它们的差异不仅让我们更加深入的去理解这些库的设计思想,也能帮助我们在开发中更有依据的去选择合适的框架。

本篇文章就两者的更新机制来浅淡一下它们的区别,因为是浅淡并且也受限于篇幅,所以这里并不会就某些技术细节进行展开,如果大家想要深入去了解两者技术的实现,可以尝试去读一下源码,或者期待一波博主后续的更新🌹

因为不涉及技术细节,大家放轻松,悠闲自在的观看即可。

在这里插入图片描述

好啦,让我们开始吧!

Vue 更新机制

Vue 使用著名的响应式系统收集依赖派发更新,当模板中数据发生变化时,组件的 render 函数会被作为数据的依赖而被触发,只不过这个触发并不是立刻的,因为模板中会引用很多数据,render 同时是这些所有数据的依赖项,如果 render 每次都立刻执行,则会造成多次重复渲染而消耗性能。

实际上 render 是被 update 调用的,而 update 又是 Watcher 调用的,而 Watcher 在收到 Dep 的派发更新时会把自身交给 Scheduler ,由 Scheduler 负责对其去重并通过 nextTick() 将这些 Watcher 包装成微任务放入到事件循环中等待调用。

render 执行输出的结果是一颗新的虚拟 DOM 树,然后 update 会通过 patch 函数将它与旧的虚拟 DOM 树进行对比,diff 和真实 DOM 的操作过程既是在 patch 函数中进行。

所以,其实 Vue 的整个更新任务(构建虚拟 DOM ,diff,操作真实 DOM)可以算作一个整体,这个整体被当作微任务来处理,这也就是 Vue 异步更新的原理。

最后附上一张 Vue 官方文档的流程图:

在这里插入图片描述

React 更新机制

这里以 React16 之后的 Fiber 架构为例。

React 没有 Vue 的响应式系统,它的更新主要是靠用户手动的调用副作用函数(比如 setState 等)来触发( Vue 则是系统自动触发)。所有的更新任务(如调用 setState )会被 render 阶段的 Scheduer 进行调度,它会将多次的 setState 调用合并为一次更新操作,render 阶段可以随时被打断(如遇到高优先级任务、当前事件循环没有足够的时间了、发生了其它错误等)。

Scheduer 调度器负责对任务进行调度,内部会通过任务的优先级(会通过一系列的优先级设置任务的 delay ),以及当前事件循环空闲的时间等来判断当前任务是否可以执行,如果可以执行则会通过 MessageChannel 将任务包装成一个宏任务推入到事件循环当中等待执行,在任务执行时通过 render 阶段的 Reconciler 来进行协调。

Scheduer 判断当前任务是否可以执行的调度可以通过原生的 requestIdleCallback 来进行简单模拟,因为这个 Api 就是在浏览器空闲时期被调用。

Reconciler 通过递和归两个阶段来创建新的 Fiber Tree 和进行副作用的收集(这个副作用指的是 DOM 的更新操作)( diff 发生在此),至此 render 阶段结束,之后就来到了 commit 阶段,该阶段只有一个 Readerer 执行,并且是同步执行,Readerer 主要就是根据 Fiber Tree 标记的副作用来进行真实 DOM 的创建、更新和删除操作。

在这里插入图片描述

区别

其实大体上 Vue 和 React 的更新机制都是构建虚拟DOM、diff、操作真实DOM这三个主要过程,它们的主要区别主要体现在触发更新的机制和一些细节上:

  • 触发更新机制:Vue 是通过响应式系统自动及时的进行触发,而 React 则是通过用户更改状态的操作然后进行一系列调度来触发更新。

  • 任务的区别:Vue 会将任务包装成微任务,而 React 则是将其包装成宏任务。

    虽然都是异步任务,但它们有很大区别。在事件循环中,如果有微任务存在则会先一直执行微任务,直到把微任务队列清空,然后再执行宏任务,并且在每个宏任务执行完毕后,会立即检查并执行所有微任务,然后再进行下一个宏任务的执行。

    先明确一点:异步任务执行时是由主线程进行执行的,所以此时它们已经相当于是同步执行了(这个异步实际指的是异步任务在任务队列里面等待的时候不会影响主线程的执行)

    微任务执行时不会穿插其它任务(比如浏览器渲染),所以当有大量微任务堆积时可能就会阻塞浏览器渲染(异步任务),但执行完一个宏任务时如果遇到浏览器需要渲染,则不会继续执行下一个宏任务而是转去进行浏览器渲染然后开启新的一轮事件循环。

    • 因为 React 的 Fiber 架构的出现就是为了能够随时打断,把控制权交给主线程,所以 React 采用的是宏任务,而不是会一股脑 “ 全冲完 ” 的微任务,这样可以避免微任务过多而导致的任务堆积和性能问题。
    • 也正是因为 Vue 的理念是追求响应性和即时效果并避免过多的渲染,所以它采用微任务,及时把更新任务处理完,最后让浏览器渲染一次即可。
    • 其实现如今,React 和 Vue 都不是完全使用某一种任务,在一些情况下 React 也会使用微任务,Vue 亦是如此,它们的目标都是想要结合自身情况来创造一个更优秀的框架。
  • diff 算法的不同:Vue 采用双端对比,而 React 使用的是 Reconciliation 算法。

    Reconciliation 算法是React 整体的更新策略,并不只是简单的 diff 算法。简单来说 React 的 diff 过程会对单节点和多节点分别计算(都是遍历 Fiber 链表进行的),多节点的情况会分两轮遍历,第一轮遍历会尝试逐个的复用节点,第二轮遍历处理上一轮遍历中没有处理完的节点。

    React 不使用双端 diff 的原因:
    在这里插入图片描述
    React 源码中的原话:This algorithm can’t optimize by searching from boths ends since we don’t have backpointers on fibers. I’m trying to see how far we can get with that model. If it ends up not being worth the tradeoffs, we can add it later.(这种算法不能通过从两端搜索来优化,因为我们在 Fiber 对象上没有反向指针。我正试着看看我们能用这个模型走多远,如果这种方式不理想,以后再考虑实现两端搜索。)
    并且源码中还提到,React 认为对于列表反转和需要进行双端搜索的场景是少见的,所以综合以上情况, React 暂时还不会使用双端 diff。

结语

还是那句话,本篇文章只是浅淡,Vue 和 React 的更新机制非常复杂,其中涉及的知识点很多,比如 Vue 的响应式原理、Vue 双端 diff 流程、React Fiber 架构、Fiber 双缓冲、React Reconciler 递和归两阶段流程等等。

本文简单梳理了一下它们更新机制的整体流程,希望能基于此来为大家展开一个清晰的脉络,如果在阅读过程中发现了问题,欢迎评论区留言交流!

如果本篇文章对你起到了帮助,还请大家不要吝啬手中的点赞、评论、收藏和关注,我们下次再见!

最近忙着秋招,更新频率虽然降低了,但是我写文章的热情可是一点没减,期待下次好文相见!

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

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

相关文章

使用自定义插槽(slot)来将数据传递给插槽内容。el-step

description为描述性文字,需使用slot来自定义文字。 A 是 Vue 3 中的语法糖,用于简洁地定义插槽。用来绑定step组件中description。step可使用插槽 B是绑定date数据实现自定义描述文字。

VoxWeekly|The Sandbox 生态周报|20230918

欢迎来到由 The Sandbox 发布的《VoxWeekly》。我们会在每周发布,对上一周 The Sandbox 生态系统所发生的事情进行总结。 如果你喜欢我们内容,欢迎与朋友和家人分享。请订阅我们的 Medium 、关注我们的 Twitter,并加入 Discord 社区&#xf…

linux安装配置 flume

目录 一 解压安装包 二 配置部署 (1)修改配置 (2)下载工具 (3)创建配置文件 (4)启动监听测试 (5)flume监控文件 一 解压安装包 这里提供了网盘资源 链…

狂热过后,RPA到底是什么?

随着科技的不断进步,人工智能正在逐步渗透到各个领域,并不断演变,成为更加便捷的方式步入万家,让科技的变革的春风吹入了千行百业,落入千家万户。而“RPA”(Robotic Process Automation,即机器人…

视频去LOGO的方法,AI自动完美地去除视频LOGO

喜欢做影视剧剪辑的朋友,可能会遇到下载的影视剧本身存在字幕、台标的情况,这些和新的剪辑主题不相符的原片元素,都会影响我们最终的成片效果。不过也无需烦恼哦,我们可以利用AI视频处理工具,自动去除视频中的logo或其…

6个超好用的团队任务管理工具,帮你解决团队工作任务“杂乱难”

当团队面临大量任务和复杂工作时,任务管理往往变得杂乱且困难。为了提高团队效率和组织能力,许多团队都在寻找适合他们需求的任务管理工具。在这篇文章中,我们将介绍6个超级好用的团队任务管理工具,它们可以帮助团队更好地组织、分…

【Redis】第1讲 互联网架构的演变历程

第1阶段 数据访问量不大,简单的架构就可以! 第2阶段 数据访问量大,使用缓存技术缓存数据库的压力,不同的业务访问不同的数据库。 第3阶段 之前的缓存技术确实能够缓解数据库的压力,但是写和读都集中在一个数据库上&…

PLC串口通讯和通讯接口知识汇总

在使用PLC的时候会接触到很多的通讯协议以及通讯接口,最基本的PLC串口通讯和基本的通讯接口你都了解吗? 一、什么是串口通讯? 串口是一种接口标准,是计算机上一种非常通用设备通信的协议。它规定了接口的电气标准,没…

国家加快培育数据要素市场的重要意义是什么

加快培育数据要素市场 中国大数据发展趋势如何?据工业和信息化部官网9月29日消息,9月28日,2021全国大数据标准化工作会议在山东省济南市召开。工信部信发司副司长王建伟参加会议并致辞。当前,数据已成为重要的生产要素,是加快经…

buuctf-[网鼎杯 2020 朱雀组]phpweb

1.打开网站,吓我一跳 2.查看源代码,主要看到timezone,然后这个页面是五秒就会刷新一次 一开始去搜了这个,但是没什么用 3.使用bp抓包 会发现有两个参数,应该是用func来执行p 4.修改func和p file_get_contents&#…

linux离线安装glibc.i686

一、下载相关rpm包 链接:https://pan.baidu.com/s/1Of1myRZa2ClrlSYw43OR3Q 提取码:hlsq 二、将相关rpm包复制到服务器上 三、执行sh install.sh即可

iOS“超级签名”绕过App Store作弊解决方案

一直以来,iOS端游戏作弊问题都是游戏行业的一大痛点。在当下游戏多端互通的潮流下,游戏作为一个整体,无论哪一端出现安全问题,都会造成更加严重的影响。因此,iOS端游戏安全保护也同样十分重要。 iOS独特的闭源生态&am…

SpringBoot2.7.14整合Swagger3.0的详细步骤及容易踩坑的地方

🧑‍💻作者名称:DaenCode 🎤作者简介:啥技术都喜欢捣鼓捣鼓,喜欢分享技术、经验、生活。 😎人生感悟:尝尽人生百味,方知世间冷暖。 📖所属专栏:Sp…

基于C#的AE二次开发之IQueryFilter接口、ISpatialFilter接口、IQueryDef 接口的查询接口的介绍

一、开发环境 开发环境为ArcGIS Engine 10.2与Visual studio2010。在使用ArcEngine查询进行查询的时候主要使用三种查询接口IQueryFilter(属性查询) 、ISpatialFilter(空间查询) 、IQueryDef (多表查询) 那…

js 事件流、事件冒泡、事件捕获、阻止事件的传播

事件流 js 事件的执行过程分为捕获阶段(由外层节点传播到内层节点)和冒泡阶段(由内层节点传播到外层节点),即先执行捕获阶段的代码,后执行冒泡阶段的代码 事件冒泡 js 事件中的代码默认在冒泡阶段执行&…

滚动渐变导航栏

实现导航栏固定顶部&#xff0c;且滚动渐变的效果 实现效果 准备html vscode可利用快捷输入 header>aul>li*3>atab <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport"…

ULID 在 Java 中的应用: 使用 `getMonotonicUlid` 生成唯一标识符

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

【Java】防沉迷实名认证系统接口测试代码(已全示例通过)

下面的代码以及置顶文件使用并修改了作者:jsppqq.com的开源代码&#xff0c;只作学习使用&#xff0c;侵删 背景&#xff1a; 在接入Taptap的防沉迷实名认证前&#xff0c;需要先通过国家防沉迷实名认证系统的接口测试&#xff0c;要求全部示例通过才能允许使用接口&#xff1…

docker安装nacos和sentinel笔记

docker安装nacos和sentinel笔记 docker安装nacos docker pull nacos/nacos-server:v2.2.3docker run -d --name -p 8848:8848 -e PREFER_HOST_MODEhostname -e MODEstandalone nacos/nacos-server:v2.2.3docker安装sentinel docker pull bladex/sentinel-dashboard:1.8.0doc…