我有一个2列布局,右栏是一个可滚动的结果列表,最多有200个项目结果(基本上只有一个ul overflow-y: scroll;
设置)
我发现当您滚动时,右栏会导致一些jank(在低端硬件上特别明显)。
在Chrome时间轴中,我可以看到一些主要的"更新层树"我滚动列。 有什么方法可以弄清楚为什么"更新层树"是如此冗长,CSS属性影响速度最快? 当我点击它时 - 只是告诉我它运行的时间和其他信息。
我的每个人都有一些表现不佳的CSS(例如过滤器,变换,盒子阴影等) - 如果我逐个删除每个SASS文件,它会提高滚动性能(并且一旦删除所有CSS,最终会删除jank),但很明显很难确定哪些css属性没有执行此操作。
我想知道我是否遗漏了铬时间轴中可能对此有所帮助的内容?
我尝试使用will-change
CSS属性将滚动提升为不同的图层/强制硬件加速 - 但这并没有太大的区别。
滚动时也没有执行javascript事件。
限制少于200件物品不是一个选择。
我已经设置了一个这样的例子(我知道它有更长的项目列表,但这仅用于演示目的): https://github.com/jooj123/jank/blob/master/scroll.html
真正有趣的是,如果我删除overflow-y: scroll;
(在上面的示例中的.map-search__结果中),滚动变得非常平滑并且jank消失 - 为什么这会产生如此大的影响?
这是Chrome时间轴(基本上只有很长时间"更新层树"部分):
Paul's answer about will-change: transform
is spot on,特别是这个花絮帮助:
"添加will-change:transform;。一旦添加,"重新绘制滚动" rect已经不见了。"
但要小心,因为它不会总是适用,具体取决于您的代码库,检查滚动性能问题指示器以确保"重新绘制滚动"关闭,对我来说,我还必须禁用在其中一个子div中设置的-webkit-clip-path
属性(在我的实际代码库中 - 而不是在提供的演示中),请参阅:
答案 0 :(得分:26)
我试了your test page并看一看。
首先,对于滚动性能问题,我喜欢翻阅“渲染”面板中的一些复选框:
我们可以立即看到这个div被称为“重新滚动”。然后,您可以在实验“图层”面板中验证:
(我在树中右键单击并选择“显示内部图层”btw)
现在大的“更新层树”成本通常是由很多层或一些尺寸非常大的层引起的。在这种情况下,我们真的没有。但是我们确实有一个滚动图层,它不会被合成滚动。
复合滚动==快速滚动==通常是默认值。但在这样的情况下,我们回到“主线程滚动”,这真的很慢而且很糟糕。从好的方面来说,crbug.com/381840即将修复,应自动修复此测试用例。好极了!但我们现在可以解决它。
你确实提到你试过will-change
并且它没有效果,但是自己尝试一下效果很好。它属于overflow
设置的元素,在本例中为.map-search__results
选择器。添加will-change: transform;
。一旦添加,“重新绘制滚动”矩形就消失了。然后用时间轴进行测量,它会更好。
这是一个前/后视图:
祝你好运!答案 1 :(得分:4)
如果在滚动时您的问题明显可见,您可以在开发人员工具中打开时间轴和样式标签,取消选中适用的样式在样式选项卡中逐个查看元素,看看它如何影响滚动。这样,您可以独立测试每个样式规则,而不是整个CSS文件。如果您在CSS中使用 sourcemaps ,您应该可以轻松地在实际的CSS文件中找到违规规则并进行调整。
如果您不熟悉使用样式标签:打开Chrome开发者工具,请使用检查工具(开发人员窗格的左上角)选择您怀疑可能会给您带来问题的项目。所选元素关联或覆盖的所有样式都将列在样式选项卡中。然后你可以逐个关闭它们。您也可以使用检查器深入挖掘嵌套项目的深度。
<强>更新强>
我在编辑后删除了代码并仔细查看了它。我注意到你的溢出就在你的ul
项目上。就个人而言,我从来没有在ul
上使用溢出(通常更喜欢像div
这样的容器),所以出于好奇,我从overflow-y:scroll
删除了ul
并将其放入在ul的包含div .right-content
(并将其高度设置为100%),并且janky滚动消失了。
至于为什么,我只能推测,但我认为它与您滚动的项目数量有关。当您的溢出在UL上时,您将直接滚动所有这些子li
项。当它在包含div
时,你实际上只滚动ul
,所以我相信这个过程在计算移动项目的定位时确定的数学要少得多。 1 div定位调整与数百个li进行调整。
如果您比较上图中的时间轴,您会看到差异。顶部的是overlflow-y:scroll
上ul
的原始版本。您可以将鼠标悬停在更新树过程中的所有小行上,并看到有数百个项目正在绘制。这些是您的li
项。第二个时间轴是我从ul
中删除溢出并将其应用于包含div
的版本。您可以在此时间轴中看到更新树过程只有一个要绘制的项目是ul
。如果您查看项目的尺寸,您也会看到尺寸的差异。