Comments (4)
See #8470 (review) and #8470 (comment). @pmeenan mentioned that in the spec discussion (presumably this means discussion in the Priority Hints spec, before the HTML upstreaming was started) that priority would not cascade down / be inherited by dependent resources. The why behind this is not obvious to me, so maybe Pat can link to some of the spec discussion he referred to and help us clarify this?
from html.
It was a simplifying decision around scripts, iframes and modules that the fetchpriority
was specifically just for the resource that it was tagged on and that there were no downstream effects on fetching or execution.
At least in Chrome, "auto" for a module script dependency should already be high and you wouldn't be able to boost it anymore. It's less clear that you'd want dependencies to be lowered again after the main resource was loaded or what that would even mean (i.e. for a script, would every fetch from within the script get a forced priority change, what would break if that were the case).
It's a bit clearer in the iFrame case for something like a video embed or chat widget (ignore for now that fetchpriority doesn't actually apply to iframes but consider the grouping). Just because you want the frame itself to load later doesn't mean you want it to load slowly once it has started.
So, we decided that fetchpriority on the main resource would control when things started but would then get out of the way and if we had a case for more fine-grained control over grouped execution contexts that that would be something else solved at a different time (once the use case for it was clear).
from html.
At least in Chrome, "auto" for a module script dependency should already be high and you wouldn't be able to boost it anymore. It's less clear that you'd want dependencies to be lowered again after the main resource was loaded or what that would even mean (i.e. for a script, would every fetch from within the script get a forced priority change, what would break if that were the case).
I think there's a difference here between "script A loads script B" (in which I agree we don't want to inherit priority automatically) and "script A statically imports script B" in which script A will not execute until script B is there. I think it makes sense to consider A & B the same resource in this case, as they are totally co-dependent.
Aside: I missed the fact that module scripts don't get priority modifications in Chromium. That means that this doesn't matter in practice (in Chromium) when upgrading priority, but can definitely matter when downgrading it.
from html.
Even in the downgrade case, because of the late discover of imports, it's not obvious that cascading the downgrade is the "right" thing to do.
Example
Let's say we have a page with a module script a.js
that imports b.js
and there are 100 images on the page where the first one is a hero image:
...
<script type="module" src="a.js"></script>
<img src="1.jpg">
<img src="2.jpg">
...
On the browser side, some simplifying assumptions for the purpose of the example (close enough to actual behavior):
- There are 2 priority levels,
high
andlow
- Module scripts and imports default to a
high
priority - Images default to a
low
priority fetchpriority=high
moves a resource tohigh
priorityfetchpriority=low
moves a resource tolow
priority
Also assume we have a browser and server that honor prioritization:
- Resources are requested/served in priority order
- Resources of the same priority are requested/served in the order they are discovered
Let's say that a.js
is a script that is important to the page but not to the user experience, like an analytics script where you want it to run as soon as possible so you can track abandons but not block the user experience.
Default loading behavior
By default, the order for the resources being loaded would be something like:
a.js
is transferred1.jpg
is transferred (already in-flight whenb.js
is being requested)b.js
is transferreda.js
executes- Images 2-100 are transferred
Adjusting with fetchpriority
By default, a.js
is delaying the hero image so we boost the priority of the hero image and lower the priority of a.js
:
...
<script type="module" src="a.js" fetchpriority=low></script>
<img src="1.jpg" fetchpriority=high>
<img src="2.jpg">
...
Priority does NOT cascade
In the case where the priority for module scripts does not affect the import priorities, b.js
will be transferred at a high priority once it is discovered after a.js
has loaded:
1.jpg
is transferreda.js
is transferred2.jpg
is transferred (already in-flight)b.js
is transferreda.js
executes- Images 3-100 are transferred
It's not perfect, but it gets a.js
out of the way of the hero image but still allows it to execute before the other images load.
Priority cascades
In the case where the priority for module scripts does affect the import priorities, b.js
will be transferred at a low priority once it is discovered after a.js
has loaded. This is after all of the images have already been discovered so it will be queued behind all of them:
1.jpg
is transferreda.js
is transferred- Images 2-100 are transferred
b.js
is transferreda.js
executes
This delays the execution of a.js
until after everything else on the page has already loaded. That's a pretty big footgun if it wasn't expected.
Bundles
In the case of bundling the modules at build time, b.js
would be included in a.js
and it would effectively load at the same time as a.js
:
1.jpg
is transferreda.js
is transferred (withb.js
included)a.js
executes- Images 3-100 are transferred
Thoughts
Not cascading is the closest to "bundled" behavior and basically mimics the behavior of Fonts where late-discovery of resources that are needed by the thing they are loaded by are loaded at a high priority because they are needed now.
The discovery changes a bit when it comes to import maps or preloads so I could see making a case for "fetchpriority=low on a module script where the imports are already in-flight does not modify the priority of the existing requests" so you could get the ordering directly from the import maps or preloads but I don't think it should be the default behavior.
The other option would be to extend loading=lazy or something like that to module scripts of you want a situation where the imports all load at idle time.
from html.
Related Issues (20)
- [rendering] animation frame callback handling when iframes are involved HOT 18
- "On platforms where Esc is the close request, the user agent will first fire an appropriately-initialized keydown and keyup event sequence" is confusing HOT 1
- [parsing] "adoption agency algorithm" ambiguity
- Error reporting in HostEnqueuePromiseJob is not specified nor interoperable HOT 1
- Errors when attaching a declarative shadow root HOT 12
- image.decode() interacts weirdly with the sync cases in "update the image data" HOT 10
- Silence Jake diagram conformance warnings on CI
- Discussing how to focus navigate display: contents elements that are focusable in CSS reading-flow HOT 5
- Upcoming WHATNOT meeting on 2024-08-01 HOT 1
- Example in parallelism section needs to "queue a task" to handle the promise
- Meeting 5 for joint OpenUI-WHATWG/HTML-CSSWG task force on styleable form controls HOT 3
- Allow explicitly indicating an `unchecked` state for an `<input type="checkbox">`. HOT 3
- Upcoming WHATNOT meeting on 2024-08-08
- Discussing how to focus navigate absolute position elements that are focusable in CSS reading-flow
- Rationale for when invalid value default differs from missing value default HOT 6
- Chinese Translation of HTML Standard Completed HOT 3
- Script element schematic diagram for async/defer is not readable in dark mode HOT 6
- inconsistent input label `:active` and `:hover` behavior HOT 1
- Document "can have its URL rewritten" incorrectly rejects file:// URL with only query changed HOT 3
- HTMLConstructor construction steps: Incorrect exception specified in step 11.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from html.