杭州高端网站开发网站建设公司.

pingmian/2026/1/20 13:44:04/文章来源:
杭州高端网站开发,网站建设公司.,做网站用windows还是linux,网易邮箱163登录作者 | #x1f47d;来源 | 前端Sharing背景在不同的技术框架背景下#xff0c;处理更新的手段各不相同#xff0c;今天我们来探讨一下#xff0c;主流的前端框架批量处理的方式#xff0c;和其内部的实现原理。通过今天的学习#xff0c;你将收获这些内容#xff1a;主… 作者 | 来源 | 前端Sharing背景在不同的技术框架背景下处理更新的手段各不相同今天我们来探讨一下主流的前端框架批量处理的方式和其内部的实现原理。通过今天的学习你将收获这些内容 主流前端框架的批量更新方式。 vue 和 react 批量更新的实现。 宏任务和微任务的特点。一次 vue 案例首先来想一个问题。比如在 vue 中一次更新中。templatediv姓名 {{ name }}年龄 {{ age }}button clickhandleClick 点击/button/div /templatescript export default {data(){return {age:0,name:}},methods:{handleClick(){this.name  alienthis.age  18}} } /script如上是一个非常简单的逻辑代码点击按钮会触发 name 和 age 的更新。那么首先想一个问题就是正常情况下vue 的数据层是通过响应式处理的那么比如 age 和 name 可以理解成做了一层属性代理字符串模版 template 里面的属性 name 和 age 的 get 会和组件的渲染 watcher vue3.0 里面的 effect 建立起关联。一次重新赋值会触发 set 那么根据响应式会触发渲染 watcher 重新执行然后就会重新更新组件渲染视图。那么暴露的问题就是我们在 handleClick 中同时改变了 name 和 age 属性那么按照正常情况下会分别触发 name 和 age 的 set那么如果不做处理那么会让渲染 watcher 执行两次结果就是组件会 update 两次但是结果是这样的吗结果是vue 底层通过批量处理只让组件 update 一次。一次 react 案例上面介绍了在 vue 中更新批处理的案例之后我们来看一下在 react 中的批量更新处理。把上述案例用 react 来实现一下function Index(){const [ age , setAge ]  React.useState(0)const [ name, setName ]  React.useState()return div姓名 {name}年龄 {age}button onClick{(){setAge(18)setName(alien)}}点击/button/div }点击按钮触发更新会触发两次 useState 的更新函数。那么 React 的更新流程大致是这样的。首先会找到 fiberRoot 。然后进行调和流程。执行 Index 组件得到新的 element。diff fiber得到 effectList。执行 effect list得到最新的 dom 并进行渲染绘制。那么按常理来说Index 组件会执行两次。可事实是只执行一次 render。批量处理意义通过上面的案例说明在主流框架中对于更新都采用批处理。一次上下文中的 update 会被合并成一次更新。那么为什么要进行更新批处理呢批处理主要是出于对性能方面的考虑这里拿 react 为例子看一下批处理前后的对比情况例子一假设没有批量更新/ ------ js 层面 ------第一步发生点击事件触发一次宏任务。第二步执行 setAge 更新 fiber 状态。第三步进行 render 阶段Index 执行得到新的 element。得到 effectlist.第四步进行 commit 阶段更新 dom。第五步执行 setName 更新 fiber 状态。第六步重复执行第三步第四步。/ ------ 浏览器渲染 ------js 执行完毕渲染真实的 dom 元素。我们可以看到如果没有批量更新处理那么会多走很多步骤包括 render 阶段 commit 阶段dom 的更新等这些都会造成性能的浪费接下来看一下有批量更新的情况。例子二存在批量更新。/ ------ js 层面 ------第一步发生点击事件触发一次宏任务。第二步setAge 和 setName 批量处理 更新 fiber 状态。第三步进行 render 阶段Index 执行得到新的 element。得到 effectlist.第四步进行 commit 阶段更新 dom。/ ------ 浏览器渲染 ------js 执行完毕渲染真实的 dom 元素。从上面可以直观看到更新批处理的作用了本质上在 js 的执行上下文上优化了很多步骤减少性能开销。简述宏任务和微任务在正式讲批量更新之前先来温习一下宏任务和微任务这应该算是前端工程师必须掌握的知识点。所谓宏任务我们可以理解成script 标签中主代码执行一次用户交互比如触发了一次点击事件引起的回调函数定时器 setInterval 延时器 setTimeout 队列 MessageChannel 等。这些宏任务通过 event loop来实现有条不紊的执行。例如在浏览器环境下宏任务的执行并不会影响到浏览器的渲染和响应。我们来做个实验。function Index(){const [ number , setNumber ]  useState(0)useEffect((){let timerfunction run(){timer  setTimeout(()  {console.log(----宏任务执行----)run()}, 0)}run()return ()  clearTimeout(timer)},[])return divbutton onClick{()  setNumber(number  1 )}  点击{number}/button/div }如上简单的 demo 中通过递归调用 run 函数让 setTimeout 宏任务反复执行。这种情况下 setTimeout 执行并不影响点击事件的执行和页面的正常渲染。什么是微任务呢 那么我们再来分析一下微任务在 js 执行过程中我们希望一些任务不阻塞代码执行又能让该任务在此轮 event loop 执行完毕那么就引入了一个微任务队列的概念了。微任务相比宏任务有如下特点微任务在当前 js 执行完毕后立即执行会阻塞浏览器的渲染和响应。一次宏任务完毕后会清空微任务队列。常见的微任务有 Promise queueMicrotask 浏览器环境下的 MutationObserver node 环境下 process.nextTick 等。我们同样做个实验看一下微任务function Index(){const [ number , setNumber ]  useState(0)useEffect((){function run(){Promise.resolve().then((){run()})}run()},[])return divbutton onClick{()  setNumber(number  1 )}  点击{number}/button/div }在这种情况下浏览器直接卡死了没有了响应证实了上述的结论。微任务宏任务实现批量更新讲完了宏任务和微任务继续来看第一种批量更新的实现就是基于宏任务 和 微任务 来实现。先来描述一下这种方式比如每次更新我们先并不去立即执行更新任务而是先把每一个更新任务放入一个待更新队列 updateQueue 里面然后 js 执行完毕用一个微任务统一去批量更新队列里面的任务如果微任务存在兼容性那么降级成一个宏任务。这里优先采用微任务的原因就是微任务的执行时机要早于下一次宏任务的执行。典型的案例就是 vue 更新原理vue.$nextTick原理 还有 v18 中 scheduleMicrotask 的更新原理。以 vue 为例子我们看一下 nextTick 的实现runtime-core/src/scheduler.tsconst p  Promise.resolve()  /* nextTick 实现用微任务实现的 */ export function nextTick(fn?: ()  void): Promisevoid {return fn ? p.then(fn) : p }可以看到 nextTick 原理本质就是 Promise.resolve() 创建的微任务。再看看 react v18 里面的实现。react-reconciler/src/ReactFiberWorkLoop/ensureRootIsScheduledfunction ensureRootIsScheduled(root, currentTime) {/* 省去没有必要的逻辑 */if (newCallbackPriority  SyncLane) {/* 支持微任务 */if (supportsMicrotasks) {/* 通过微任务处理 */scheduleMicrotask(flushSyncCallbacks);}} }接下里看一下 scheduleMicrotask 是如何实现的。/* 向下兼容 */ var scheduleMicrotask  typeof queueMicrotask  function ? queueMicrotask : typeof Promise ! undefined ? function (callback) {return Promise.resolve(null).then(callback).catch(handleErrorInNextTick); } : scheduleTimeout;scheduleMicrotask 也是用的 Promise.resolve 还有一个 setTimeout 向下兼容的情况。接下来模拟一下这个方式的实现。class Scheduler {constructor(){this.callbacks  []/* 微任务批量处理 */queueMicrotask((){this.runTask()})}/* 增加任务 */addTask(fn){this.callbacks.push(fn)}runTask(){console.log(------合并更新开始------)while(this.callbacks.length  0){const cur  this.callbacks.shift()cur()}console.log(------合并更新结束------)console.log(------开始更新组件------)} } function nextTick(cb){const scheduler  new Scheduler()cb(scheduler.addTask.bind(scheduler)) }/* 模拟一次更新 */ function mockOnclick(){nextTick((add){add(function(){console.log(第一次更新)})console.log(----宏任务逻辑----)add(function(){console.log(第二次更新)})}) }mockOnclick()我们来模拟一下具体实现细节通过一个 Scheduler 调度器来完成整个流程。通过 addTask 每次向队列中放入任务。用 queueMicrotask 创建一个微任务来统一处理这些任务。mockOnclick 模拟一次更新。我们用 nextTick 来模拟一下更新函数的处理逻辑。可控任务实现批量更新上述介绍了通过微任务的方式实现了批量更新还有一种方式通过拦截把任务变成可控的典型的就是 React v17 之前的 batchEventUpdate 批量更新。这种情况的更新来源于对事件进行拦截比如 React 的事件系统。以 React 的事件批量更新为例子比如我们的 onClick onChange 事件都是被 React 的事件系统处理的。外层用一个统一的处理函数进行拦截。而我们绑定的事件都是在该函数的执行上下文内部被调用的。那么比如在一次点击事件中触发了多次更新。本质上外层在 React 事件系统处理函数的上下文中这样的情况下就可以通过一个开关证明当前更新是可控的可以做批量处理。接下来 React 就用一次就可以了。来看一下 React 的底层实现逻辑react-dom/src/events/ReactDOMUpdateBatching.jsexport function batchedEventUpdates(fn, a) {/* 开启批量更新  */const prevExecutionContext  executionContext;executionContext | EventContext;try {/* 这里执行了的事件处理函数 比如在一次点击事件中触发setState,那么它将在这个函数内执行 */return fn(a);} finally {/* try 里面 return 不会影响 finally 执行  *//* 完成一次事件批量更新  */executionContext  prevExecutionContext;if (executionContext  NoContext) {/* 立即执行更新。  */flushSyncCallbackQueue();}} }在 React 事件执行之前通过 isBatchingEventUpdatestrue 打开开关开启事件批量更新当该事件结束再通过 isBatchingEventUpdates false; 关闭开关然后在 scheduleUpdateOnFiber 中根据这个开关来确定是否进行批量更新。比如一次点击事件中const [ age , setAge ]  React.useState(0) const [ name, setName ]  React.useState() const handleClick(){setAge(18)setName(alien) }那么首先 handleClick 是由点击事件产生的那么在 React 系统中先执行事件代理函数然后执行 batchedEventUpdates。这个时候开启了批量更新的状态。接下来 setAge 和 setName 在批量状态下不会立即更新。最后通过 flushSyncCallbackQueue 来立即处理更新任务。接下来我们模拟一下具体的实现body  button onclickhandleClick() 点击/button /body scriptlet  batchEventUpdate  false let callbackQueue  []function flushSyncCallbackQueue(){console.log(-----执行批量更新-------)while(callbackQueue.length  0 ){const cur  callbackQueue.shift()cur()}console.log(-----批量更新结束-------)}function wrapEvent(fn){return function (){/* 开启批量更新状态 */batchEventUpdate  truefn()/* 立即执行更新任务 */flushSyncCallbackQueue()/* 关闭批量更新状态 */batchEventUpdate  false}}function setState(fn){/* 如果在批量更新状态下那么批量更新 */if(batchEventUpdate){callbackQueue.push(fn)}else{/* 如果没有在批量更新条件下那么直接更新。 */fn()}}function handleClick(){setState((){console.log(---更新1---)})console.log(上下文执行)setState((){console.log(---更新2---)})}/* 让 handleClick 变成可控的  */handleClick  wrapEvent(handleClick)/script分析一下核心流程本方式的核心就是让 handleClick 通过 wrapEvent 变成可控的。首先 wrapEvent 类似于事件处理函数在内部通过开关 batchEventUpdate 来判断是否开启批量更新状态最后通过 flushSyncCallbackQueue 来清空待更新队列。在批量更新条件下事件会被放入到更新队列中非批量更新条件下那么立即执行更新任务。往期推荐Redis 缓存击穿失效、缓存穿透、缓存雪崩怎么解决如果被问到分布式锁应该怎样回答三分钟教你用 Scarlet 写一个 WebSocket AppJava 底层知识什么是 “桥接方法” 点分享点收藏点点赞点在看

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

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

相关文章

商务型网站模板迁西住房和建设管理局网站

Unity学习笔记(零基础到就业)|Chapter01:C#入门 前言一、控制台输入输出语句二、初识变量1.一些好用的tips2.变量声明的固定写法3.变量类型 三、变量的本质1.变量的存储空间2.变量的本质:2进制 四、变量的命名规范1.必须遵守的规则…

网页开发视频教程百度搜索引擎seo

一、概述 Android中,上下文菜单是通过onLongClick(...)事件访问的。在事件触发后显示菜单项。 在使用上下文菜单时,通常在onCreate(...)方法中,先行注册上下文菜单。在实现onCreateContextMenu(...)方法和onContextItemSelected(...)方法。 注…

网站不收录排名会降吗邢台网站制作哪家强

1、玄铁 9 系列概述 玄铁 8 系列 基于C-SKY架构,玄铁 9 系列基于 RISC-V 架构。E 系列为 RISC-V 32 位,C 系列为 RISC-V 64 位。 E902:超低功耗 RSIC-V 架构处理器 E902 采用 2 级极简流水线兼容 RISC-V 架构且对执行效率等方面进行了增强&a…

河南城市建设招标类网站拟定网站优化方案

文章目录 Vue在混合开发中的特点创建MAUI项目创建Vue应用使用element-ui组件库JavaScript和原生代码的交互传递根组件参数从设备调用Javascript代码从Vue页面调用原生代码 读取设备信息项目地址 .NET MAUI结合Vue的混合开发可以使用更加熟悉的Vue的语法代替Blazor语法&#xff…

网站建设的目标有哪些怎样是做网站

快速连接形成稳定的电测试在新能源行业里面是很常见的测试场景,比如说在新能源汽车行业的电池包、电机、电控制器的电性能测试中会有很多高压线束,需要将这些线束和电池包、电控制器、电机与测试设备快速连接在一起进行相关的EOL/DCR测试。 新能源汽车高…

购物网站建设优势网站建设与管理 中职

在前一篇博客中,我们介绍了五个实用的爬虫示例,分别用于新闻文章、图片、电影信息、社交媒体和股票数据的采集。本文将继续探索爬虫的奇妙世界,为你带来五个全新的示例,每个示例都有其独特的用途和功能。 1. Wikipedia数据采集 爬…

网站建设与维护的软件网站开发费用报价单

一年一度的“双十一”又要来了,很多人已经开始摩拳擦掌,毕竟几天之后手还在不在就不好说了。 作者:清风小筑 各种社交软件也是跟着遭殃,整天就是“来帮我一起盖楼”,各种字体绕过屏蔽,什么奇葩的脑洞也出来…

政务网站建设工作总结旅游网站首页设计模板

文章目录T1:跳格子题目题解CODET2:英雄联盟题目题解CODET3:排序问题题目题解CODET1:跳格子 题目 n 个格子排成一列,一开始,你在第一个格子,目标为跳到第 n 个格子。在每个格子 i 里面你可以做…

