-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Scrolling jumps #2646
Comments
One way to solve this would be getting the image sizes from the server and load a blank rectangle the same size as the image will be as a place holder until the image loads. Telegram also does this along with loading a blurry version of the image until the full thing has loaded |
what's the tl;dr on this? I think the relevant bugs are fixed? |
assuming it's fixed |
it's very much a problem still. i'm not sure what triggers it, but certainly rooms with images or URL previews can jump around enormously when you are backpaginating, landing you on an entirely different pages. it used to be fine (about 6 months ago) |
this is reproduceable right now in #riot-dev |
gah - i've seen this about 10 times in the last 24 hours, but on trying to get a video i couldn't reproduce it. i think it may be particularly obvious when the server is slow (so you have more time to stare at the spinner, and perhaps for a race to happen). Or it may be specifically related to rooms with URL previews. |
Having turned URL previews on on my homeserver, I have noticed more jumping. Thinking about it, the previews have a preset height - we should make them that height whilst they're loading, surely? |
Ironically i've only spotted this when scrolling backwards, but in general i tend to only ever read scrollback in reverse chronological order anyway (given read markers are still flakey). I just saw this (using #dendrite-dev) on a room with no images at all, only URL previews... however, I wonder if this is a separate problem; that simply we're lazy-loading the URL previews on content which has just been paginated into the top of the screen, which cosmetically looks identical to the scroll offset jumping.... |
whoops.. |
Part of the scrolling jumpiness seems to not be to do with things that change in size (images loading etc), but the way messages are added and removed. What it looks like is before any filling or unfilling takes place, the scroll position is saved. After the filling or unfilling has completed, the scroll position is restored by calculating the new scrolltop from the old one. I tried measuring the time between most recent save and restores, and I got values ranging from 10ms to 400ms, and a couple that were more than a second! If that's the case, it's not surprising if it's jumping around a bit. Maybe what happens between the save and the restore could be sufficiently optimized. I'm not sure if things like image downloads happen in this time (which would explain some of the large timings), or if it would be possible to do them outside the save-restore window. EDIT: It looks like all the network stuff for filling is happening inside the save-restore window. Also, I tried scrolling in a room with url previews, and I was regularly getting timings of over half a second, and it was very jumpy! |
I'm getting some quite serious scroll jumps on |
I've done a bit of digging and have found that the save-restore window is indeed the problem here. This was a reproduceable scroll jump when scrolling back (earlier) through the timeline from https://riot.im/develop/#/room/#riot:matrix.org/$15034002194798QLmXG:cervoi.se. It wasn't always in the same place and could be explained by the inline md-style mxc images that were being used in nearby messages.
The order of events is:
On step 3, if the scroll state had been restored following the timeline changing, the next scroll event would have caused the following save to be done in the correct, non-jumped position. Other casesI've seen cases in other rooms where a jump has happened seemingly without inline images being present and will investigate. |
Having checked the maths on our impl, it looks sound. The only issue is that we save the scroll state at times where it might not be correct (i.e. following a change in scrollHeight or scrollTop that was not accounted for). Perhaps our method for getting the previous scroll state should be adjusted such that we know that the calculations we're doing at this exact point in time are based on correct scroll state. This might mean ignoring scroll state saves that are a literal jump in the timeline. |
This is getting worse and worse; especially in E2E rooms I regularly see jumps of more than a page whilst scrolling through scrollback :( |
This is quite bad on Quantum, even with smooth scrolling disabled. |
So somehow we weren't calling onWidgetLoad from MImageBody when an |
I seemed to have neglected to doc this but I had an attempt at using Chrome's new support for scroll anchors and plonked it a branch. Here's the PR to merge said branch, but it's just a POC; not for merging. It answers the question "what happens when we disable our own scroll management and let Chrome do it's thing". The answer is that it works remarkably well (from memory) apart from when the top of the page appears in the viewport. (See matrix-org/matrix-react-sdk#1787) The issue for me is that we have an implementation that saves & restores the scroll position. In theory we could have one the relies entirely on a new technology - web anchoring. Interestingly, Chrome does this remarkably well and I even tested this in the past with Riot. The conclusion here was that until all major browsers support this, we continue to maintain a single code path as we don't have capacity to maintain two different code paths for the same component. It's possible that we're missing out though. |
Empirically, back paginating in an e2e room seems very scroll-jumpy, especially when the probability of a jump is increased by scroll events being fired more frequently (i.e. when using a Mac trackpad). See #6265 |
For me this happens very severely in the Android version. I usually click "Jump to first unread messages" there and start to scroll down. As soon messages are loaded as part of the scroll process the view jumps for me, which always disturbes the reading flow. I can reproduce this on basically any channel that I am in (normal IRC bridged rooms, so text messages only). |
@Ablu that is an issue with https://github.com/vector-im/riot-android, please report it in that repo. |
Ah. I thought the code was shared since the Android client felt like the
wrapped web version. But thanks, I will see whether this is already
reported there! :)
… |
I think the E2E issue is probably due to fixupHeight() not considering the fact that E2E images are sent with a clientside thumbnail which is typically smaller than the 800x600 bounding box (perhaps)? |
Firefox console says:
From https://developer.mozilla.org/en-US/docs/Mozilla/Performance/Scroll-linked_effects:
|
this is obsoleted by #8565 |
The logic handling [un]pagination and scrolling needs a bit of thinking about. What we really want is smooth scrolling through the timeline, with pagination and unpagination, with the assumption that events could change size or be re-rendered at any time.
Occasionally the scroll position "jumps" as images are loaded (see #2640, #2624) and possibly when new messages arrive (#2619) or just when reading backlog (#2138, although this issue was submitted before the most recent unpagination logic was merged, and so may not be useful at this point).
The
ScrollPanel
concept of stickiness appears to be lacking in these cases. Given that the bugs are seemingly to do with scrolling to the top of the screen, and given thatScrollPanel
only has the concept ofstickyBottom
(and notstickyTop
) https://github.com/matrix-org/matrix-react-sdk/blob/v0.8.0/src/components/structures/ScrollPanel.js#L66, maybe we should have more control of "sticking" and instead of just sticking to the bottom, perhaps we could stick to an arbitrary point in the timeline (e.g. keep the event under the mouse/at the top/at the bottom in the same place). UPDATE: this is already done, and it's most likely that_onWidgetLoad
is not being called when something changes height in theMessagePanel
.The solution to this might be being more sensible with unpagination. At the moment, events are unpaginated when they are really (arbitrarily) far away from the view-port (see matrix-org/matrix-react-sdk#567 for the latest fix).
Update: #2624 (encrypted images mess up scroll position) should have been fixed by matrix-org/matrix-react-sdk#577
Update: #2744 says that encrypted videos mess up scroll position still
To prevent future regressions and hopefully get reliable visibility on these bugs, it'd probably be a good idea to add tests that can determine that these "jumps" do not happen during [un]pagination, event tiles changing size, new messages arriving, etc. A "jump" probably can't simply be defined as a big change in
scrollTop
of theScrollPanel
, because this happens when events are [un]paginated. A better definition could be "when an event in view changes position without a scroll event having been fired".The text was updated successfully, but these errors were encountered: