diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp index e6eda1a47555..abc0b548051b 100644 --- a/dom/script/ScriptLoader.cpp +++ b/dom/script/ScriptLoader.cpp @@ -731,34 +731,49 @@ void AdjustPriorityForNonLinkPreloadScripts(nsIChannel* aChannel, do_QueryInterface(aChannel)) { LOG(("Is not FetchPriority(); + // The spec defines the priority to be set in an implementation defined // manner (, step 15 and // ). - // For web-compatibility, the fetch priority mapping from - // - // is taken. - const Maybe supportsPriorityValue = [&]() -> Maybe { + // + // provides more context for the priority mapping. + const int32_t supportsPriorityValue = [&]() { switch (fetchPriority) { - case RequestPriority::Auto: - return Nothing{}; + case RequestPriority::Auto: { + if (aRequest->IsModuleRequest()) { + return nsISupportsPriority::PRIORITY_HIGH; + } + + const ScriptLoadContext* scriptLoadContext = + aRequest->GetScriptLoadContext(); + if (scriptLoadContext->IsAsyncScript() || + scriptLoadContext->IsDeferredScript()) { + return nsISupportsPriority::PRIORITY_LOW; + } + + if (scriptLoadContext->mScriptFromHead) { + return nsISupportsPriority::PRIORITY_HIGH; + } + + return nsISupportsPriority::PRIORITY_NORMAL; + } case RequestPriority::Low: { - return Some(nsISupportsPriority::PRIORITY_LOW); + return nsISupportsPriority::PRIORITY_LOW; } case RequestPriority::High: { - return Some(nsISupportsPriority::PRIORITY_HIGH); + return nsISupportsPriority::PRIORITY_HIGH; } default: { MOZ_ASSERT_UNREACHABLE(); - return Nothing{}; + return nsISupportsPriority::PRIORITY_NORMAL; } } }(); if (supportsPriorityValue) { LogPriorityMapping(ScriptLoader::gScriptLoaderLog, - ToFetchPriority(fetchPriority), - *supportsPriorityValue); - supportsPriority->SetPriority(*supportsPriorityValue); + ToFetchPriority(fetchPriority), supportsPriorityValue); + supportsPriority->SetPriority(supportsPriorityValue); } } } diff --git a/testing/web-platform/mozilla/meta/fetch/fetchpriority/fetchpriority.h2.html.ini b/testing/web-platform/mozilla/meta/fetch/fetchpriority/fetchpriority.h2.html.ini index e34dde6949b3..2fac3e3e7c06 100644 --- a/testing/web-platform/mozilla/meta/fetch/fetchpriority/fetchpriority.h2.html.ini +++ b/testing/web-platform/mozilla/meta/fetch/fetchpriority/fetchpriority.h2.html.ini @@ -18,6 +18,3 @@ [image-dynamic-load.h2.html: test different 'fetchpriority' values] expected: FAIL - - [script-initial-load-body.h2.html: test different 'fetchpriority' values] - expected: FAIL diff --git a/testing/web-platform/mozilla/tests/fetch/fetchpriority/support/script-tests-data.js b/testing/web-platform/mozilla/tests/fetch/fetchpriority/support/script-tests-data.js index ae2d80b33428..98309cc71ce8 100644 --- a/testing/web-platform/mozilla/tests/fetch/fetchpriority/support/script-tests-data.js +++ b/testing/web-platform/mozilla/tests/fetch/fetchpriority/support/script-tests-data.js @@ -3,6 +3,12 @@ const kFetchPriorityHighRequestFileNameAndSuffix = "dummy.js?2"; const kFetchPriorityAutoRequestFileNameAndSuffix = "dummy.js?3"; const kNoFetchPriorityRequestFileNameAndSuffix = "dummy.js?4"; +// Mapping fetchpriority's values to internal priorities is specified as +// implementation-defined (https://fetch.spec.whatwg.org/#concept-fetch, step +// 15). For web-compatibility, Chromium's desired mapping is chosen, see +// . +// Exceptions are commented below. + const kExpectedRequestsForScriptsInHead = [ { fileNameAndSuffix: kFetchPriorityLowRequestFileNameAndSuffix, internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_LOW @@ -11,21 +17,13 @@ const kExpectedRequestsForScriptsInHead = [ internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_HIGH }, { fileNameAndSuffix: kFetchPriorityAutoRequestFileNameAndSuffix, - internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL + internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_HIGH }, { fileNameAndSuffix: kNoFetchPriorityRequestFileNameAndSuffix, - internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL + internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_HIGH } ]; -// Mapping fetchpriority's values to internal priorities is specified as -// implementation-defined (https://fetch.spec.whatwg.org/#concept-fetch, step -// 15). For web-compatibility, Chromium's mapping is chosen, see -// . -// -// The difference of the internal priorities for late- and early-in-body scripts -// is considered important for optimizing the LCP -// (https://developer.mozilla.org/en-US/docs/Glossary/Largest_contentful_paint). const kExpectedRequestsForScriptsInBody = [ { fileNameAndSuffix: "dummy.js?1", internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_LOW @@ -33,11 +31,12 @@ const kExpectedRequestsForScriptsInBody = [ { fileNameAndSuffix: "dummy.js?2", internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_HIGH }, + // Bug 1872654: Chromium's behavior here differs. { fileNameAndSuffix: "dummy.js?3", - internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_HIGH + internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL }, { fileNameAndSuffix: "dummy.js?4", - internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_HIGH + internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL }, { fileNameAndSuffix: "dummy.js?5", internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_LOW @@ -55,6 +54,53 @@ const kExpectedRequestsForScriptsInBody = [ export const kTestFolderName = "script-tests"; +const kExpectedRequestsForNonModuleAsyncAndDeferredScripts = [ + { fileNameAndSuffix: "dummy.js?1", + internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_LOW + }, + { fileNameAndSuffix: "dummy.js?2", + internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_HIGH + }, + { fileNameAndSuffix: "dummy.js?3", + internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_LOW + }, + { fileNameAndSuffix: "dummy.js?4", + internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_LOW + }, +] + +const kExpectedRequestsForDynamicNonModuleScripts = [ + { fileNameAndSuffix: "dummy.js?1", + internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_LOW + }, + { fileNameAndSuffix: "dummy.js?2", + internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_HIGH + }, + { fileNameAndSuffix: "dummy.js?3", + internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_LOW + }, + { fileNameAndSuffix: "dummy.js?4", + internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_LOW + }, +]; + +// Chromium's desired behavior is under discussion: +// . +const kExpectedRequestsForModuleScripts = [ + { fileNameAndSuffix: "dummy.js?1", + internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_LOW + }, + { fileNameAndSuffix: "dummy.js?2", + internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_HIGH + }, + { fileNameAndSuffix: "dummy.js?3", + internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_HIGH + }, + { fileNameAndSuffix: "dummy.js?4", + internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_HIGH + }, +] + export const kTestData = [ { testFileName: "script-initial-load-head.h2.html", expectedRequests: kExpectedRequestsForScriptsInHead @@ -63,24 +109,24 @@ export const kTestData = [ expectedRequests: kExpectedRequestsForScriptsInBody }, { testFileName: "async-script-initial-load.h2.html", - expectedRequests: kExpectedRequestsForScriptsInHead + expectedRequests: kExpectedRequestsForNonModuleAsyncAndDeferredScripts }, { testFileName: "deferred-script-initial-load.h2.html", - expectedRequests: kExpectedRequestsForScriptsInHead + expectedRequests: kExpectedRequestsForNonModuleAsyncAndDeferredScripts }, { testFileName: "module-script-initial-load.h2.html", - expectedRequests: kExpectedRequestsForScriptsInHead + expectedRequests: kExpectedRequestsForModuleScripts }, { testFileName: "async-module-script-initial-load.h2.html", - expectedRequests: kExpectedRequestsForScriptsInHead + expectedRequests: kExpectedRequestsForModuleScripts }, // Dynamic insertion executes non-speculative-parsing // (https://developer.mozilla.org/en-US/docs/Glossary/speculative_parsing) - // code paths. + // code paths. Moreover such inserted scripts are loaded asynchronously. { testFileName: "script-dynamic-insertion.h2.html", - expectedRequests: kExpectedRequestsForScriptsInHead + expectedRequests: kExpectedRequestsForNonModuleAsyncAndDeferredScripts }, { testFileName: "module-script-dynamic-insertion.h2.html", - expectedRequests: kExpectedRequestsForScriptsInHead + expectedRequests: kExpectedRequestsForModuleScripts } ];