Skip to content

Commit

Permalink
Implement modulepreload in early hints
Browse files Browse the repository at this point in the history
The aEarlyHintPreloaderId parameter for StartLoad/StartLoadInternal is changed
to be a member variable of ScriptLoadRequest instead so that an initiator type
of early hints can be set for module requests. Before, ModuleLoader would always
pass in a zero value for the id since ModuleLoaderBase has no concept of early
hints when it calls StartFetch.

As a prerequisite for early hints support, this commit also implements
modulepreload in link headers (Bug 1773056).

Differential Revision: https://phabricator.services.mozilla.com/D180020

bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1798319
gecko-commit: 5cafcb0a03c862dea23b88faae77b0e79693fcc6
gecko-reviewers: manuel, smaug, necko-reviewers, kershaw
  • Loading branch information
zqianem authored and moz-wptsync-bot committed Jun 26, 2023
1 parent 92189cb commit 5bbe09d
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// META: script=/common/utils.js
// META: script=resources/early-hints-helpers.sub.js

// see modulepreload-in-early-hints.h2.window.js for params explanation
test(() => {
const params = new URLSearchParams();
params.set("description",
'Modulepreload should not load with as="worker" from cross-origin url');
params.set("resource-url",
CROSS_ORIGIN_RESOURCES_URL + "/empty.js?" + token());
params.set("as", "worker");
params.set("should-preload", false);
const test_url = "resources/modulepreload-in-early-hints.h2.py?" + params.toString();
window.location.replace(new URL(test_url, window.location));
});
15 changes: 15 additions & 0 deletions loading/early-hints/modulepreload-as-worker.h2.window.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// META: script=/common/utils.js
// META: script=resources/early-hints-helpers.sub.js

// see modulepreload-in-early-hints.h2.window.js for params explanation
test(() => {
const params = new URLSearchParams();
params.set("description",
'Modulepreload should load with as="worker" from same-origin url');
params.set("resource-url",
SAME_ORIGIN_RESOURCES_URL + "/empty.js?" + token());
params.set("as", "worker");
params.set("should-preload", true);
const test_url = "resources/modulepreload-in-early-hints.h2.py?" + params.toString();
window.location.replace(new URL(test_url, window.location));
});
13 changes: 13 additions & 0 deletions loading/early-hints/modulepreload-cross-origin.h2.window.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// META: script=/common/utils.js
// META: script=resources/early-hints-helpers.sub.js

// see modulepreload-in-early-hints.h2.window.js for params explanation
test(() => {
const params = new URLSearchParams();
params.set("description", "Modulepreload works in early hints from cross-origin url");
params.set("resource-url",
CROSS_ORIGIN_RESOURCES_URL + "/empty.js?" + token());
params.set("should-preload", true);
const test_url = "resources/modulepreload-in-early-hints.h2.py?" + params.toString();
window.location.replace(new URL(test_url, window.location));
});
10 changes: 10 additions & 0 deletions loading/early-hints/modulepreload-in-early-hints.h2.window.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
// META: script=/common/utils.js
// META: script=resources/early-hints-helpers.sub.js

// params are sent to a Python handler[1] that returns a 103 Early Hints
// response based the values of "resource-url" and "as", and then that response
// is validated by a window test[2] according to the value of "should-preload"
//
// see: https://web-platform-tests.org/writing-tests/h2tests.html
//
// [1]: resources/modulepreload-in-early-hints.h2.py
// [2]: resources/modulepreload-in-early-hints.h2.html
test(() => {
const params = new URLSearchParams();
params.set("description", "Modulepreload works in early hints");
params.set("resource-url",
SAME_ORIGIN_RESOURCES_URL + "/empty.js?" + token());
params.set("should-preload", true);
const test_url = "resources/modulepreload-in-early-hints.h2.py?" + params.toString();
window.location.replace(new URL(test_url, window.location));
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@

def handle_headers(frame, request, response):
resource_url = request.GET.first(b"resource-url").decode()
link_header_value = "<{}>; rel=modulepreload".format(resource_url)
as_value = request.GET.first(b"as", None)
if as_value:
link_header_value = "<{}>; rel=modulepreload; as={}".format(
resource_url, as_value.decode())
else:
link_header_value = "<{}>; rel=modulepreload".format(resource_url)
early_hints = [
(b":status", b"103"),
(b"link", link_header_value),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@
});
}

const params = new URLSearchParams(window.location.search);
const description = params.get("description");

promise_test(async (t) => {
const params = new URLSearchParams(window.location.search);
const resource_url = params.get("resource-url");
const should_preload = params.get("should-preload") === "true";
await fetchModuleScript(resource_url);
assert_true(isPreloadedByEarlyHints(resource_url));
}, "Modulepreload in an early hints.");
assert_equals(isPreloadedByEarlyHints(resource_url), should_preload);
}, description);
</script>
</body>

0 comments on commit 5bbe09d

Please sign in to comment.