如何解决使用 chrome devtools 调试滚动卡顿 “更新层树”
在 android 上,滚动在我正在构建的 React 应用程序的聊天提要中非常卡顿。在检查性能面板中的 devtools 时,我可以看到大量时间用于渲染
我尝试通读了许多资源
- https://gist.github.com/paulirish/5d52fb081b3570c81e3a
- https://developers.google.com/web/fundamentals/performance/rendering/avoid-large-complex-layouts-and-layout-thrashing
- http://jankfree.org/
- https://www.html5rocks.com/en/tutorials/speed/layers/
- https://calendar.perfplanet.com/2013/the-runtime-performance-checklist/
- https://www.html5rocks.com/en/tutorials/speed/high-performance-animations/
- https://chromium.googlesource.com/chromium/src/+/master/docs/speed/debug-janks.md
- https://www.chromium.org/developers/how-tos/trace-event-profiling-tool/using-frameviewer
- Reducing scroll jank when using overflow-y: scroll;
- https://developers.google.com/web/fundamentals/codelabs/web-perf
- https://www.html5rocks.com/en/tutorials/speed/scrolling/
- https://www.html5rocks.com/en/tutorials/internals/howbrowserswork/#Style_Computation
- https://www.html5rocks.com/en/tutorials/speed/rendering/
- http://www.chromium.org/developers/design-documents/gpu-accelerated-compositing-in-chrome
我尝试了很多方法,但都没有产生重大影响。
- 我已禁用所有
:hover
选择器。 - 滚动期间没有任何类发生变化,我已经通过
subtree: true
[0] 父元素上的突变观察者验证了这一点。 - 列表中的元素没有
mouseEnter
或mouseLeave
事件侦听器。 - 我在 scroll 期间没有读取或写入
offsetHeight
、scrollTop
或此列表中的任何其他值。我在适用的情况下使用InersectionObserver
。 - 我尝试在每个列表项上应用
contain: layout
和/或在父项上应用contain: layout
。 - 我已尝试删除全局反应滚动事件侦听器。
- 我已从列表中删除了所有要呈现的图像。
- 我尝试将
will-change: transform;
应用于父级 - 我在渲染部分启用了“布局移动区域”、“图层边框”。
我唯一能做的有重大影响的事情就是改变基本布局:
html,body {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
overflow: hidden;
}
.scroll-parent {
height: 100vh;
overflow-y: scroll;
display: flex;
flex-direction: column-reverse;
}
到
html,body {}
.scroll-parent {}
后者仍然会产生定期的“更新图层树”事件,但它们并没有占用大量时间,更多的时间花在了“绘制”部分。
启用“渲染 > 图层边框”显示之前的 css 布局中有两个重叠的“组”tile。
问题是我需要身体上的前 overflow:hidden;
以避免工具栏在 ios safari 上自动隐藏。我也不认为性能应该这么糟糕,因为我有一个带有一些内部滚动的 div。 AFIK 滚动应该不会导致图层树更新,它应该只会导致合成?我也可以求助于虚拟化滚动,但我已经向下滚动了更长的页面而没有卡顿,所以我认为这只是另一种解决方法,而不是解决核心限制。
深入研究开发工具,我可以看到罪魁祸首似乎是“更新的图层树”,但我不确定从哪里开始。
我尝试了 chrome://tracing,但我不能说我知道我在看什么
我一直在研究一个最小的可重现示例。这与我所能得到的非常接近 https://codesandbox.io/s/test-layout-reflow-on-scroll-u1kjr?file=/src/App.tsx 在分析副本时有可观察到的“更新层树”标志,但性能几乎没有实际应用中那么糟糕。我把它归结为 CSS 复杂性要低得多,因此“更新的层树”在副本中运行得更快,但我可能不应该做出任何假设。
- 我可以采取哪些步骤来更好地分析可能的根本原因?
- 滚动过程中出现这么多“更新的图层树”事件是否正常?
[0]
observer.observe(element,{ subtree: true,childList: true,attributes: true,characterData: true })
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。