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

Getting notified about cancellation of the initial navigation. #256

Open
jespertheend opened this issue Dec 5, 2022 · 9 comments
Open

Comments

@jespertheend
Copy link

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:

window.addEventListener("keydown", e => {
	if (e.code == "Escape") {
		e.preventDefault();
	}
});
@domenic
Copy link
Collaborator

domenic commented Apr 28, 2023

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 whatwg/html#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

@jespertheend
Copy link
Author

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.

@khushalsagar
Copy link

khushalsagar commented Aug 23, 2023

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>

@domenic
Copy link
Collaborator

domenic commented Aug 23, 2023

  • 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 whatwg/html#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.)

@khushalsagar
Copy link

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.

@domenic
Copy link
Collaborator

domenic commented Aug 23, 2023

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.

@vmpstr
Copy link

vmpstr commented Aug 24, 2023

      // 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?

@khushalsagar
Copy link

^ 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.

@noamr
Copy link

noamr commented Sep 20, 2023

Created an HTML issue to continue evolving the proposal from the comment: whatwg/html#9760

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

No branches or pull requests

5 participants