[v1.3] 显著提升 UI 响应速度 —— 修复 ArcoDesign/React 中 focusin / focusout 事件问题 by cyfung1031 · Pull Request #1224 · scriptscat/scriptcat

应该只有 focusin/focusout
AI解释如下


是否存在类似事件?

存在,但真正值得像 focusin / focusout 这样采用 macrotask 延迟处理的同类事件非常少。

大多数问题集中在同时具备「同步冒泡 + 高频触发 + React/框架额外包装一层」特性的事件上。

以下按实际踩坑概率从高到低排序,而非罗列所有事件。


一、与 focusin / focusout 同级别(最需关注)

1. focus / blur

(⚠️ 与 focusin/focusout 行为不完全相同)

事件 原生冒泡特性
focus 不冒泡
blur 不冒泡

为何仍需关注?

  • React 通过捕获阶段 + 合成事件模拟冒泡行为
  • 主流 UI 库(Arco、Ant Design、MUI 等)常同时监听 focus / focusin
  • React 17+ 事件委托已下放到 root 容器,重复触发问题更容易被放大


原生 focus/blur 不冒泡,浏览器不会像 focusin/focusout 那样产生「逐层爆炸式触发」。

结论
一般无需采用当前 macrotask hack,除非明确发现某 UI 库对 focus 事件进行了多层代理。


二、存在「同步连环触发」的高频 UI 事件(有一定风险)

特点:一次用户操作 → 同步触发多个事件 → React/框架再次包装

2. mouseover / mouseout(次高风险)

  • 子元素切换时会频繁反复触发
  • 冒泡
  • 多数组件库内部会基于它们衍生:hover、tooltip、popover、menu 等

为何通常没 focusin 那么严重?

  • 浏览器和 React 对 mouse 事件优化多年
  • UI 库普遍采用 throttle / debounce / pointer-events 等防护措施

结论
理论上存在类似风险,但不推荐使用 macrotask 延迟,性价比低,副作用可能大于收益。

3. pointerover / pointerout(🟡 现代且相对干净)

  • pointer 事件统一了 mouse / touch / pen
  • 触发路径更可预测、可控
  • UI 库在此类事件上踩坑较少

结论:基本无需特别担心。


三、真正的高频事件,但不适合用 macrotask 方案

4. scroll / resize(🚫 不建议此方式)

  • 触发极高频
  • 同步执行
  • scroll 不冒泡

若强行放入 macrotask:

  • UI 出现明显迟滞
  • 布局抖动加剧

推荐正确处理方式

  • requestAnimationFrame
  • throttle / debounce
  • passive: true

四、键盘与输入相关事件(需视场景而定)

5. input / change / keydown / keyup

在中文输入法(IME)场景下会产生:
compositionstart → compositionupdate → compositionend

一次输入可能导致原生 + React 多轮触发

这些事件语义极其敏感(光标位置、撤销栈、输入法交互等),延迟到 macrotask 极易引入 bug。

结论
禁止全局 hack,只能在具体业务组件内做针对性、精细化处理。


五、为何 focusin / focusout 尤其“特殊”?

当前 macrotask 方案几乎是为它们量身定制,主要原因同时满足以下六点:

  1. 同步触发
  2. 支持冒泡
  3. 在 DOM 路径上反复触发
  4. React 17+ 合成事件机制会再完整走一遍
  5. 众多 UI 库习惯在 document / body 层绑定
  6. 延迟一个 macrotask 对用户无明显感知

真正同时满足这六点的其他事件极少


六、实战判断标准(Mental Checklist)

未来遇到类似性能问题时,可快速对照以下条件:

只有同时满足全部条件的事件,才值得考虑 macrotask 延迟方案:

  • 支持冒泡
  • 同步触发
  • 一次用户动作会多次触发
  • UI 库 + React 都会额外包装一层
  • 延迟到下一个 macrotask 不破坏语义和用户体验

目前几乎仅限于:

  • focusin
  • focusout