Closed Bug 1425310 (modulepreload) Opened 7 years ago Closed 2 years ago

Implement link rel="modulepreload"

Categories

(Core :: DOM: Core & HTML, enhancement, P3)

55 Branch
enhancement

Tracking

()

RESOLVED FIXED
115 Branch
Tracking Status
firefox115 --- fixed

People

(Reporter: d, Assigned: zqianem)

References

(Blocks 2 open bugs)

Details

(Keywords: dev-doc-complete)

Attachments

(1 file)

modulepreload is a new link relation that behaves similar to preload, but different in several key ways. For example, it interprets its attributes and changes to them differently; it uses the module map instead of the preload cache; and it allows optionally fetching descendant modules as an optimization. Spec: https://html.spec.whatwg.org/multipage/links.html#link-type-modulepreload Tests: https://github.com/w3c/web-platform-tests/blob/master/preload/modulepreload.html
Priority: -- → P3
Preloading is currently disabled and will be re-enabled by bug 1394778.
Depends on: 1394778
FWIW the processing module for modulepreload is unrelated to that for preload so I don't think bug 1394778 is actually a dependency.

Until recently (I'd need to parse Firefox versions to confirm when this occurred), web pages could leverage rel="preload" to ensure the early download of a JS file (and as spec'd early parsing) regardless of whether the script was later loaded as type="module" or not. However, the current experience is that while the preload occurs, a script included in the page as type="module" is then downloaded a second time. See https://modern-web.dev/ as an example as discussed in https://bugs.chromium.org/p/chromium/issues/detail?id=1178198#c9

It seems Chrome is likely to move to this more strict interpretation of the rel="preload" spec and pages will need to move to rel="modulepreload" to get performance benefits in type="module" scripts anywhere, so I was hoping it would be possible to get an update on whether Firefox saw this as something they'd be able to implement.

I think <link rel="modulepreload"> is currently one of the most important features to be implemented in Gecko, as pages load a lot slower without this.

Without modulepreload, the user agent must first download the primary JavaScript file before it can download its dependencies specified in an ES6 import. These imported JavaScript modules can import other modules as well, and so on. Because of this, the user agent has to make several network requests successively instead of making them all at once in parallel. This results in a noticeably slower page loading speed.

To better illustrate this, here is a screenshot of Chromium's waterfall of JavaScript files of some website of mine and here is the same website's JavaScript files download timeline in Firefox. Notice how without modulepreload support, Gecko has to wait for the first file to be downloaded before it can download the other files imported by it. These files themselves import other files which then also import yet another set of files. Blink however can download all JavaScript files in parallel, which results in a ~4 times better loading speed.

Blink is currently the only browser engine that supports this, which is a shame because preloading JavaScript modules is an essential thing that modern browsers are supposed to support. This has been specified for over five years now in the official HTML specification, which is another reason to implement this. As @Westbrook already pointed out, there is no way to polyfill this feature with things like <link rel="preload">.

Jon, is this worth re-triaging, perhaps?

Flags: needinfo?(jcoppeard)

I'm a maintainer of Svelte / SvelteKit and contributor to Vite, which are large and growing projects in the JS ecosystem (https://2021.stateofjs.com/en-US/conclusion). We are using ESM modules almost exclusively and are seeing more and more of the JS ecosystem moving this direction. Vite and SvelteKit provide modulepreload on all pages out-of-the-box and performance is greatly improved in Chrome compared to Firefox as a result. I would find it very valuable if the priority and severity were bumped on this one.

I saw that https://bugzilla.mozilla.org/show_bug.cgi?id=1773056 was marked as duplicate of this, are Mozilla in favor of implementing modulepreload also in link headers? See spec PR: https://github.com/whatwg/html/pull/7862

(In reply to Noam Rosenthal from comment #8)

I saw that https://bugzilla.mozilla.org/show_bug.cgi?id=1773056 was marked as duplicate of this, are Mozilla in favor of implementing modulepreload also in link headers? See spec PR: https://github.com/whatwg/html/pull/7862

As there was no feedback on this question and they are actually two different features, I've reopened bug 1773056 now. Though Yoshi, feel free to mark the other bug as duplicate again if you think both the HTML attribute and the HTTP header will be implemented in this bug.

Sebastian

Severity: normal → S3
Blocks: 1798319

Usage of modulepreload has been growing steadily at about 3x annually for the past few years despite the lack of support in Firefox. This is a key feature of the web platform and Chrome's performance is noticeably better than Firefox's on sites that leverage it.

https://chromestatus.com/metrics/feature/timeline/popularity/2232

This seems to have hundreds of ms page load impact for 1% of page views and 1% top sites (per above chrome use counter).

I checked a page (https://www.norwoodrun.com/) from the "Adoption of the feature on top sites" list and checked how it uses modulepreload. It's a Vimeo video player embed (https://player.vimeo.com/video/364490447). I ran https://www.webpagetest.org/ for the vimeo url in Firefox and Chrome; Firefox is 400ms slower to Start Render (1300ms vs 1700ms). The waterfall chart shows the module scripts being loaded in parallel in Chrome and in sequence in Firefox.

Firefox: https://www.webpagetest.org/result/230220_BiDcEZ_7AM/1/details/#waterfall_view_step1
Chrome: https://www.webpagetest.org/result/230220_AiDcTB_7JV/1/details/#waterfall_view_step1

Performance Impact: --- → ?

WebKit/WebKit#10419 was merged, so WebKit now has modulepreload support along with Chrome.

We were previously able to polyfill modulepreload. However, something has changed in recent versions of Firefox making it so that using the polyfill always results in duplicate requests being issued (guybedford/es-module-shims#354). We've had a number of web dev experts looking at it and no one's been able to come up with a solution other than just living with the duplicate requests. However, that's a highly unsatisfying solution and is really increasing our desire to see this implemented natively.

Assignee: nobody → zqianem
Status: NEW → ASSIGNED
Performance Impact: ? → ---
Pushed by jcoppeard@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/be054669251a Implement modulepreload for link rel. r=yulia,smaug,jonco
Created web-platform-tests PR https://github.com/web-platform-tests/wpt/pull/39539 for changes under testing/web-platform/tests
Upstream PR was closed without merging
Attachment #9322582 - Attachment description: Bug 1425310 - Implement modulepreload for link rel. r?yulia,smaug → Bug 1425310 - Implement modulepreload for link rel. r=yulia,smaug,jonco
Pushed by opettay@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/b288a387f790 Implement modulepreload for link rel. r=yulia,smaug,jonco
Upstream PR was closed without merging
Pushed by opettay@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/1ef27d4a851e Implement modulepreload for link rel. r=yulia,smaug,jonco
Upstream PR was closed without merging
Pushed by opettay@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/0054de12b39c Implement modulepreload for link rel. r=yulia,smaug,jonco
Flags: needinfo?(zqianem)
Status: ASSIGNED → RESOLVED
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → 115 Branch
Upstream PR merged by moz-wptsync-bot
Regressions: 1832361

Backed out while the issue is being investigated(Bug 1832361)

Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Target Milestone: 115 Branch → ---
Created web-platform-tests PR https://github.com/web-platform-tests/wpt/pull/39929 for changes under testing/web-platform/tests
Upstream PR merged by moz-wptsync-bot
Pushed by opettay@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/3bb8a8b46f3c Implement modulepreload for link rel. r=yulia,smaug,jonco
Created web-platform-tests PR https://github.com/web-platform-tests/wpt/pull/40002 for changes under testing/web-platform/tests

Backed out for failures on /preload/modulepreload.html

[task 2023-05-13T17:41:02.938Z] 17:41:02     INFO - TEST-START | /preload/modulepreload.html
[task 2023-05-13T17:41:02.972Z] 17:41:02     INFO - Closing window 9c1102f3-02ef-455e-901d-f3a77324ddfb
[task 2023-05-13T17:41:16.503Z] 17:41:16     INFO - Got content assert count 1
[task 2023-05-13T17:41:16.576Z] 17:41:16     INFO - TEST-UNEXPECTED-FAIL | /preload/modulepreload.html | assertion count 1 is more than expected 0 assertions
[task 2023-05-13T17:41:16.577Z] 17:41:16     INFO - TEST-OK | /preload/modulepreload.html | took 13639ms

Other TVw failure: TEST-UNEXPECTED-FAIL | /preload/modulepreload.html | link rel=modulepreload - assert_equals: resources/dummy.js?unique expected 1 but got 0

Flags: needinfo?(jcoppeard)
Flags: needinfo?(zqianem)
Upstream PR was closed without merging
Pushed by opettay@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/e1770e1308d6 Implement modulepreload for link rel. r=yulia,smaug,jonco
Flags: needinfo?(zqianem)
Status: REOPENED → RESOLVED
Closed: 2 years ago2 years ago
Resolution: --- → FIXED
Target Milestone: --- → 115 Branch
Upstream PR merged by moz-wptsync-bot

FYI FF115 Docs work for this is complete/awaiting reviews. Detail can be found in https://github.com/mdn/content/issues/27177

Regressions: 1842792
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: