Ext JS 7.4.0 AdvancedGrouping多分组高频更新后点击异常问题求解
问题原因
你遇到的交互卡顿是高频单次更新触发多次UI重绘导致的JS主线程阻塞:
当前的更新逻辑中,每调用一次entity.set()都会触发Store的update事件,Multigroup插件监听该事件后会立即执行分组重计算、DOM重绘操作。500条记录每次更新会触发500次重绘逻辑,10秒一次的更新频率会持续占用JS主线程,用户交互事件(点击、滚动、选中)会进入任务队列排队等待主线程空闲,因此需要多次点击才能触发响应。
解决方案
1. 改为批量更新逻辑,单次更新只触发一次重绘
修改你的更新代码,批量更新时暂停Store事件触发,所有数据更新完成后再触发一次全局刷新即可,修改后代码如下:
updateDevices: function (array) { var i, store, entity; store = Ext.getStore('Devices'); // 开启批量更新,暂停所有事件触发 store.suspendEvents(false); try { for (i = 0; i < array.length; i++) { entity = store.getById(array[i].id); if (entity) { // 单条更新加silent属性,静默更新不触发单独事件 entity.set({ status: array[i].status, lastUpdate: array[i].lastUpdate }, { dirty: false, silent: true }); } } } finally { // 恢复事件触发 store.resumeEvents(); // 全局触发一次刷新,仅重绘一次UI store.fireEvent('refresh', store); } }
如果你使用的是ExtJS 6及以上版本,可以用内置的批量更新API代替手动挂起事件,安全性更高:
updateDevices: function (array) { var i, store, entity; store = Ext.getStore('Devices'); store.beginUpdate(); try { for (i = 0; i < array.length; i++) { entity = store.getById(array[i].id); if (entity) { entity.set({ status: array[i].status, lastUpdate: array[i].lastUpdate }, { dirty: false }); } } } finally { store.endUpdate(); } }
2. 优化Multigroup插件配置
- 检查插件是否开启了
autoRefresh、groupRefreshOnUpdate这类实时刷新配置,关闭自动刷新改为手动控制刷新时机 - 如果你的分组规则不会随status、lastUpdate字段变更,可配置插件跳过字段更新时的分组重计算逻辑,仅在全量数据变更时重算分组
3. 额外优化项
- 关闭表格、单元格的选中动画、高亮过渡效果,减少DOM渲染开销
- 开启表格的虚拟滚动配置,如果插件支持的话,只渲染可视区域的DOM节点,减少重绘时的DOM操作量
内容的提问来源于stack exchange,提问作者jona972
相关产品推荐
相关产品推荐

