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

consider exposing and allowing script to set Request priority #436

Open
wanderview opened this issue Dec 14, 2016 · 13 comments
Open

consider exposing and allowing script to set Request priority #436

wanderview opened this issue Dec 14, 2016 · 13 comments
Labels
addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest topic: api

Comments

@wanderview
Copy link
Member

Currently the browser makes a number of decisions about what network requests are high priority vs low priority. We could expose this as a Request.priority attribute.

In addition, we could allow script to set this so that authors can hint that some requests are low priority. For example, think of a requestIdleCallback() that is intended to avoid interfering with normal page operation, but it needs a network request. It could use a "low" priority.

Another use case would be pre-caching resources at a low priority in a ServiceWorker's install event handler. This would reduce any impact to the currently displayed page.

I don't think we would want to guarantee honoring the value, though. It would be a hint and best effort by the browser.

Webidl sketch:

interface Request
 {
  readonly attribute RequestPriority priority;
};
dictionary RequestInit
 {
  RequestPriority priority;
};
enum RequestPriority { "low", "normal", "high" };

Service workers would also be able to inspect priority:

addEventListener('fetch', evt => {
  if (evt.request.priority === 'high') {
    // high priority request
  }
});
@sleevi
Copy link

sleevi commented Dec 15, 2016

@wanderview How does that IDL sketch reconcile with https://fetch.spec.whatwg.org/#fetching ? That is, that 'priority' is a user-agent defined object, but the IDL sketch seems to make it a specific set of values (no longer UA defined)

In particular, I'm thinking about the Note in Step 5

The user-agent-defined object could encompass stream weight and dependency for HTTP/2, and equivalent information used to prioritize dispatch and processing of HTTP/1 fetches.

At least in Chrome, the low/normal/high is not a priority system we're happy with, and certainly not with exposing, at least historically speaking. Even weighting numeric priorities has caused a host of issues with H/2 processing, and we're trying to move away from that. I'm not sure how Firefox is handling that, but I thought @mcmanus had implemented a much more nuanced priority/dependency tracking already.

@wanderview
Copy link
Member Author

You can read my post as "exact priority enum values TBD".

I did indicate script specified priority would be a hint and not a guarantee. I think this value could reflect intent, but not necessarily exact implementation detail. I would not want this API to constrain the implementation.

@mcmanus
Copy link

mcmanus commented Dec 15, 2016

the priority low->high paradigm is certainly better than nothing.. at some point when combining different classes of things (or things from different sources - but that's outside the scope of one script) it devolves into needing dependencies.. but that's a lot of complexity and a lot of complexity authors prefer to avoid and honestly screw up. As long as you're not combining things from multiple sources (i.e. things that aren't aware of each other or trust each other) you can mostly get by with priorities. Especially if you can reprioritize.

I'm not sure what the right balance in this API is but I lean towards at least some sense of classification if you don't feel full on deps are appropriate.

firefox does do a lot of dependency management for markup, but when it comes to scripts it has little idea what is going on.. and as mentioned before without some kind of classification or dependency system combining these scopes is super hard.

@wanderview
Copy link
Member Author

I'd be happy with just "low" and "default" or something. The "low" value is to indicate something explicitly de-prioritized like a beacon, etc.

@yoavweiss
Copy link
Collaborator

I think that a priority indication, both for fetch() and as part of markup is very much needed, and not just for scripts.

A few use-cases:

  • fetch() triggered beacons (as mentioned)
  • Adding <link rel=preload> for late-discovered non-render-blocking resources without having them contend with more critical resources
  • Preventing non-critical third party content from contending with critical content

All these cases require a priority downgrade. I'm not sure if there are other cases that require an upgrade.

@annevk
Copy link
Member

annevk commented Apr 17, 2018

cc @domfarolino

@annevk annevk added addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest labels Apr 17, 2018
@domfarolino
Copy link
Member

Thanks for the cc! Since this thread's birth, this idea has been embodied in Priority Hints, and is currently being discussed at whatwg/html#3670 to see if we can get it in HTML/Fetch. @wanderview we're currently going with low, auto, and high importance values, which serve as a hint to a resource's intended priority. If you'd like to chime in there a bit that'd be awesome, as we're trying to gauge interest from other browsers.

I know that priority as request concept already exists here, but how do we feel about having another concept importance, which is potentially exposed? Here are some questions/thoughts:

  • Would it be too confusing having both importance and priority concepts on a Request object?
  • I know that exposing priority was discussed here. My thoughts are that priority might be a little too specific to expose here, not to mention it might be computed later than the request is made (though an estimation or baseline could be exposed instead I guess). I'm more in favor of exposing importance, which would default to auto unless developer-specified. I know @yutakahirano was a big fan of not exposing Request.importance in Chrome's initial implementation, I believe for ease of adoption, but if we think it would be nice to expose this, as @wanderview mentioned exposing priority, that could work. Thoughts?

@wanderview
Copy link
Member Author

Sorry, I missed #436 (comment) when it was first written.

It does feel a bit confusing to have both priority and importance, but importance needs to be represented in the fetching algorithm somehow.

Maybe since priority is currently a UA defined object we could just say that it must include the source importance value as well?

@wanderview
Copy link
Member Author

Also, if Priority Hints exposes an importance attribute on elements, then there should probably also be an expose Request.importance and RequestInit.importance. Feels natural and I don't see a good reason to hide them. Also, you will need that if you want service workers to be able to preserve the importance value if its doing anything more complicated than a pass-through fetch.

@domfarolino
Copy link
Member

Good points. We do have some discussion around that right now, but ultimately it seems reasonable to expose it. Main thing we're worried about now is a hint's effects taking place twice. For example, the UA defers sending importance=low requests to the SW because of the developer intention, then the same deferring takes place again when sending from the SW => actual network. This isn't really related to exposing the attribute or not, but I guess application code could do some extra playing around with the scheduling of a request if it were exposed.

If welcomed, I can start working on HTML and Fetch Standard PRs for this. HTML Standard issue is filed here (whatwg/html#3670) for reference.

@wanderview
Copy link
Member Author

For example, the UA defers sending importance=low requests to the SW because of the developer intention

AFAICT this isn't really permitted by the spec today. The fetching algorithm does not have any variation in how Handle Fetch is invoked. I think this kind of observable change would have to be discussed as a separate issue.

Also, I highly doubt prioritization before the service worker would be worth the complexity. Unless the service worker is doing blocking operations, like spinning a loop on js-level computations, then there should be very little request queueing in front of the service worker. The one exception is when you need to spawn the service worker, but in that case I don't see how prioritization is going to make anything faster.

@annevk
Copy link
Member

annevk commented Jan 30, 2021

What's the status here? I was thinking there might also be some overlap with #184 in that low-priority requests could potentially be coalesced.

@domenic
Copy link
Member

domenic commented Feb 1, 2021

I believe @natechapin is working on this problem from the Chrome side now. I'll let him expand, but I think the latest thinking after priority hints didn't show promise is to allow applications to manipulate fetch priority using similar tools to how they manipulate JS task priority, with the hopes that this allows applications to make more holistic decisions like "this whole section of code, including its fetches, is less important".

The connection to #184 and coalescing is very interesting and I'd be interested in his take there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest topic: api
Development

No branches or pull requests

7 participants