Skip to content
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

Support BFCache using the pageshow event #34

Closed
mjackson opened this issue Aug 21, 2015 · 10 comments
Closed

Support BFCache using the pageshow event #34

mjackson opened this issue Aug 21, 2015 · 10 comments

Comments

@mjackson
Copy link
Member

We should support BFCache users using the pageshow event.

See #31 (comment) for more discussion.

@mjackson
Copy link
Member Author

@taurose Would you like to take a stab at this?

@agundermann
Copy link
Contributor

I would, but I'm not sure how to best implement this. When going back to a different page, do we run transition hooks as if the page was never left, or immediately update the location? Should we let the user know that the transition came from pageshow instead of popstate, and should we let him know in case the URL hasn't changed and we don't need to transition?

@mjackson
Copy link
Member Author

When going back to a different page, do we run transition hooks as if the page was never left, or immediately update the location?

From what I understand of the original bug, it seems like pageshow should be treated just like our initial POP event which bypasses transition hooks and immediately updates the location, but I'm not 100% sure.

In the steps to reproduce that bug, when is pageshow actually fired? When you hit Enter or when you hit the back button?

@agundermann
Copy link
Contributor

It fires when you come back to the app, i.e. when hitting the back button. Instead of re-executing the app, we get the pageshow event with everything else being in the state that the app was left.

The example I posted there may be a bit confusing since the app isn't really left, but pressing enter on the URL bar has the same effect of creating a new document, reloading HTML&JS etc. This example should be easier to follow.

I'm leaning towards treating it like the initial event, too, since it would be confusing to go back to a page and be presented with a dialog about leaving the page I left a long time ago. On the other hand, the initial DOM will reflect the old page, so maybe we should make it distinguishable somehow.

@mjackson
Copy link
Member Author

mjackson commented Sep 5, 2015

On the other hand, the initial DOM will reflect the old page, so maybe we should make it distinguishable somehow.

What would be the use case here? I guess someone might want to preserve that DOM for some reason. I'm trying to imagine maybe a half-filled out form or something, where you'd want to keep data the user had already entered. But then you'd have to pull all of your application state from the DOM... maybe I'm thinking too much about the React paradigm?

In any case, I think for now we can just treat it like the initial POP and wait for someone to say "hey, I need to do something special on pageshow!" and we can continue this discussion at that point.

@agundermann
Copy link
Contributor

I guess someone might want to preserve that DOM for some reason. I'm trying to imagine maybe a half-filled out form or something, where you'd want to keep data the user had already entered. But then you'd have to pull all of your application state from the DOM... maybe I'm thinking too much about the React paradigm?

You wouldn't have to do that since javascript state is cached, too. From the app's perspective, the site was never left. That's where pageshow comes in.

In any case, I think for now we can just treat it like the initial POP and wait for someone to say "hey, I need to do something special on pageshow!" and we can continue this discussion at that point.

Sounds good.

When trying to implement this, I stumbled upon another problem. Firefox doesn't seem to update window.history.state to the current entry. Instead, it still has the state of the cached page that the user has navigated away from. So when calling updateLocation(getCurrentLocation()) in response to a persisted pageshow event, location.key will be wrong. Pressing back then forward or F5 will fix it.

I can't think of a way to work around this and fix location.key. Seems like a browser issue to me with window.location and window.history.state being out of sync.

@mjackson
Copy link
Member Author

What would be your recommendation here, @taurose? I'm sorry I haven't had more time to dig into this myself.

@agundermann
Copy link
Contributor

I don't think it's worth pursuing this:

  • I still couldn't solve the problem mentioned above, so I don't think we can make it work without losing state for the first page the user sees when coming back to our app
  • the cache seems mostly useful for multi page apps/websites to speed up transitions between pages. Transitions from other websites back to one's app via back button aren't as important I'd say
  • the cache is disabled in many cases (https, beforeunload, ...)
  • no one else ran into this issue or asked for this functionality as far as I can tell; perhaps due to the reasons above

@ZebraFlesh
Copy link

I think I have a use case for this feature: our site is currently part single page apps and part legacy server side HTML. We step our users through what's essentially a multipage form (essentially, https://www.example.com/try-us-for-free/{guid1}/step1, /step2, etc). When they complete the process, the temporary {guid1} resource is converted into a permanent resource (something like, https://www.example.com/success/{guid2}). This permanent resource page is server side HTML. If the user presses the back button at this point, they go back into the single page app. The fetch for this page includes a server side redirect (HTTP 302 response) and they're forced back to the permanent resource. (Indeed, any request for a step in the multipage form with the consumed temporary resource results in a server side redirect.)

This all works great until you get to a BFCache supporting browser such as Safari. Safari ignores the no-cache header and returns the user to the single page application (https://www.example.com/try-us-for-free/{guid1}/stepN), loading it from the cache and not performing any server requests.

Right now, the only solution to this problem is to manually hooking into the pageshow event, outside of history. It feels and looks terribly hacky.

@mjackson
Copy link
Member Author

Closing due to inactivity.

@lock lock bot locked as resolved and limited conversation to collaborators Jun 5, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants