Closed Bug 1524281 Opened 5 years ago Closed 5 years ago

[Scroll Anchoring] Scroll position is not maintained after page reload

Categories

(Core :: Layout: Scrolling and Overflow, defect, P2)

defect

Tracking

()

RESOLVED DUPLICATE of bug 1546027
Tracking Status
firefox66 + wontfix
firefox67 - fix-optional
firefox68 --- affected
firefox69 --- affected

People

(Reporter: asoncutean, Assigned: rhunt)

References

(Depends on 1 open bug, Blocks 1 open bug, )

Details

Attachments

(2 files)

Attached video screencast issue.mov

[Affected versions]:

  • 66.0b3 (20190128143734)
  • 67.0a1 (2019-01-31)

[Affected platforms]:

  • Windows 10 x64
  • Mac OS 10.11
  • Ubuntu 18.04 x64

[Steps to reproduce]:

  1. Launch Firefox
  2. Go to https://www.rhs.org.uk/
  3. Scroll down (stop next to the Feedback button for better observation)
  4. Reload the page
  5. Look at the scroll position

[Expected result]:

  • The scroll position is the same as before the reloading action.

[Actual result]:

  • The scroll position is not saved - (see the attached screencast).

[Regression range]:

  • Not a regression, this was introduced with the Scroll Anchoring feature - 66.0a1 (2019-01-11).

[Additional Notes]:

  • With the layout.css.scroll-anchoring.enabled set to false, the issue is not reproducible, the scroll keeps its initial position.
  • This issue can’t be seen on Chrome/Safari.

Sean, can you triage and prioritize this bug with regards to our 66 release? Thanks

Flags: needinfo?(svoisen)

Sure, I can track this, and will wait for Sean's feedback on how important it is that we fix this before scroll anchoring goes to release.

I'd like Ryan to chime in here if possible. Ryan: Have you looked at other cases of this? I feel like we had other bugs where scroll position was not restored correctly, but bug 1519938 claims to be unrelated to scroll anchoring.

Flags: needinfo?(svoisen) → needinfo?(rhunt)
Priority: -- → P2
Flags: needinfo?(svoisen)

Based on e-mail thread, Ryan has started investigating, so assigning to him.

Let's keep tracking. I don't think this should block scroll anchoring going to release, but I'd like to know the root cause (and/or a reduced testcase) to better determine how frequently we might run into this beyond the site listed in the STR.

Assignee: nobody → rhunt
Flags: needinfo?(svoisen)
Flags: needinfo?(rhunt)

I'm having a tricky time debugging this issue. I believe this is caused by an interaction between loading, restoring scroll positions, and scroll anchoring.

It sounds like Chrome has had these with their implementation [1], and didn't have a solution for them.

Here's my fuzzy understanding of what's going on with this page. We store the absolute scroll offset before reloading the page. At some point when reloading the page, we scroll down to that absolute scroll offset. As loading continues, we perform scroll adjustments to keep the anchor in the same relative position.

The problem is that the content at the absolute scroll offset taken from a fully loaded page may be different from the content at that position while the page is loading. This can cause us to apply adjustments to keep that different content in the same relative position to the viewport.

This is happening on the page with the 'Please accept cookies' banner. The banner is about 60px tall. When we restore the scroll position and choose an anchor, it's not in the DOM. Then at some point later it's added, and we adjust downwards by 60px to keep our anchor valid. This causes us to end up below where we were looking at.

If you click 'Accept Cookies' and reload, you'll notice that we are closer to keeping the same scroll position, as it doesn't insert the banner after load.

There's also another adjustment caused by a layout flush triggered by a script during load. I haven't figured out that one yet. It's about the height of the navigation bar when it's floating. It's definitely not caused by a scroll event, as disabling firing those doesn't resolve it.

[1] https://github.com/WICG/ScrollAnchoring/blob/master/explainer.md#history-scroll-restoration

Okay, I've figured out what's happening to us here.

  1. User loads the page fresh

  2. A script appends 'flex' class to <html> which changes the layout of site-header, reducing height by 36px

  3. A script inserts 66px 'accept cookies' div

  4. User scrolls down 400px onto the animated hero banner

  5. User soft reloads the page

  6. We load the body and stylesheets then run into synchronous JS '/wwwroot/js/bundles/main.min.js?v=552'

  7. The script triggers a layout flush, causing us to apply scroll offset restoration [1]

  8. We scroll down 400px and select a scroll anchor

  9. A script appends 'flex' class to <html> which changes the layout of site-header, reducing height by 36px

  10. A script inserts 66px 'accept cookies' div

  11. We see that our anchor node has moved by (66px - 36px) and apply ~30px adjustment downward

Attached is a reduced test case.

The big question I have here is why isn't Chrome affected by this? They're affected by the reduced test case, and I can't find any special code that would handle this. It's possible there's another difference in what triggers layout flushes.

I'm not sure what we can do here. We could disable scroll anchoring while the page is loading, but I have a feeling that we'd miss applying important adjustments as things load.

