Open jespertheend opened 1 year ago
This is not currently possible. However, I think we could consider making it work. The hard part is whether we want to treat the initial page load as special, or try to integrate it with the rest of the navigation API.
Arguments for treating it as special: well, it is special. In particular:
Script only starts running after a good bit of the loading process is already done, unlike from-your-page navigations where we can give you insight into, and control over, every step of the loading process.
This load will always be cross-document. The navigation API has several cases where it assumes cross-document navigations, if they commit, will blow away the current page, and thus none of the current page's script will run. (E.g., it doesn't bother resolving the committed
and finished
promises for cross-document navigations.) This assumption doesn't hold for the initial page load though.
So although it is tempting to try to do something clever here, e.g. making navigation.transition
have a non-null value during the current page load, or try to find a good time to fire a special NavigateEvent
representing the initial page load, I think we're better off doing a special API just for the initial page load.
Another idea we've gotten in this space is https://github.com/whatwg/html/issues/9090.
Here's one idea:
navigation.initialLoad.signal.addEventListener("abort", () => {
// initial page load was aborted
});
// Stop the loading indicator.
navigation.initialLoad.stopIndicator();
// Maybe this is the place to put https://github.com/whatwg/html/pull/1936,
// if people still want that:
await navigation.initialLoad.parsed;
await navigation.initialLoad.contentLoaded;
await navigation.initialLoad.subresourcesFullyLoaded;
// We could add some of the more informational properties of NavigateEvent, maybe?!
navigation.initialLoad.userInitiated;
navigation.initialLoad.navigationType;
navigation.initialLoad.formData; // this one could be a lot of work to implement, for POSTs
This sounds good! I wish I could give somewhat more constructive feedback on this, but admittedly I haven't yet had a chance to use the navigation api a lot. The sites I make are mostly SPA web games, so I'm not exactly dealing with navigations on a daily basis. Getting more control over the initial page load is my only use case really.
I like the proposal on here! Another use-case which needs this is cross-document View Transition. The new Document needs to know the type of navigation to set up the UX (like swipe left/right if its a back/fwd navigation).
A few aspects to think through:
initialLoad will need to be updated if the Document is restored from BFCache or activated after pre-rendering. So probably just the naming needs to be different.
initialLoad can also provide you an index of the previous navigation entry. So authors can know what the url or any other state of the old Document was for this navigation.
I like that initialLoad gives a set of promises to observe the Document going through different stages in a navigation lifecycle. I wonder if the event proposed here could be one of those promises? So something like:
<head>
<script>
// Subscribe for new load.
navigation.initialLoad.reveal.then(setUpTransition);
// Subscribe for BFCache loads? Does this also work for pre-render?
window.addEventList("pageshow", (event) => {
if (event.persisted) { setUpTransition(); }
});
</script>
</head>
- initialLoad will need to be updated if the Document is restored from BFCache or activated after pre-rendering. So probably just the naming needs to be different.
Strongly agreed. Name suggestions welcome... Nothing is immediately coming to mind.
- initialLoad can also provide you an index of the previous navigation entry. So authors can know what the url or any other state of the old Document was for this navigation.
I think we can provide the whole previous entry, with a .from
property. At least for same-origin navigations, which is what the navigation API mostly deals with... is it OK to scope out cross-origin ones? Or should we think through something that might work for both? (All navigation API indices are within a same-origin context.)
- I like that initialLoad gives a set of promises to observe the Document going through different stages in a navigation lifecycle. I wonder if the event proposed here could be one of those promises?
That sounds great!
In general, the promises I mentioned above (from https://github.com/whatwg/html/pull/1936) kind of floundered on lack of use cases. So we should start with ones that have solid use cases, like your reveal
. (Another one that comes up often is a promise version of the prerenderingchange
event.)
Or should we think through something that might work for both? (All navigation API indices are within a same-origin context.)
Same-origin is fine for now.
We want to extend this feature to same-site eventually. Assuming both Documents opt-in, is there a reason the browser still can't allow same-site entries to be visible in the navigation API.
We want to extend this feature to same-site eventually. Assuming both Documents opt-in, is there a reason the browser still can't allow same-site entries to be visible in the navigation API.
Assuming both documents opt-in, this would be fine.
// Subscribe for new load. navigation.initialLoad.reveal.then(setUpTransition); // Subscribe for BFCache loads? Does this also work for pre-render? window.addEventList("pageshow", (event) => { if (event.persisted) { setUpTransition(); } });
Just to clarify my understanding: You'd still need to register things for BFCache restores right? Like navigation.initialLoad.reveal is a promise that gets satisfied at some point in the initial load, but then it would need to be a new promise when this page is again activated out of BFCache, so you'd still register for pageshow?
^ yes. The initialLoad
object changes when the Document exits BFCache. The event.persisted
check in pageShow is to register to the new promise for that case.
Created an HTML issue to continue evolving the proposal from the comment: https://github.com/whatwg/html/issues/9760
We have a site that shows a loading screen on first page load, which is served in the html of the initial navigation, without running any scripts. We then download all the scripts and assets, which might take a while on slower connections. During this time the user is able to cancel the page load using the escape key. But this can be a bit confusing, because when cancelling the page load, the text 'loading...' will stay visible forever, or until the page is refreshed. It doesn't help either that the escape key is also used to open the menu once the page has loaded.
So I'm trying to figure out a way to improve the user experience here. I was hoping there would be an event that I could listen for when the page load is cancelled. That way I could change the text to something else. Or maybe prevent the cancellation. Right now the only thing that seems to work is listening for the 'Escape' key. But without being able to know for sure whether this caused the user agent to prevent loading, the best I can do is preventDefault the event: