Skip to content
This repository has been archived by the owner on Sep 25, 2021. It is now read-only.

Turbolinks should save page state before it is closed #185

Closed
heaven opened this issue Oct 1, 2016 · 9 comments
Closed

Turbolinks should save page state before it is closed #185

heaven opened this issue Oct 1, 2016 · 9 comments

Comments

@heaven
Copy link

heaven commented Oct 1, 2016

The page could be modified after the last turbolinks event, e.g. some elements could be added/hidden, input values might be changed, etc. I think it would be correct to bind to beforeunload event and update the cache before closing the tab/following link where turbolinks is disabled.

@jonesmac
Copy link

I am running into the need for the as well. Without this feature, its too easy to cache pages in an unwanted state and impossible to get a fresh rebuild from the server.

@domchristie
Copy link
Collaborator

@heaven would you be able to elaborate on this, as I'm not sure I understand the use-case. There are a few issues which discuss the beforeunload event (#216, #230, #264), but I'm not sure if these are relevant.

@heaven
Copy link
Author

heaven commented Sep 14, 2018

@domchristie the problem is that the page could be modified before it is unloaded while turbolinks keeps the old version of the page, created after the page was loaded. In this case when you click back you see an outdated page, different than it actually was before you left it.

@domchristie
Copy link
Collaborator

Turbolinks caches a page just before a new one is rendered (rather than just after it has loaded) … but I have just noticed that the end of your original post, you mention "where turbolinks is disabled", in which case I think pressing "Back" will fallback back to a browser's default behaviour:

a history mechanism is meant to show exactly what the user saw at the time when the resource was retrieved.
https://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.13

@heaven
Copy link
Author

heaven commented Sep 14, 2018

You can see yourself the different behavior even here, on GitHub.

I just wrote this comment but didn't submit it. Instead, I clicked on the Preview tab above the text field.

Then two different scenarios are possible:

  1. The correct one. I clicked the Insights link (handled with JS) at the top of the page. After I navigated back to this page my comment was left in the text box and the Preview tab was still open, just how I left it.
  2. The incorrect one. If you click the turbolinks link (which is not handled by JS) pointing to turbolinks github account and then navigate back, your comment will still be preserved but the Preview tab will not be open. Here you can see the problem – the script didn't save the current (valid) page state, but, at the same time, the browser did it, saving your input in the text box.

I hope this will give you more understanding of my point of view.

Since it would be a really bad design keeping track of all page changes and modifying the cache on the go, especially on dynamic pages, using beforeunload event seems the most appropriate for this.

@domchristie
Copy link
Collaborator

The incorrect one. If you click the turbolinks link (which is not handled by JS) pointing to turbolinks github account and then navigate back, your comment will still be preserved but the Preview tab will not be open. Here you can see the problem – the script didn't save the current (valid) page state, but, at the same time, the browser did it, saving your input in the text box.

In this case, the cache is handled by the browser according to the spec—storing the page state when it was initially retrieved. The Turbolinks cache is empty because the page was unloaded. The reason the text box value is restored is because GitHub stores input values in session storage before exiting the page (possibly on beforeunload), and subsequently restores them when the page loads. To clarify, this is what's happening:

  1. Click non-Turbolinks-enabled link
  2. (GitHub stores input values in session storage)
  3. New page is fully loaded without Turbolinks and therefore wipes out any Turbolinks cache
  4. Click "Back"
  5. Browser handles this by restoring the page back to what is was when it was initially retrieved
  6. GitHub JS restores input values

The problem is that when you fully load a page without Turbolinks (e.g. via a link with turbolinks-disabled), you are clearing the Turbolinks cache because it is stored locally in a JavaScript object. With this in mind, if Turbolinks were to store the state of the page on beforeunload it would be immediately discarded when the page is unloaded :/

It's technically possible to store the state of the page in session storage, but aside from the security concerns, it would be difficult to know when to restore from this cache, and it'd also be prone to visual flicker when Turbolinks takes over following the default browser "Back" behaviour (which is unavoidable in this case).

So all things considered, it is best to keep as many Turbolinks-enabled transitions as possible in your app! :)

Hope that makes sense! Using session storage to cache pages for offline is being discussed in #196, so I'm closing this.

@heaven
Copy link
Author

heaven commented Sep 14, 2018

It's not GitHub storing anything on the unload event, you can test here https://www.w3schools.com/html/html_forms.asp (just enter any value in the form then close and re-open the page). Google Chrome and Safari restored my custom value in both cases: back/forth navigation and closing/re-opening the tab. Firefox did only if I hit back/forth but didn't if I completely close and re-open the tab.

A web form was just an example, the page could be modified with other scripts and the native back button restores them properly, while Turbolinks breaks this. I don't use Turbolinks now and don't have a place where to test but doesn't it already flicker replacing the restored by the browser (most recent) page from a stale cache? I think that was the original issue for this report.

I'm glad you were able to convince yourself this is not an issue with Turbolinks.

@heaven
Copy link
Author

heaven commented Sep 14, 2018

Another issue with GitHub – posted my last comment and then clicked this link https://www.w3schools.com/html/html_forms.asp, then clicked back and my post disappeared due to the stale cache.

UPD. I think I just remembered our use case – we had an infinite scroll and each time user clicked the link and then wanted to return back to the same place. So a workaround might be to add a special data attribute to the link to allow it to save the current state before exit. Which will not resolve the problem with restored tabs, though.

@domchristie
Copy link
Collaborator

To elaborate, GitHub does store form values in session storage:

screen shot 2018-09-14 at 17 35 30

Perhaps because this kind of caching behaviour is not strictly defined, as well as for cross-browser consistency.

the native back button restores them properly, while Turbolinks breaks this.

This isn't the case. When transitioning between Turbolinks-enabled pages, Turbolinks caches the page just before the next page is rendered. To demonstrate this, type a new comment, tap "Preview", scroll up and tap "Pull Requests", then navigate "Back". The preview tab will still be active.

Another issue with GitHub – posted my last comment and then clicked this link https://www.w3schools.com/html/html_forms.asp, then clicked back and my post disappeared due to the stale cache.

GitHub/Turbolinks has no control over what the browser initially serves when navigating "Back" from https://www.w3schools.com…. This case demonstrates the default browser behaviour as defined in the spec i.e. serving a version of the page as it was when it was initially retrieved.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants