whatwg / html

HTML Standard
https://html.spec.whatwg.org/multipage/
Other
8.03k stars 2.62k forks source link

Early termination of navigation loading spinner on cross-document navigation #9090

Open tbondwilkinson opened 1 year ago

tbondwilkinson commented 1 year ago

@sebmarkbage was mentioning that in some of their server streaming HTML cases, the user agent loading spinner continues long after the important parts of the page have loaded.

If developers had some way of early terminating the loading spinner with JavaScript, that could provide a better user experience. This would not involve modifying actual loading behavior, merely the loading spinner indicator.

Correct me if I misunderstood the request Seb.

sebmarkbage commented 1 year ago

That's correct. An example:

<div>
  <h1>Hello</h1>
  <div class="loading" aria-busy="true">
    Loading...
  </div>
</div>
<script>
navigation.stopIndicator();
</script>
<script>
  moar stuff...
</script>

The main use case is that you have lots of more content that will stream in at the bottom of the HTML document but you've effectively already finished loading or are showing a custom loading state to the user already. This can be because the bottom include data or meta data that isn't visible to the user anyway (e.g. "hydration data") or it can be HTML that gets injected into the page later in slots that already have inline loading states and don't need a global one.

Although even better would be to have it work without JavaScript. E.g. some placeholder in the HTML would be enough.

E.g. <? done ?> in this example.

<div>
  <h1>Hello</h1>
  <div class="loading" aria-busy="true">
    Loading...
  </div>
</div>
<? done ?>
<script>
  moar stuff...
</script>

It could potentially also be an attribute annotation to indicate that when an element "ends" the essence of the document is already done.

sebmarkbage commented 1 year ago

For context, we have gotten some feedback that it feels faster when the same site does a secondary request from the client to the server to fetch more content with script - instead of embedding it into the stream. Objectively it's not "faster" to do the second roundtrip but the indicator stopping earlier makes it feel faster because the main UI is stable faster.

domenic commented 1 year ago

I've noted this as part of a cluster of related possibilities for exposing more about the initial load, over at https://github.com/WICG/navigation-api/issues/256#issuecomment-1527059530. But let's talk more in this issue about exactly what the ask is here.

I think the big question is how much does this method do, either by default or as an option. Here are various things it could do:

  1. Stop any browser UI loading indicator
  2. Announce to accessibility technology that the load is done
  3. Fire the load event "early". (This could potentially cause it to fire before DOMContentLoaded or readystatechange!)
  4. Don't fire the load event right away, but delay any further-encountered elements from delaying the load event.

I think at least (1) and (2) should be coupled. Maybe anything further is unwanted? Not sure.