4 ms·
There are some intricacies about when to reset the scroll position, if ever. Here's one way: https://codepen.io/xorgy/pen/yYdVoY https://codepen.io/xorgy/pen/y
by microcolonel 6y ago
There are some intricacies about when to reset the scroll position, if ever.
Here's one way: https://codepen.io/xorgy/pen/yYdVoY https://codepen.io/xorgy/pen/yYdVoY
- chrismorgan 6y agoThis way is very, very wrong in how it resets the scroll position: it essentially assumes synchronous scrolling, and falls apart completely if that isn’t the case—and it hasn’t been for some years. By “synchronous scrolling” I mean that reading scrollTop gets you the true current value, and that setting scrollTop sets the value immediately. These used to be the case, but scrolling is handled off-thread now, so the values you read may not be the actual values, and your setting the value may clobber scrolling that has taken place since your code started being called. (This also means that any fake scrolling you do will lag behind reality—one of the reasons to use fully native scrolling if you possibly can. This has been unavoidable since asynchronous scrolling came in.) The effect is that on devices with precise scrolling and inertia especially, it will make scrolling extremely slow, because essentially most of the scrolling delta is being lost. I see this problem very commonly in systems that have tried to implement their own scrolling. For reference, I’m using Firefox on a Surface Book. A generous two-finger swipe that should scroll by several thousand pixels is in your demo (when further instrumented to keep totals of deltas) only perceiving several dozen pixels of delta. In short: you mustn’t ever reset the scroll position.
- microcolonel 6y agoOn Chrome based browsers on Android at least, it works perfectly fine with momentum. It even does accumulating momentum, I can easily get it up to 6,000px/frame. Does this not work properly on iOS?
- chrismorgan 6y agoAlthough in theory the problem is universal, in practice the problem only appears when the user is using touchpad-based scrolling; touch-based scrolling is typically unaffected. But it’s all happening because you’re interacting with the scroll position in a way that is incorrect within the models of the platform, reading and writing the scroll position as though it were atomic and sequentially consistent when it’s not, so it could break in more situations at any time. It’s thus much better to avoid the technique and work in a way that is supported. (I’ve decided to change the terms I’m using from synchrony to atomicity. For users familiar with that domain: the problem is essentially equivalent to the scroll position being atomics that are changed from another thread, but you’re doing a load and a store, probably with relaxed sequential consistency, rather than using an atomic swap operation, or a mutex lock over a non-atomic. There is no recourse while using this technique because the scroll position is not exposed as an atomic or something lockable.)