-
Notifications
You must be signed in to change notification settings - Fork 522
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Flash of blank space in data scroller use case #187
Comments
Set a larger rootMargin and you will be notified a little in advance before your visible range is actually on screen. That parameter was added specifically for the "infinite scroller" use case. Will that work with your requirements? |
Throw scrolling can move in increments of 1000s of pixels. Keeping that wide a margin around the viewport is too expensive in my case. |
IntersectionObserver is not really intended to drive per-frame layout. As mpb@ pointed out, you can use root margin to give yourself some extra runway to respond to scroll events, but the fundamental problem remains. |
There's no solution in any modern browser that will guarantee no flashes of blank space because scrolling happens on a different thread from JS. There are some scenarios under which browsers will scroll on the JS thread, but they are becoming increasingly rare as browsers further optimized their pages. Our conclusion from that was that the only solution for infinite scrollers is to have some amount of runway. Definitely open to other ideas. The fastest thing you could do today is have a scroll listener that does a double requestAnimationFrame and calls takeRecords. In that world you'd always miss exactly one frame. I guess you can force a layout in your scroll listener and avoid missing a frame, but you'd still have the runway problem with threaded scrolling. How does codemirror handle threaded scrolling today? |
So I guess the idea of providing client code with some hook to force scrolling of a given container to happen on the JS thread so that it can intercept it is considered undesirable because 'people will abuse it'. I can kind of understand that position, but it is unfortunate that it breaks this use case, forcing people to completely hijack scrolling—which leads to an even worse user experience.
It doesn't, that's why I'm looking for a better solution, which brought me here. Feel free to close this if you decide that guaranteed JS-free scrolling is more important than data scrolling libs. |
I don't think there's a universally correct answer for this, but I will say that based on experience, users are more bothered by scrolling-induced jank (i.e. dropped frames) than by painting stale content. IntersectionObserver is intended more as an after-the-fact reporting mechanism, and one if its design goals is to avoid impacting rendering performance. As you point out, there are other mechanisms you can use to intercept scroll events and avoid painting stale content, albeit with the side effect that you may drop frames. Which approach you choose is really up to you. |
@szager-chromium wrote:
I was claiming that there aren't such mechanisms, that I'm aware of. |
(I'm the maintainer of CodeMirror, a code editor that supports large documents by only drawing the range around the current viewport.)
So the spec says
which means that drawing happens first, and observers are notified afterwards. I understand the reasons for this. However, that does mean that in the 'data scroller' scenario, there doesn't appear to be a way to prevent users from seeing the content flash into view as they scroll quickly (yank scrollbar or throw-scroll). This may not sound like a big deal, but in CodeMirror, users repeatedly and insistently complained about this until we fixed it (with a bunch of scary tricks some of which are starting to fall apart now that browsers delay scroll events more).
If you run the little demo below, which sets up a scrolling element with two colored elements inside of it, and colors the bottom red one blue as soon as the observer tells us it has become visible, you can easily see a flash of red when you scroll quickly.
Has a way to avoid this been discussed? Is it considered too problematic for performance, or is this whole use case not really in scope for this proposal?
The text was updated successfully, but these errors were encountered: