Fix scroll timeout by waiting for the scroll position to settle#727
Open
otsch wants to merge 1 commit into
Open
Fix scroll timeout by waiting for the scroll position to settle#727otsch wants to merge 1 commit into
otsch wants to merge 1 commit into
Conversation
The scroll timeout addressed in chrome-php#678 happens when the page layout changes between the moment `Mouse::scroll()` computes the target scroll position and the moment it verifies that position. The verify loop waits for the page to reach an exact, pre-computed target. Once the layout shifts mid-scroll, that target can become unreachable and the loop spins until it fails with OperationTimedOut. While digging deeper into this I (assisted by AI I have to admit ;)) found several distinct ways to reproduce the issue, each added as a test case: - scrollShrink.html - the scrollable area shrinks right after the scroll starts. - scrollLock.html - an overlay/modal locks scrolling (body becomes position:fixed), so the maximum scroll distance drops to 0. - infiniteScroll.html - a lazy-loaded image above the current position finishes loading mid-scroll and shifts the layout (the typical infinite-scroll case). The fix proposed in chrome-php#678 (retry once when the recomputed distances changed) only covers the cases where the maximum scroll distance changes: it recovers the shrink and the lock case, but not the layout-shift case. There the page grows, the recomputed distance stays the same, and it still times out - so that fix unfortunately does not solve every variant of the issue. This change takes a different, more robust approach. Instead of waiting for an exact, pre-computed target, it observes the actual scroll position and treats the scroll as done once the position stops changing ("settles"). It reacts to what really happens on the page, so it handles a shrinking scrollable area, a scroll lock and a layout shift alike - without a retry, without a fixed target, and noticeably faster (no fixed timeout penalty on every occurrence). Alternative approach to chrome-php#678.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The scroll timeout addressed in #678 happens when the page layout changes between the moment
Mouse::scroll()computes the target scroll position and the moment it verifies that position. The verify loop waits for the page to reach an exact, pre-computed target. Once the layout shifts mid-scroll, that target can become unreachable and the loop spins until it fails with OperationTimedOut.While digging deeper into this I (assisted by AI I have to admit ;)) found several distinct ways to reproduce the issue, each added as a test case:
The fix proposed in #678 (retry once when the recomputed distances changed) only covers the cases where the maximum scroll distance changes: it recovers the shrink and the lock case, but not the layout-shift case. There the page grows, the recomputed distance stays the same, and it still times out - so that fix unfortunately does not solve every variant of the issue.
This change takes a different, more robust approach. Instead of waiting for an exact, pre-computed target, it observes the actual scroll position and treats the scroll as done once the position stops changing ("settles"). It reacts to what really happens on the page, so it handles a shrinking scrollable area, a scroll lock and a layout shift alike - without a retry, without a fixed target, and noticeably faster (no fixed timeout penalty on every occurrence).
Alternative approach to #678.
Proof
The videos below run all three reproduction cases (shrinking scrollable area, scroll lock, layout shift) back to back - first against the current code, then with this fix.
Before (current code): every case hangs and fails with
OperationTimedOut.2026-06-bug-state.mp4
After (this fix): every case scrolls and returns cleanly, no timeouts.
2026-06-patched-state.mp4