记一次性能优化(埋坑与填坑的过程)
接到一个需求,需要实现拖动单元格来自定义地调整宽度,啪啪啪,敲完代码,调试完工😊。
测试发现在单页列表条数达到一定数量时会在拖动的过程中出现明显的卡顿,会影响到用户的体验。
根据情况,我猜想是由于在列表拖动的过程中,随着鼠标的拖动,列表每一行的宽度都跟随进行了调整,也随之导致了卡顿的情况。于是我决定在拖动的过程中,只调整显示区域列表的单元格的宽度,在拖动完毕之后再调整所有行的该列宽度。策略就是在列表上下滚动的过程中,为处于显示区域的行添加一个特征class,在拖动的过程中只调整拥有该特征class的行的列宽度。
写完代码之后发现,由于在监视scroll事件的过程中,需要遍历每一行,并对行进行class赋值,频繁的操作导致列表上下滚动的时候也出现了卡顿的问题。
为了解决这个问题,我决定用setTimeout实现只在列表停止上下滚动的时候执行遍历操作,从而减少卡顿的情况。
var $body = this.$el.parent()
it = 0,
self = this;
$body.on("scroll",function(){
clearTimeout(it);
it = setTimeout(function(){
self.getMethod("resizeSomeColumn")
},500)
})
写完这些之后,再去查看列表宽度调整时的卡顿的情况,发现情况依旧😣。
于是想,不能这么瞎猜了,google 之后发现需要Chrome DevTools 去分析卡顿产生的原因。
在Timeline 面板,录制了宽度调整的过程,发现大多Frame的 fps只有2~5,在跳到Layout Tree(需在Chrome开启该工鞥) 查看之后发现,每次列表宽度的调整,都会导致整个列表的重新布局,如此导致了卡顿的情况,即使只调整了显示区域的行的列宽度,但整个列表还是重新布局了。
回过头来发现,为了在宽度调整的过程中不出现显示错位的情况,代码中有存在当行内列宽度调整的时候,就去的调整整个列表宽度的代码。
调整了这些代码,在列表宽度开始调整的时候就将列表包裹块的宽度增长到一定宽度,宽度调整完毕后在计算设置包裹块的宽度,移除了在拖动过程中的列表包裹块的宽度调整。
这样修改后,列表宽度调整过程中的卡顿不再明显,但Timeline面板中依旧显示存在很多long frame,还需要进行优化,以达到更好的显示效果。