You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Lodash isEqual作为React.memo比较函数致应用偶发冻结问题咨询

问题场景

React组件按如下写法做默认导出:

React.memo(MyReactComponent, isEqual)

其中比较函数isEqual来自Lodash工具库。业务场景下组件props会以10Hz的频率持续更新,运行过程中偶发应用卡在LodashisEqual函数执行阶段,出现无响应冻结问题。

可能原因
  • props携带了超大规模的嵌套对象:lodash.isEqual是递归执行的深比较函数,如果没做props裁剪,直接把整棵应用状态树、上万条数据的列表对象、几十层嵌套的配置对象这类大结构透传给组件,深比较的耗时会随对象规模暴涨。10Hz的更新频率要求每100ms就要跑完一次比较,只要单次比较耗时超过100ms就会阻塞主线程,对象规模够大的时候直接触发页面冻结。
  • props混入了非普通JS对象的宿主实例:如果误把DOM节点、React组件实例、File文件对象、Socket连接实例这类浏览器/运行时提供的内置对象传入组件,isEqual遍历属性时会顺着原型链扫描这些对象挂载的上百个内置属性、方法,单次比较的遍历量会是普通对象的几十上百倍,很容易直接卡满主线程。
  • 比较逻辑触发了死循环:两种场景会导致这个问题:一是使用的Lodash版本过旧,早期版本的isEqual对循环引用的处理存在bug,遇到特定结构的循环引用对象时会进入无限递归,完全不释放主线程;二是待比较的对象属性定义了带死循环/超长同步逻辑的getter访问器,isEqual读取属性值做对比时会直接执行getter内的逻辑,从调用栈看就像是卡在了isEqual内部。
  • props传入了大体积二进制数据:如果props中包含大长度的ArrayBuffer、TypedArray、Buffer这类二进制对象,isEqual会逐字节对比内容,只要二进制数据体积达到几十MB级别,单次比较就会占用数秒主线程时间,直接触发无响应。
  • 对象自定义方法触发性能陷阱:如果待比较对象重写了toString、valueOf方法,且方法内部存在大量同步计算逻辑,isEqual在做类型校验、值对比时触发这些方法,也会导致比较耗时异常升高,出现卡顿。

内容的提问来源于stack exchange,提问作者Samuel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 14:01:14