找回密码
 立即注册

QQ登录

只需一步,快速开始

Wilson.Zhang
超级版主   /  发表于:2024-11-30 19:31  /   查看:5  /  回复:0
背景:当sheet中存在的数据量较大时,sortRange排序耗时较长,探索可行的优化方式。
问题原帖:https://gcdn.grapecity.com.cn/forum.php?mod=viewthread&tid=228930

我们知道SpreadJS单元格状态之一的脏状态标识了被修改数据的单元格,也就是说某个单元格中数值发生变化后,该单元格即被标脏,其状态变为脏状态。这样可以帮助用户快速了解当前sheet中发生数值变化的单元格,辅助其他业务的进行。试想一下,如果某列单元格中的数据杂乱无序,通过排序使其自上而下呈现出有序的状态,那么,在排序前后,某些单元格中的数据必然发生了变化,而这个变化正式产生于排序过程。简言之,在排序过程中伴随有单元格的标脏活动。如果数据量庞大,频繁的标脏活动必然耗时较长。应对这一点,SpreadJS提供了suspendDirty和resumeDirty,即暂停标脏和恢复标脏。与suspendPaint和resumePaint同理,在标脏活动开始前暂停将标脏产生的效果同步渲染在sheet中,待排序活动结束后再显式标脏产生的效果。可以理解为,在暂停标脏和恢复标脏的过程中完成了实际排序,恢复标脏仅需要将排序后的结果展现在sheet中即可。这样便有效地避免了排序过程中由于标脏活动带来的耗时问题,节约了时间,提升了性能。

有了这个优化机制,在不同的排序方式中合理利用即可。一般地,可以在UI上通过筛选框的排序按钮对整列数据排序,此时结合RangeSorting和RangeSorted事件使用暂停标脏和恢复标脏。具体地,在RangeSorting事件中暂停标脏,此时正是排序进行时;排序结束后RangeSorted被触发,此时恢复标脏即可。参考如下代码:
  1. spread.bind(GC.Spread.Sheets.Events.RangeSorting, function (sneder, args) {
  2.     sheet.suspendDirty();
  3.   });
  4.   spread.bind(GC.Spread.Sheets.Events.RangeSorted, function (sender, args) {
  5.     sheet.resumeDirty();
  6.   });
复制代码

需要注意RangeSorting和RangeSorted事件仅能响应通过UI触发的排序活动,在实际业务场景中,不乏通过排序API在代码侧完成排序。那么,通过代码排序时其实已经在合适的时机触发了排序,在代码前后分别暂停标脏和恢复标脏即可,参考如下代码:
  1. sheet.suspendDirty();
  2. //  排序
  3. sheet.sortRange(0, 0, sheet.getRowCount(), sheet.getColumnCount(), true, sortInfo);
  4. sheet.resumeDirty();
复制代码

参考官网文档了解更多:
https://demo.grapecity.com.cn/spreadjs/help/docs/BestPractices/UsingsuspendDirtyandresumeDirty

0 个回复

您需要登录后才可以回帖 登录 | 立即注册
返回顶部