Weird scroll behavior in latest Blink-included browsers (like Chrome, Opera)

JavascriptAngularGoogle ChromeScrollTreeview

Javascript Problem Overview


Recently I've been working on building a tree-view component library for Angular, as ngx-tree.

Problem

Soon after I figured out how to implement a virtual-scroll feature for this library for performance with large data set, and got it to run properly in Firefox, I am trapped by a weird scrolling behavior in Blink-included browsers(like Chromium, Chrome, Opera).

> Here is the demo plunkr -- https://embed.plnkr.co/xMpmK5EBC46tDKpYFpw8</del> see Update #1 below

Situation

  • In Firefox, Edge and IE 11, my library with virtual scroll feature works in expectation with smooth scrolling.
  • However, in Chrome and Opera, when I scroll to some positions inside the tree-view, the position of the scrollbar(which is the scrollTop property of scroll area) jump up and down, causes a flickering tree-view and break down the virtual-scroll feature.
browser detail version
  • Chrome - 59.0.3071.115
  • Firefox - 54.0
  • Edge - 40.15063.0.0
other browsers

In China, there are some shelled browsers derived from Chromium project(like 360se, QQ browser, Sogou browser, UC browser) with older version of V8 and blink. And they don't have that weird scroll behavior.

Some Assumption

Is it caused by some optimization on the scroll implementation(like smooth scrolling) by the Chromium team?

Hope to get some guides!!! (≧﹏ ≦)


Update #1

> Demo link update with event log: https://embed.plnkr.co/GpQBZsguhZZOQWWbZnqI/

One must test the scrolling before opening devtool to see the logs

I have to explain a little more how the virtual-scrolling works and what's causing the flickering.

First, see the design of Virtual Scrolling.

A key point of virtual scrolling is, we create a fake scroll area the same size as that area without virtual scrolling instrumented. So in an optimal situation, the scrollbar position of the scroll area ought not to change until some expected events trigger its changes. For scroll event, we update the view for every animation frame.

Within a height-fixed scrolling area, we assume a truth that the scrollTop property will not change with a large percentage, if we simulate the those unrendered elements' height properly(there could be a bit of deviation for the calculation accuracy) within an animation frame.

However, based on my observed results, the blink-series browsers seems to perform a different strategy to update the scrollTop of the scrollable element. Its timing to update the scrollTop is different than none-blink-series browsers. That all I've figured out so far.


Sample gifs

Here I made some gifs to show the output of Chrome, Firefox, and Edge.

Chrome

Chrome gif

Firefox

Firefox gif

Edge

Edge gif

Javascript Solutions


Solution 1 - Javascript

You're pulling the library from the virtual-scroll-demo-branch branch:

'ngx-tree': 'https://rawgit.com/e-cloud/ngx-tree/virtual-scroll-demo-branch/src/lib',

That branch is 105 commits behind master. It incorrectly sets margin-top on one of the inner elements. This is fixed in newer versions.

Edit: The developer actually referenced this Stack Overflow question in their commit message.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questione-cloudView Question on Stackoverflow
Solution 1 - JavascriptZenexerView Answer on Stackoverflow