Skip to content

Scroll position restoration#7800

Merged
matthewp merged 6 commits intomainfrom
vt-types
Jul 28, 2023
Merged

Scroll position restoration#7800
matthewp merged 6 commits intomainfrom
vt-types

Conversation

@matthewp
Copy link
Copy Markdown
Contributor

Changes

  • This implements scroll position restoration in the ViewTransitions router.
  • State is preserved in history.state
    • when clicking a link we add the previous page's position
    • when a scroll event occurs we record the state
    • When the user clicks back we use the state to set scrollTo
    • When the user clicks forward we use the state to set scrollTo

Testing

  • Back button test added
  • Forward button test added

Docs

N/A, transparent to developer

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Jul 25, 2023

🦋 Changeset detected

Latest commit: e00bc95

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added the pkg: astro Related to the core `astro` package (scope) label Jul 25, 2023
@matthewp matthewp marked this pull request as ready for review July 25, 2023 17:41
Comment on lines +210 to +218
// There's not a good way to record scroll position before a back button.
// So the way we do it is by listening to scroll and just continuously recording it.
addEventListener('scroll', () => {
const state: State | undefined = history.state;
if(state) {
state.scrollY = scrollY;
history.replaceState(state, '');
}
}, { passive: true });
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though with passive, I wonder if there's a perf penalty calling replaceState repeatedly. Maybe it can use a throttle.

Could keep an eye on this and leave it as is too now though.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with Bjorn, but I feel more strongly on this one. I think we have to add a bouncing mechanism.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it were a regular Map would you still feel this way? I would assume that replaceState is just a map under the hood. I don't want to add extra code, increasing the bundle size, unless we know that we need to.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that this is an experimental feature I think it's ok to be less safe in this case. If it is a problem we'll hear about it and fix before it becomes stable.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did some investigation and Safari considers calling replaceState too many times a security issue. I think I understand why; malicious sites could call pushState a lot to prevent you from backing out of the site. But I don't see why that would be the case for replaceState.

In any event, will need to look for another solution here.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remember very vaguely hitting this issue, and was able to fix it with a throttle helper with 300ms timeout (i think). This SO post seems to explain it: https://stackoverflow.com/questions/38419867/os-x-ios-safari-history-replacestate-limit-throws-securityerror-dom-exception

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's what I wound up doing. I did 500ms to be safe, but can bump it down. Otherwise ready for another review.

@matthewp matthewp merged commit 49a4b28 into main Jul 28, 2023
@matthewp matthewp deleted the vt-types branch July 28, 2023 13:07
This was referenced Jul 28, 2023
@Akxe
Copy link
Copy Markdown

Akxe commented Jul 28, 2023

This has a 2 bugs:

In prod - back animation no longer plays

  1. Open https://gingerarchitecture.cz/
  2. Click the first box
  3. Navigate back
  4. Observe: no animation back

In dev (and probably in prod once the previous bug is fixed) -

  1. Clone and start this repository: https://github.com/Akxe/gingerarchitecture.cz
  2. Scroll down
  3. Click the last box
  4. Navigate back
  5. Navigate forward
  6. Observe: scrollTop = 0 is applied to the old page causing the animated image to "fly" from the bottom of the page to the top

@millette
Copy link
Copy Markdown
Contributor

From what I can see in prod, if I follow a link from the footer, the page opens at the footer instead of the top. Is this expected? Can it be overriden?

@Akxe
Copy link
Copy Markdown

Akxe commented Jul 28, 2023

@millette I do not see that, but going back and forth using navigation does seem to break the page... sometimes... this is worrying.

@millette
Copy link
Copy Markdown
Contributor

For example, if you click Français on https://bus.waglo.com/en/ you'll stay at the top, but if you go the to bottom of the page and click one of the footer links, the page stays at the bottom.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pkg: astro Related to the core `astro` package (scope)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants