最新的Blink内核浏览器(如Chrome、Opera)存在奇怪的滚动行为问题

58

最近我一直在为Angular构建一个树形视图组件库,名为ngx-tree

问题

不久之后,我发现如何为这个库实现虚拟滚动功能以应对大数据集的性能,并在Firefox中使其正常运行,但在Blink内核的浏览器(如Chromium、Chrome、Opera)中,我被奇怪的滚动行为困扰。

演示链接

这是演示plunkr -- https://embed.plnkr.co/xMpmK5EBC46tDKpYFpw8 请参见下面的更新#1

情况

  • 在Firefox、Edge和IE 11中,我的带有虚拟滚动功能的库与平滑滚动预期一致。
  • 然而,在Chrome和Opera中,当我滚动到树形视图内的某些位置时,滚动条的位置(即滚动区域的scrollTop属性)会上下跳动,导致树形视图闪烁并且破坏虚拟滚动功能。

浏览器详细版本

  • Chrome - 59.0.3071.115
  • Firefox - 54.0
  • Edge - 40.15063.0.0

其他浏览器

在中国,有一些派生自Chromium项目的壳浏览器(如360安全浏览器、QQ浏览器、搜狗浏览器、UC浏览器),它们使用较旧版本的V8和blink,并且没有这种奇怪的滚动行为。

一些假设

这是由Chromium团队对滚动实现的优化(如平滑滚动)引起的吗?

希望能得到一些指导!(≧﹏ ≦)


更新 #1

演示链接已更新,包含事件日志:https://embed.plnkr.co/GpQBZsguhZZOQWWbZnqI/

在打开开发工具查看日志之前,必须先测试滚动条

我需要进一步解释虚拟滚动是如何工作以及什么导致了闪烁。

首先,请查看虚拟滚动的设计

虚拟滚动的关键点在于,我们创建一个与没有虚拟滚动工具的区域相同大小的虚拟滚动区域。因此,在最佳情况下,滚动区域的滚动条位置不应该改变,直到某些预期事件触发其更改。对于滚动事件,我们会在每个动画帧更新视图。

在一个高度固定的滚动区域内,我们假设当我们适当模拟未渲染元素的高度(计算精度可能会有一点偏差)时,scrollTop属性不会以较大的百分比变化。然而,根据我的观察结果,闪烁系列浏览器似乎执行了一种不同的策略来更新可滚动元素的scrollTop。它更新scrollTop的时间与非闪烁系列浏览器不同。这是目前我所发现的所有内容。

示例gif

这里我制作了一些gif来展示Chrome、Firefox和Edge的输出。

Chrome

Chrome gif

火狐浏览器

Firefox gif

边缘

Edge gif


3
只凭少量的分析,这似乎是函数 setNative (zone.js) 的一个错误。它涉及处理 requestAnimationFrame,但需要更深入的挖掘。发起者是在 zone.js 的第 1522 行反复调用 setNative.apply(window, args)。这可能也是由于与其他库混合使用造成的,但当其他浏览器正常时...... - bigless
5
我需要说明的是,我在Chromium问题跟踪器上找到了一个相关问题:https://bugs.chromium.org/p/chromium/issues/detail?id=727239 - e-cloud
浏览器可能会返回一些不应该返回的东西,从而破坏了 zone.js 的处理。但如果这与浏览器有关,那我算什么呢 ;) 希望它能很快得到修复。祝好运 ;) - bigless
1
我甚至无法运行提供的演示plunkr。 - Kiran Shakya
1
你尝试过在 chrome://flags/ 中禁用 平滑滚动 吗? - Sanxofon
显示剩余8条评论
1个回答

2
你正在从 virtual-scroll-demo-branch 分支拉取库:
'ngx-tree': 'https://rawgit.com/e-cloud/ngx-tree/virtual-scroll-demo-branch/src/lib',

那个分支落后于主分支105次提交。它错误地在其中一个内部元素上设置了margin-top。这个问题在更新版本中已经修复
编辑:开发者实际上在他们的提交信息中引用了这个Stack Overflow问题链接

事实上,我是开发人员。是的,我使用另一种方法来避免这个问题。虽然那个分支有点旧,但核心算法几乎相同。“它错误地设置了margin-top”可能不正确,因为它在Edge和Firefox中可以工作。 - e-cloud

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接