It's possible there is a more 'narrow' definition of loading that we could use. Maybe once the HTML page has been completely parsed?

[1] https://searchfox.org/mozilla-central/rev/4587d146681b16ff9878a6fdcba53b04f76abe1d/layout/generic/nsGfxScrollFrame.cpp#4407

Blocks: scroll-anchoring
No longer blocks: 1305957
Depends on: 1529702

Untracking and marking as fix-optional for 67 given that the bug has unresolved dependencies and we are already at the midpoint of our beta cycle.

Blocks: 1546027
See Also: → 1555229

I filed ticket https://bugzilla.mozilla.org/show_bug.cgi?id=1555229 which is a duplicate of this one. Subscribing to this one...

Just my 2¢, I'm not sure if it's pixel based or percentage-of-the-page based. In my original example (https://forums.virtualbox.org) I see around 75 px of movement. In https://slashdot.org which is a rather longer page, the move is way, way more pronounced.

For the last 1-2 weeks, severe failure of the anchor scrolling capability continues for:

Firefox Quantum 67.0 (64-bit)
Chrome Version 74.0.3729.169 (Official Build) (64-bit)
Thunderbird 60.7.0 (32-bit)

Windows 10 Home Edition
64-bit Operating System, x-64 based processor

A similar issue is bug 1551534 on 'cnn.com' I'm going to mark that a duplicate of this to consolidate the issue.

I wrote up the cause in comment 6. The issue is that when loading a page we restore an absolute scroll position and anchor to the content near that position. But then the contents of the page change after load and we apply adjustments to keep the content in the same position, moving us away from the absolute scroll offset we had restored.

I think the ideal solution here is to disable scroll anchoring when we are restoring a scroll offset, and re-enable it when the user scrolls.

I wrote a patch to do this, but it's tricky. The scroll frame code doesn't distinguish between restoring a scroll offset from history and restoring a scroll offset from reframing. Reframing happens when we change certain CSS properties like writing-mode, and disabling scroll anchoring for these changes leads to test failures. [1]

[1] https://treeherder.mozilla.org/#/jobs?repo=try&revision=3e1d074784daf145c9529a2a946700c0dc6643a2

Reproducible on latest Nightly 69.0a1 (2019-07-04).

One interesting observation is that when the page being reloaded is in the background, the issue is 90% not observed. For example, if the page in question is in a tab that doesn't have the focus, and I right-click on that background tab and select "Reload", the page will reload with the correct scroll position.

Same behavior if I hit in quick succession "Cmd+R" (to reload the affected page), followed by "Cmd+Shift+]" to switch to the tab to the right of the affected page. After the affected tab is loaded, I can switch to it again, with the issue again not observed.

I say 90% of the time, because either I'm too slow to switch tabs, or for some other random reason that I haven't been able to record reproducibly.

Patch at bug 1546027 also fixes this.

No longer blocks: 1546027
Depends on: 1546027

Should be fixed by bug 1546027, let me know if not.

Status: NEW → RESOLVED
Closed: 5 years ago
Resolution: --- → DUPLICATE

heise.de was definitely fixed by this.
I tested 70.0a1 (2019-07-16) (64-Bit) on Windows 10 64bit Education Edition
Though I noticed that the scroll position sometimes differs because one of ad has a larger height than all other ads. (The article is lower then, because it's pushed downwards by the ad div. The ad itself is in an iframe in that div)
Chrome shows the same behavior, so the only reason I mention this, is because I don't know whether "scroll anchoring" was supposed to fix even that. (remembering the top most visible element and then refresh the page and scroll to that instead of the old scroll position, even when the height of the content above changes)
I'll attach a screenshot of the two ads that showcases the height difference.

amazon.de is way better than before but - unlike heise.de - not fixed completely.
https://www.amazon.de/BLACKROLL-PRO-Faszienrolle-Profi-Selbstmassage-Rolle-verschiedenen/dp/B00TDK7P24/

Screencapture:
https://youtu.be/gRz-l1Dqb7g
It starts happening when I scroll past sponsored products at 1:20. (before the fix it could also happen almost at the top of the page)
It doesn't happen on every refresh like before, but it definitely happens as you can see in the video.
At 2:57 I switch to pressing F5 instead of clicking the refresh button: as you can see F5 is not affected. At 3:55 I switch back to the button and the issue repeats itself.

Chrome doesn't show this behavior on amazon.

Can you file a separate bug for that and ni? me? I think I know what's going on. We get to the restored scroll offset but there's still parts of the page loading. So instead of keeping the scroll position we just start applying scroll anchor adjustments, which is not great.

I think the fix for that should also be relatively easy.

Here's the follow-up for amazon.de : Bug 1566513

About heise.de:
I only just noticed the commit message:
"Don't apply scroll anchor adjustments if we're restoring our scroll position."
So my guess is now, that the remaining page reload behavior on heise.de is fully intentional.

Yeah, scroll offset restoration is absolute, if refreshing the page creates more content then the behavior you describe is the expected one.

We could try to make scroll restoration relative, but that is a completely different effort :)

Regressions: 1566783
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: