一、背景
通过今天的学习,你将收获这些内容:

创新互联服务项目包括盂县网站建设、盂县网站制作、盂县网页制作以及盂县网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,盂县网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到盂县省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!
- 主流前端框架的批量更新方式。
- vue 和 react 批量更新的实现。
- 宏任务和微任务的特点。
1.一次 vue 案例
首先来想一个问题。比如在 vue 中一次更新中。
姓名: {{ name }}
年龄: {{ age }}
如上是一个非常简单的逻辑代码,点击按钮,会触发 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 一次。
2.一次 react 案例
上面介绍了在 vue 中更新批处理的案例之后,我们来看一下在 react 中的批量更新处理。把上述案例用 react 来实现一下:
function Index(){
const [ age , setAge ] = React.useState(0)
const [ name, setName ] = React.useState('')
return
姓名: {name}
年龄: {age}
}点击按钮,触发更新,会触发两次 useState 的更新函数。那么 React 的更新流程大致是这样的。
- 首先会找到 fiberRoot 。
- 然后进行调和流程。执行 Index 组件,得到新的 element。
- diff fiber,得到 effectList。
- 执行 effect list,得到最新的 dom ,并进行渲染绘制。
那么按常理来说,Index 组件会执行两次。可事实是只执行一次 render。
3 批量处理意义
通过上面的案例说明在主流框架中,对于更新都采用批处理。一次上下文中的 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 的执行上下文上优化了很多步骤,减少性能开销。
二、简述宏任务和微任务
在正式讲批量更新之前,先来温习一下宏任务和微任务,这应该算是前端工程师必须掌握的知识点。
所谓宏任务,我们可以理解成,
打印结果:
分析一下核心流程:
- 本方式的核心就是让 handleClick 通过 wrapEvent 变成可控的。首先 wrapEvent 类似于事件处理函数,在内部通过开关 batchEventUpdate 来判断是否开启批量更新状态,最后通过 flushSyncCallbackQueue 来清空待更新队列。
- 在批量更新条件下,事件会被放入到更新队列中,非批量更新条件下,那么立即执行更新任务。
参考资料
React进阶实践指南
当前标题:聊聊主流前端框架更新批处理方式
分享URL:http://www.jxjierui.cn/article/dhsesoc.html


咨询
建站咨询
