Bug 1880528 - Introduce preference for fetch priority adjustment of <link rel=preload as=script>. r=valentin,necko-reviewers

The fetchpriority attribute allows web developers to request some
adjustment to the internal priorities when fetching resources. In order
to give some flexibility for experimenting and choosing the values that
work best for Gecko, we will introduce new preferences to control
exactly how the internal priority is adjusted, depending on the value
auto/high/low of the fetchpriority attribute.

This is the first patch of a series introducing such preferences,
focusing on the case `<link rel=preload as=script>`. The following 3
integer preferences are introduced:

```
network.fetchpriority.adjustments.link-preload-script.low
network.fetchpriority.adjustments.link-preload-script.high
network.fetchpriority.adjustments.link-preload-script.auto
```

and are set so that we don't change current behavior (already
covered by tests). A test is also added to verify basic invariants
for such adjustments.

Differential Revision: https://phabricator.services.mozilla.com/D201997
This commit is contained in:
Frédéric Wang
2024-02-19 13:35:39 +00:00
parent eaa4787926
commit a81ab9e9b6
4 changed files with 90 additions and 37 deletions

View File

@@ -668,53 +668,35 @@ static void AdjustPriorityAndClassOfServiceForLinkPreloadScripts(
nsIChannel* aChannel, ScriptLoadRequest* aRequest) {
MOZ_ASSERT(aRequest->GetScriptLoadContext()->IsLinkPreloadScript());
if (!StaticPrefs::network_fetchpriority_enabled()) {
// Put it to the group that is not blocked by leaders and doesn't block
// follower at the same time.
// Giving it a much higher priority will make this request be processed
// ahead of other Unblocked requests, but with the same weight as
// Leaders. This will make us behave similar way for both http2 and http1.
ScriptLoadContext::PrioritizeAsPreload(aChannel);
return;
}
// Put it to the group that is not blocked by leaders and doesn't block
// follower at the same time.
// Giving it a much higher priority will make this request be processed
// ahead of other Unblocked requests, but with the same weight as
// Leaders. This will make us behave similar way for both http2 and http1.
ScriptLoadContext::PrioritizeAsPreload(aChannel);
if (nsCOMPtr<nsIClassOfService> cos = do_QueryInterface(aChannel)) {
cos->AddClassFlags(nsIClassOfService::Unblocked);
if (!StaticPrefs::network_fetchpriority_enabled()) {
return;
}
if (nsCOMPtr<nsISupportsPriority> supportsPriority =
do_QueryInterface(aChannel)) {
LOG(("Is <link rel=[module]preload"));
const RequestPriority fetchPriority = aRequest->FetchPriority();
const auto fetchPriority = ToFetchPriority(aRequest->FetchPriority());
// The spec defines the priority to be set in an implementation defined
// manner (<https://fetch.spec.whatwg.org/#concept-fetch>, step 15 and
// <https://html.spec.whatwg.org/#concept-script-fetch-options-fetch-priority>).
// For web-compatibility, the fetch priority mapping from
// <https://web.dev/articles/fetch-priority#browser_priority_and_fetchpriority>
// is taken.
const int32_t supportsPriorityValue = [&]() {
switch (fetchPriority) {
case RequestPriority::Auto: {
return nsISupportsPriority::PRIORITY_HIGH;
}
case RequestPriority::High: {
return nsISupportsPriority::PRIORITY_HIGH;
}
case RequestPriority::Low: {
return nsISupportsPriority::PRIORITY_LOW;
}
default: {
MOZ_ASSERT_UNREACHABLE();
return nsISupportsPriority::PRIORITY_NORMAL;
}
}
}();
LogPriorityMapping(ScriptLoader::gScriptLoaderLog,
ToFetchPriority(fetchPriority), supportsPriorityValue);
supportsPriority->SetPriority(supportsPriorityValue);
// See corresponding preferences in StaticPrefList.yaml for more context.
const int32_t supportsPriorityDelta =
FETCH_PRIORITY_ADJUSTMENT_FOR(link_preload_script, fetchPriority);
supportsPriority->AdjustPriority(supportsPriorityDelta);
#ifdef DEBUG
int32_t adjustedPriority;
supportsPriority->GetPriority(&adjustedPriority);
LogPriorityMapping(ScriptLoader::gScriptLoaderLog, fetchPriority,
adjustedPriority);
#endif
}
}