• React批处理原理及性能优化实践


    事件循环

    JavaScript是一门单线程语言,但是会分为同步和异步,同步任务和异步任务分别进入不同的执行"场所"。

    同步任务进入主线程,异步任务进入Event Table并注册回调函数,Event Table会将这个函数移入任务队列(task queue),等待主线程的任务执行完毕。当执行栈中的代码执行完毕,执行栈(call stack)中的任务为空时,就会读取任务队列(task queue)中的任务,去执行对应的回调。如此循环,就形成js的事件循环机制(Event Loop)。

    事件循环队列里有两种任务,宏任务(同步代码、setTimeout)、微任务(promise),一次事件循环中的同步代码执行完毕后,会去把队列中已有的微任务执行清空,然后进入下一次事件循环

    先做几个题感受一下

    答案:13642


    答案:136542


    答案:135642


    答案:3


    答案:23

    几个问题

    setState到底是异步还是同步的?

    熟悉react的小伙伴都知道,react是通过状态变化,然后自动计算,将这些变化渲染在界面上的。 但在实际使用过程中,有很多地方表现的与我们预期的不一致。我们来看下一个简单的demo。多个顺序执行的setState不是同步的一个个执行的,会一个个加入队列中,最后一期执行,即批处理『我不会爬到山峰三次,每一次都去更新一个状态』

    React 会把我们更新 state 的函数加入到一个队列里面,然后,按照函数的顺序依次调用。同时,为每个函数传入 state 的前一个状态,这样,就能更合理的来更新我们的 state 了。

    为什么直接修改this.state无效

    要知道setState本质是通过一个队列机制实现state更新的。 执行setState时,会将需要更新的state合并后放入状态队列,而不会立刻更新state,队列机制可以批量更新state。 如果不通过setState而直接修改this.state,那么这个state不会放入状态队列中,下次调用setState时对状态队列进行合并时,会忽略之前直接被修改的state,这样我们就无法合并了,而且实际也没有把你想要的state更新上去。

    React17的渲染流程源码解析(事件响应)

    onPress之后进入到React的事件代理和分发;重点关注一下batchedUpdates。

    React的渲染流程源码解析(batchedUpdate)

    executionContext代表当前处于什么处理流程状态

    BatchedContext是批处理状态

    React的渲染流程源码解析(setState)

    this.setState进入的关键代码片段

    lane: 获取当前更新的类型(优先级)

    保存状态的更新数据

    进入调度方法看是否需要将更新应用到渲染

    React的渲染流程源码解析(lane)

    fiber.mde: 当前React的虚拟dom的调度渲染模式

    BlockingMode: 含有并发模式小部分功能的模式 ConcurrentMode:并发模式(React18的默认模式)

    Reat17中不特意开启,就不会进入上述两个模式中

    React的渲染流程源码解析(scheduleUpdateOnFiber 调度)

    lane: 当前这个更新的类型(优先级)

    若当前更新不在批处理状态中

    此方法约等于 直接渲染

    React17默认模式的批处理是半自动的

    事件处理函数、生命周期函数中的同步代码包裹在batchedUpdates的回调中,react框架就能知道所有的同步更新可以合并,到同步代码运行的最后前再做渲染。

    如果放在异步代码里,框架内部的事件循环就结束了,无法控制后续异步回调里的更新做批处理,每次更新都会触发渲染。

    那有没有全自动?

    React18以及React17的并发模式的批处理是全自动的

    Why?

    对每一个更新操作定义优先级,在一段时间内优先级相同的更新只渲染一次

    相关优化思路

    • 先级高的异步任务先处理,优先级低的异步任务等渲染完成再处理;* 方法内的setState、dispatch放入batch回调中处理,batch可以通过train_rn_common引入* * *

    今天分享了公司React业务代码中在处理电商场景(日活2千万)一些性能优化操作,没有使用代码块,而是直接截图了 公司业务代码(隐藏了baseUrl),防止一些啥都不懂的前端小朋友误会~

  • 相关阅读:
    Android KeyStore 秘钥导入
    hadoop笔记——YARN部署
    面试官:Go函数参数传递到底是值传递还是引用传递?
    OS——进程并发控制(五大经典问题信号量机制描述)
    中英文说明书丨艾美捷HEK293T宿主细胞蛋白ELISA试剂盒
    2023年9月8日
    2024届 C++ 刷题 笔试强训 Day 02
    如何在 HarmonyOS 对数据库进行备份,恢复与加密
    app 更新 对aso是否有影响
    专利快速预审主体备案服务指南
  • 原文地址:https://blog.csdn.net/weixin_53312997/article/details/126303000