-
Notifications
You must be signed in to change notification settings - Fork 26
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
What happens when returning to entries captured by app-history #99
Comments
This is a really hard one, because I think it would be confusing to default to loading as if we were back in '/' when the URL bar actually says '/article-1' but you're right that this is a place where developers have to add special handling (basically they have to redo in JS all the things that the page formerly did). I don't think we should go the route of making formerly same-document history entries cross-document, that also feels bad. To me this problem is more about how fast we can display HTML to the user on a back navigation. Right now, it's a waste because when you're on a page with a URL, but you've done a So if I were to go about fixing this problem, I would think about ways that the browser could snapshot the contents of the DOM when the URL bar changes in a same-document way, as if that DOM had been requested explicitly from the network. Then, even though this isn't a full BFCache reload (since the JS context is recreated), you would at LEAST not lose the DOM content, which I assume is cheaper to cache than full JS context. Keep in mind too that developers always have to handle this case, because at any moment the user could reload. Interestingly, reloading does transform entries into cross-document, so e.g. if you had |
In general app history builds on the existing session history model, and I don't think we have any particular opportunities to change it. So I think the behavior here should be the same as it is for pushState. I don't know how we'd spec something else.
My understanding is that typically SPAs are done by either:
So I don't think it's very typical that |
Well, I do think you're over-estimating apps. But further I think what's more frustrating than having to handle this specially is that to handle this, you have to either keep server-side rendering in sync with client-side rendering, which isn't trivial OR you have to do all client-side rendering, which has time-to-interaction implications. Vs. with multi-page applications, browsers do a really good job of making reloads and navigations cheap, with SPA, reloads and navigations can be very expensive if JS context is lost. |
That bit is fine. The server sends HTML. It's when that document also needs to handle As you say, if all URLs are rewriting to the same app JS, it's fine. It's possible that's what everyone does. |
I don't think so, not in Chrome anyway. Where are you seeing this? |
Yeah, I think my mental model of how Interestingly, if I Google for 'pushState demo', the first result with a working demo is https://css-tricks.com/using-the-html5-history-api/, and the demo makes the same incorrect assumption. I have a vague worry that the current API encourages this thinking. Eg: // The amazing lightbox library!
appHistory.addEventListener("navigate", event => {
if (!event.canRespond || event.hashChange) return;
const url = new URL(event.destination.url);
if (!/\.(jpe?g|gif|png|avif|webp)$/.test(url.pathname)) return;
displayImageInAModal(url);
}); This captures navigations to images and displays them in-page. The link is sharable (it'll just point to the image). The back button will appear to work. It'll even sometimes work across documents thanks to bfcache. I guess we just have to document that the above is not okay. |
For instance starting on Or am I misunderstanding what you mean? |
The image example is interesting - I assume open in new tab/window would still work as expected. But perhaps we'd only allow making cross-document navigations same-document if the other document is of the same "type", e.g a webpage and not a resource. |
Maybe I'm reading this wrong. Here's a test:
When you said " 3 results in a change of document, but it updates both history entries, so 4 traverses to the same document. |
Your console should show a 404 error since that path doesn’t exist at example.com. But the browser does attempt the load I believe and makes the network request.
But I believe 4 would result in a change of document, had the network request in 3 not been a 404, unless I'm wrong in my terminology and document doesn't mean what I think it means.
|
I'm not seeing that behaviour in Chrome, Firefox, or Safari https://static-misc-2.glitch.me/push-state-test/ |
Ah, now I see what you mean. You're right! :) Another fun quirk. |
It's consistent with navigating away then pressing back (unless bfcache), and hash-change navigations, so that's one thing at least! |
Although it doesn’t seem like this is something that can be solved (where it actually needs solving, I mean?) by AppHistory alone, perhaps if AppHistory ends up being friendly to pairing with the proposed URLPattern and/or “Declarative routing” APIs, this would in turn make it more straightforward and attractive to share a single source of truth for route definitions between the client, service worker, and backend. If that pattern were easier to realize, it might help reduce the odds of folks accidentally introducing disagreements between server and client routing. |
@domenic I'm happy for this to close unless you're interested in solving the image use-case in #99 (comment), perhaps in some 'opt-in' way that forces the new history entry to use its own document state. Fwiw, my PR will probably support that. Otherwise, feels like we should stick with the current behaviour. |
I think we should probably stick with the current behavior, but I'm happy to keep this open to track efforts about documentation, or thinking if there's some way to steer people away from such behavior, or the ideas that @bathos mentions. |
I'm trying to refresh myself on this to see if we can add documentation but I unfortunately lost track of the problem. Given the lightbox image code in #99 (comment) what is the problem scenario? Is the problem that the |
|
One solution might be an option that, in step 3, creates a new history entry with the same document, but a different document state. This means the reload in step 4 would only replace the document in the second history entry. |
This came up in whatwg/html#6207 and it might be worth 'fixing' in the new API.
/
./article-1
, which is handled within the current document by responding to the "navigate" event.Currently, the equivalent
pushState
browser behaviour is:/article-1
fetched and displayed./
(no fetch).I wonder how obvious it is to developers that they need to cater for this. It seems possible that the resources at:
/
is a full app, capable of transitions etc etc/article-1
is just the article. HTML & CSS.…meaning that
/article-1
is unprepared for an internal state change to/
.Other ways this could be handled:
/article-1
fetched and displayed./
fetched and displayed.This means entries that were previously using the same document are now using different documents, which is weird in its own way. Although, this is what should happen in a literal interpretation of the spec.
Or:
/
fetched and displayed, but with/article-1
state./
(no fetch).This means fetching something other than the URL that's in the URL bar, but it loads the same code that previously handled the transition from
/
to/article-1
.The text was updated successfully, but these errors were encountered: