React+Ant Design项目non-passive事件监听器性能警告如何解决
报错与问题描述
完整错误信息
[Violation] Added non-passive event listener to a scroll-blocking 'wheel' event. Consider marking event handler as 'passive' to make the page more responsive.
问题说明
本问题是之前关于React Hooks中setState传参相关提问的延伸。
开发复杂度较高的React应用时使用了Ant Design作为组件库,其他组件运行均流畅,仅当前页面的Ant Design Modal组件存在卡顿问题。该Modal内部嵌套了Ant Design Tabs组件,每个Tab都是独立的子组件,部分Tab内部通过useEffect钩子请求接口数据后渲染列表。
该Modal在其他页面场景下从未出现卡顿,当前场景下控制台抛出上述违规警告,自身未编写任何相关事件处理函数,推测是Ant Design内部实现使用了对应事件,需要调试修复方案。
修复方案
- 优先升级Ant Design版本
Ant Design v4.17.0及后续版本、v5全版本均已修复Modal、Tabs组件滚动事件监听未配置passive的问题,先将依赖升级到对应大版本的最新稳定版,绝大多数情况可直接消除警告同时解决卡顿。 - 版本无法升级时打全局补丁修复
如果项目有兼容逻辑无法升级Ant Design,可在项目入口文件最顶部注入以下代码,全局将wheel等滚动相关事件的监听默认设为passive,直接规避警告:if (typeof window !== 'undefined') { const rawAddEventListener = EventTarget.prototype.addEventListener; EventTarget.prototype.addEventListener = function (type, listener, options) { // 匹配滚动相关事件默认设置passive为true if (['wheel', 'touchstart', 'touchmove'].includes(type)) { if (typeof options === 'object') { options.passive = options.passive ?? true; } else if (options === undefined) { options = { passive: true }; } } return rawAddEventListener.call(this, type, listener, options); }; } - 优化Modal内部渲染逻辑
因该Modal仅在当前页面卡顿,需额外排查当前场景的渲染问题:- 给Tabs组件开启懒加载,配置
destroyInactiveTabPane={true},仅在切换到对应Tab时才渲染内容、触发接口请求,减少Modal打开时的一次性渲染压力 - 检查当前页面打开Modal的逻辑,确认没有触发不必要的重复setState导致页面和Modal连带重渲染
- 如果Tab内部列表数据量较大,改用虚拟滚动组件渲染列表,减少DOM节点数量
- 给Tabs组件开启懒加载,配置
- 性能验证
打开Chrome DevTools的性能面板,录制Modal打开、滚动、切换Tab的全流程,定位卡顿的具体原因,如果性能面板显示阻塞来自wheel事件回调,则上述补丁可解决,如果阻塞来自React渲染耗时,则对应优化重渲染逻辑即可。
内容的提问来源于stack exchange,提问作者WildThing
相关产品推荐
相关产品推荐

