Issue metadata
Sign in to add a comment
|
Chrome scroll restoration does not work when the "next" page is shorter than the "previous" page
Reported by
erik.ziv...@gmail.com,
May 11 2017
|
||||||||||||||||||||||
Issue descriptionUserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Example URL: https://bes.github.io/scroll-restore-test/ Steps to reproduce the problem: 1. Go to https://bes.github.io/scroll-restore-test/ 2. Follow the instructions. TL;DR: scroll to the bottom of the page and try the two links. What is the expected behavior? Scroll restoration should work properly regardless of if the "next" page is long or short. This works properly on Firefox and Safari, but not Chrome or Opera. What went wrong? Scroll restoration does not work when going from a "long" to a "short" page and then back to the "long" page. Does it occur on multiple sites: Yes Is it a problem with a plugin? No Did this work before? N/A Does this work in other browsers? Yes Chrome version: 58.0.3029.110 Channel: stable OS Version: OS X 10.12.4 Flash Version: The source code for the example can be found at https://github.com/bes/scroll-restore-test
,
May 12 2017
Updated github repo & and example URL with MS Edge result (passes both tests).
,
May 15 2017
Able to reproduce the issue on windows 7, Ubuntu 14.04 and Mac 10.12.4 using chrome version 58.0.3029.110 and canary 60.0.3099.0. This is regression issue broken in M49.Please find the bisect information as below Narrow bisect:: Good::49.0.2620.0 -- (build revision 369070) Bad:: 49.0.2621.0 -- (build revision 369281) Change Log:: https://chromium.googlesource.com/chromium/src/+log/fa15e24628fbc6f499f6d5ea8ec8531e83d5bed0..91e6e97ccdc0d6cdd4e3543102ccc0f90a6da004 Unable to find the suspect from the CL.Could any one from dev team please look into this issue. Thanks,
,
May 18 2017
Weird, I can definitely repro. Chao, mind taking a look?
,
May 18 2017
I test it on Mac. Long page restored to a wrong position. Short page did not restore. Suspect it is from this cl 91e6e97ccdc0d6cdd4e3543102ccc0f90a6da004.
,
May 25 2017
I tried to not restore scroll position until page has enough content. It can fix this issue and not break issue 574487 , but lots test case failed. majidvp@ WDYT?
,
Jun 21 2017
> I tried to not restore scroll position until page has enough content.
The proposed fix for waiting on the page to have enough content is something we
already do for scroll restoration. In particular during a navigation we re-try
restoring the scroll position every time the page size changes (until it is
successful). However note that we only do so *during a navigation* which means
that blink doesn't try to restore scroll position once navigation is considered
complete.
I think this I think the above model gives a predictable and mostly correct
behavior. In particular, once navigation is finished, the page content can
change (and resize) to reflect a transition in the application state. Trying to
restore the old scroll position for this new application state is incorrect. In
fact, this is in exactly what CL in #3 fixes by correcting a bug where our
navigation state was not correctly updated at the end of a same document
navigation.
A same document navigation (e.g., when clicking back/forward on a entry that was
added via history API) is considered complete after "popstate" event is
dispatched. So if the page content is not at the right size after popstate we
may not be able to restore the scroll position correctly.
I suspect the above page is not creating its page content as part of the
"popstate" event which explains the issue in Blink. chaopeng@ can you look at
the page and confirm this is the case. I am also curious how Safari/Firefox behave
differently here as it seem they manage to restore position even when resize is
occurring after popstate.
I can see two potential fixes here:
- Change Blink current definition for completion of a same page navigation to
allow some async work. Perhaps we can have "restore scroll position" to
occur not just immediately after popstate event but also once all the tasks
posted by popstate are serviced. Note sure if this is even possible.
- A more intelligent scroll anchoring logic that is not position dependent.
This allows us to decouple scroll restoration from exact semantic of
navigation. For example I think something like Scroll Anchor Serialization
( Issue 734679 ) can potentially fix this.
/cc skobes@ and japhet@ in case they have ideas here.
,
Jun 22 2017
Scroll anchor serialization won't help if the content is loading after the navigation is finished. I think we need more investigation of what's happening in this test case.
,
Jun 26 2017
I agree we need more investigation/evidence before deciding to change current behavior. chaopeng@ is going to look into this. In particular, I am skeptical that any heuristic that tries to guess when the SPA UI has changed enough to correctly "restore scroll position". So I prefer the current simple model + existing escape hatch (i.e., history.scrollRestoration = 'manual';). Regarding the scroll anchor serialization suggestion, the idea was to wait on restoring the scroll position until the "anchor element" becomes available even if it is after when we consider the navigation to be complete. Again, this depends on actually investigating and confirming that this is needed.
,
Jun 29 2017
Details of this case: This case is using react + react router + history. 1. The popstate event listener is history createBrowserHistory handlePopState [1]. 2. react is using their home make vdom. They actually update DOM tree in react-dom DOMLazyTree replaceChildWithTree [2]. Add a break point at [2] we can see the stack is not async. Add log to the FrameLoader::LoadInSameDocument[3], we can see no Layout happens in popstate. That is why the content size is incorrect. [1] https://github.com/ReactTraining/history/blob/93992e8596e2cf97024b69915eb45b4da871c736/modules/createBrowserHistory.js#L90 [2] https://github.com/facebook/react/blob/b1768b5/src/renderers/dom/stack/client/DOMLazyTree.js#L82 [3] https://cs.chromium.org/chromium/src/third_party/WebKit/Source/core/loader/FrameLoader.cpp?rcl=588d17e4f4b4d8f73bca38924c24037ae4717dea&l=563
,
Jun 30 2017
This is a simple example for this issue. URL: http://ht.chaopeng.me/scroll-restore-incorrect.html
,
Jul 7 2017
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/87030295c8093dfd90b209aa099f080b278a8289 commit 87030295c8093dfd90b209aa099f080b278a8289 Author: chaopeng <chaopeng@chromium.org> Date: Fri Jul 07 16:19:13 2017 Force layout for SameDocumentLoad when content size is not enough for restore. This issue is caused by in navigation backward (LoadInSameDocument) for Single Page App, developer change DOM in onpopstate but not trigger a layout, then we don't have correct content size for restore scroll position. In this patch, we add a layout in RestoreScrollPositionAndViewState when the size is not enough for restore scroll position. This change should only effect SameDocumentLoad. Bug: 721262 Change-Id: I2b2956828634884b926b4c5b3073210170f42263 Reviewed-on: https://chromium-review.googlesource.com/556979 Commit-Queue: Jianpeng Chao <chaopeng@chromium.org> Reviewed-by: Majid Valipour <majidvp@chromium.org> Reviewed-by: Mike West <mkwst@chromium.org> Cr-Commit-Position: refs/heads/master@{#484944} [add] https://crrev.com/87030295c8093dfd90b209aa099f080b278a8289/third_party/WebKit/LayoutTests/fast/history/scroll-restoration/scroll-restoration-same-doc.html [modify] https://crrev.com/87030295c8093dfd90b209aa099f080b278a8289/third_party/WebKit/Source/core/loader/FrameLoader.cpp [modify] https://crrev.com/87030295c8093dfd90b209aa099f080b278a8289/third_party/WebKit/Source/core/loader/FrameLoader.h
,
Jul 7 2017
|
|||||||||||||||||||||||
►
Sign in to add a comment |
|||||||||||||||||||||||
Comment 1 by kavvaru@chromium.org
, May 11 2017