Derrick.Jiao 发表于 2022-3-18 14:43:33

大量使用autofit场景优化

在实际使用中,我们的数据往往都是非常多的,以一万行的数据举例,正常我们加载这些数据在表格中是毫无压力的。但是如果我们给这一万行的单元格都设置上了autofit自适应会有什么样的情况出现呢?答案就是需要花费非常多的时间去加载,性能相对较差。
我们看下这个demo,
这个是表单上的一些内容:



这个demo设置了10000行数据并且每一行都进行了autofitRow,那么带来的结果如下,可以看到数据以及前面的一些准备时间耗时都在一个非常小的范围。但是遍历调用autofitRow足足花费了接近18s的时间。


打开代码后,我们可以看到,其中已经用了挂起绘制和恢复,但是性能没有达到理想的一个状态。原因是与绘制不同,autoFitRow要考虑所有可见和不可见的单元格,然后是getText(getValue+format),考虑span,考虑高优先级选项,还有很多复杂的逻辑,因此就此demo来看,性能没有太多的提升空间。在这种情况下,他们一次自适应10000行,确实要花费这样的时间,而且根据数据集的大小,大小越大,花费的时间也越多。

所以,针对此问题变通的办法是,只对视图区域进行自适应,并在视图行改变时保持自适应,在这种情况下,所有的视图行都会显示正确的结果。简单理解就是我们只在用户看得见的地方做了自适应,看不见的区域还是与原来的一致。通过这个方案,即使数据集的大小变为1000000,也不会有性能问题。

我们可以看下更新后的demo,事件优化到了1/10秒


里面是怎么做的呢?我们需要获取视图顶部区域的行索引以及底部区域行索引,进行遍历设置自适应。
function autoFitViewportArea(sheet) {
                let topRow = sheet.getViewportTopRow(1), bottomRow = sheet.getViewportBottomRow(1);
                sheet.suspendPaint();
                for (var row = topRow; row <= bottomRow; row++) {
                  if (fitRowMap == void 0) {
                        sheet.autoFitRow(row);
                        fitRowMap = sheet.getRowHeight(row);
                  }
                }
                sheet.resumePaint();
            }



当通过下面的代码监听到滚动时,我们再调用上面定义的方法。注意,此示例只演示了纵向滚动,横向滚动也是同理。
spread.bind(GC.Spread.Sheets.Events.TopRowChanged, function (type, args) {
                  autoFitViewportArea(args.sheet);
                });

页: [1]
查看完整版本: 大量使用autofit场景优化