Formily 页面级重渲染与 Long Task

场景:Observer 粒度不够细,页面组件为了算「合计」读了 form.values.items,任意一个字段变化都会让整页重渲染,产生 long task。

怎么看:点蓝色按钮(第 0 行数量 +1),黄色闪烁的行就是被重渲染的行,顶部色块显示重渲染行数、主线程阻塞时间和 long task。

  • ❌ 问题写法:整页 observer,一次输入重渲染 100 行
  • ✅ 路线 i:form.addEffects + onFieldValueChange('items.*.qty'),只更新合计组件
  • ✅ 路线 ii:observer 下沉到合计组件,每个 Field 只订阅自己

什么时候用哪种

为什么会有路线 i:observer 会自动追踪渲染时读到的所有响应式数据。整页一旦读了 form.values.items,就等于订阅了每个字段。手动写 effect 是把这份订阅从渲染里挪出来,显式写清楚「监听哪些路径、变化后更新谁」。

只是想少渲染:优先用路线 ii,把 observer 下沉到真正用到数据的小组件,代码最少,也最符合 Formily 的写法。

这些情况用路线 i(effect):

  • 老页面整页包着 observer,一时拆不动,先用 effect 把派生数据挪出去止血
  • 变化很频繁,需要节流、防抖或批量计算
  • 变化后要做副作用:发请求、联动其他字段、把合计写回 form(form.setValuesIn('total', ...)),这些本来就不该放在渲染里
  • 派生逻辑想和 UI 解耦,放在表单模型层统一维护

注意:effect 要用唯一 id 注册,组件卸载时 form.removeEffects(id),否则会重复监听。

全屏打开