[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 方案几乎是为它们量身定制,主要原因同时满足以下六点:
- 同步触发
- 支持冒泡
- 在 DOM 路径上反复触发
- React 17+ 合成事件机制会再完整走一遍
- 众多 UI 库习惯在 document / body 层绑定
- 延迟一个 macrotask 对用户无明显感知
真正同时满足这六点的其他事件极少。
六、实战判断标准(Mental Checklist)
未来遇到类似性能问题时,可快速对照以下条件:
只有同时满足全部条件的事件,才值得考虑 macrotask 延迟方案:
- 支持冒泡
- 同步触发
- 一次用户动作会多次触发
- UI 库 + React 都会额外包装一层
- 延迟到下一个 macrotask 不破坏语义和用户体验
目前几乎仅限于:
- focusin
- focusout