做的比较好网站有哪些公司网站设计报价

【出现问题】 php页面显示中文字符出现乱码 【解决方法】 在php页面的代码前插入一行代码即可 header("Content-Type: text/html;charsetutf-8"); 转载于:https://www.cnblogs.com/wangyang0210/p/9187403.html

中山网站建设招聘网络营销工具包括

造个可重入锁的轮子 介绍目标 正文sync.Mutexsync.Mutex介绍多协程计数器demo多协程计数器加锁 源码剖析Mutex数据结构Lock()加锁核心逻辑 UnLock() 重入锁与可重入锁魔改 sync.Mutex 参考文档 介绍 开新坑啦!! 从这篇文章开始,尝试造轮子&a…

罗湖网站制作费用营销型网站建设策划案

文章目录 载具Vehicle Variety Pack(车辆品种包)Vehicle Variety Pack Volume 2(车辆品种包第 2 卷)家具Free Furniture Pack(免费家具包)Old West - VOL 1 - Interior Furniture(旧西部 - 第1卷 - 家具包)Old West VOL.3 - Travel Supplies and Goods(旧西部 - 第3卷…

邯郸做网站服务商做网站月入

一、本文介绍 本文给家大家带来的改进机制是iRMB,其是在论文Rethinking Mobile Block for Efficient Attention-based Models种提出,论文提出了一个新的主干网络EMO(后面我也会教大家如何使用该主干,本文先教大家使用该文中提出的注意力机制…

西樵营销网站制作企业展厅设计公司重庆

目录 一、基础知识1.异或运算xor2.模2算术(1)模2加法和减法(2)模2乘法(3)模2除法 二、CRC循环冗余检测1.背景2.原理3.求R 一、基础知识 1.异或运算xor 异或,顾名思义,只有当两个数…

网站快速建设软件下载西宁吧 百度贴吧

缓存穿透 一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就去后端系统查找(比如DB)。 一些恶意的请求会故意查询不存在的key,请求量很大,就会对后端系统造成很大的压力。这就叫做缓存穿透…

离退休部门网站建设情况小游戏开发软件

以实战例子讲述JSON三兄弟的后续故事。实战一:发送JSON网络请求作为JSON老大哥的QJsonValue自知对面的大户人家妹子貌美如花,心里已经打起算盘,先下手为强,后下手遭殃。决定显示下自己的家底,想起这件事,老…

安徽做公司网站哪家好建设与管理局网站

技术背景 技术概述 FPGA实现除法运算是一个比较复杂的过程,因为硬件逻辑与软件程序的区别。如果其中一个操作数为常数,可以通过简单的移位与求和操作代替,但用硬件逻辑完成两变量间除法运算会占用较多的资源,电路结构复杂&#xf…

做网站主机电脑布吉做棋牌网站建设哪家公司便宜

Input 测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数&#xff0c;分别是城镇数目N ( < 1000 )和道路数目M&#xff1b;随后的M行对应M条道路&#xff0c;每行给出一对正整数&#xff0c;分别是该条道路直接连通的两个城镇的编号。为简单起见&#xff0c;城镇…

个人网站用什么软件网站开发定制合同

在智慧电表水表的数据采集和存储过程中&#xff0c;时序数据处理成为一个重要的问题。由于电表水表数据具有时间序列的特点&#xff0c;传统的数据库和数据处理方式往往难以满足大规模数据的高速采集、存储和实时分析需求。因此&#xff0c;越来越多的企业开始进行数据架构改造…

网站开发策划书冠县快搜网站建设有限公司

C里默认int型1的二进制表示为&#xff1a; 0000 0000 0000 0000 0000 0000 0000 0001如果左移31位&#xff0c;会得到最小值 1<<31 //会得到-2147483648&#xff0c;即int型最小值即 1000 0000 0000 0000 0000 0000 0000 0000因为int类型是有符号的&#xff0c;第一位…

无障碍环境建设 网站服装品牌网站开发php

爬虫、数据清洗和分析是在数据科学、数据挖掘和网络爬虫开发领域中常见的概念。 爬虫&#xff08;Web Scraping&#xff09;&#xff1a;爬虫是一种自动化程序或脚本&#xff0c;用于从互联网上的网站上提取信息。这些信息可以是文本、图像、视频或其他类型的数据。爬虫通常会…