Skip to content
This repository was archived by the owner on Mar 10, 2023. It is now read-only.

Commit 0b07d48

Browse files
authored
Merge pull request #13 from addyosmani/cleanup
Repo re-organization
2 parents 6479c01 + 1140167 commit 0b07d48

File tree

3 files changed

+220
-207
lines changed

3 files changed

+220
-207
lines changed

EXAMPLES.md

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
## Usage Examples
2+
3+
* `<img src=foo group=visual>` - An image is to be loaded with relatively high
4+
priority as it's impacting the initial visual.
5+
* `<img src=foo before=visual>` - An image is to be loaded with higher priority
6+
than other visually impacting resources. (e.g. since it's a hero image, more
7+
important than other in-viewport images)
8+
* `<link rel=preload href=foo as=image group=visual>` - An image should be
9+
preloaded as impacting the initial visual, but not load before critical
10+
resources were discovered, as it will likely contend on bandwidth with them.
11+
* `<link rel=preload href=foo as=image group=critical>` - An image should be
12+
preloaded as a critical resource (e.g. potentially because the page has no
13+
other critical resources as they are all inlined)
14+
* That's already the default behavior of browsers in current
15+
implementations, but developers would be able to explicitly state that
16+
preference.
17+
* `<link rel=stylesheet href=foo group=late>` - can be used to indicate
18+
non-blocking style which isn't impacting the initial visual experience.
19+
* `<iframe src=foo group=late>` - would downgrade the importance of the iframe
20+
and all its subresources.
21+
* TBD - what does the fetch API parameter look like?
22+
* TBD - how does explicit reprioritization look like?
23+
24+
25+
## Use Cases
26+
27+
This section outlines the different use-cases this effort sets to
28+
address. It is worth noting that priority in these examples should not
29+
limit itself to network priority (i.e. request time and HTTP/2
30+
dependencies and weights), but also to processing priority, as the
31+
browser can use the same signals in order to avoid processing of low
32+
priority resource in favor of higher priority ones.
33+
34+
### Communicate resource importance to the browser
35+
The browser assigns priorities and certain dependencies to downloaded
36+
resources and uses them to determine:
37+
* When the resource's request is sent to the server.
38+
* What HTTP/2 dependencies and weights are assigned to the resource's
39+
request.
40+
41+
The browser uses various heuristics in order to do the above, which are
42+
based on the type of resource, its location in the document and more.
43+
44+
Occasionally, web developers are in a better position to know which
45+
resources are more impactful than others on their users' loading experience,
46+
and need a way to communicate that to the browser.
47+
48+
A few examples:
49+
* Markup images are typically loaded with low/medium priority, but may
50+
be critical to the user experience, so for certain images, the
51+
developer may want to indicate that their importance only falls short of
52+
the page's render blocking resources. A prominent example of that is
53+
the page's image in an image sharing site, where the image is the
54+
main content users are looking for. Another example is a single-page-app
55+
where route fetches must run at highest priority.
56+
* Async Javascript files may be loaded by default with low priority, but
57+
some of them may be of high priority and should be loaded at the same
58+
time as the page's render blocking resources. Developers currently use
59+
[hacks](https://twitter.com/cramforce/status/900445266750263296) to
60+
address that use-case.
61+
* Blocking scripts are often of high/medium priority (depends on their
62+
location in the page and other heuristics), yet sometimes developers
63+
want to avoid them interfering with e.g. loading of viewport images.
64+
* Third-party resources (e.g scripts from ads) are often loaded with
65+
medium/high priority, but developers may wish to load them all at low
66+
priority. Similarly, developers may wish to load all first-party
67+
resources that are critical with a high priority.
68+
* When developers download a group of resources as a result of user interaction, those
69+
resources download priorities don't take into account the eventual usage and importance
70+
of those resources. Developers may wish to load these resources with priorities and
71+
dependencies which better represent their usage and the user's needs
72+
* Single-page applications can kick off multiple API requests to
73+
bootstrap the user experience. Developers may wish to load critical
74+
API requests at a high priority and have better control over scheduling
75+
priority for the rest.
76+
77+
### Signal a resource as non-critical
78+
Using `<link rel=preload>` in order to get the browser to early
79+
discover certain resources, especially in its header form, means that the
80+
browser may discover these resources before other, more critical resources and
81+
send their request to the server first. That can result in loading regressions
82+
as the server may start sending those non-critical resources before other, more
83+
critical ones, which may fill up the TCP socket sending queues.
84+
While better transport protocols (e.g. QUIC) may address that at a lower layer
85+
for the single origin case, developers should be able to signal to the browser
86+
that a certain resource is not critical, and therefore should be queued until
87+
such resources are discovered.
88+
Such marking as "non-critical" should be orthogonal to the signaling of
89+
the resource's "importance" (e.g. this could be applied to high priority
90+
resources that shouldn't contend with rendering-critical resources as
91+
well as low priority ones).
92+
93+
### Avoid bandwidth contention in multiple origin scenarios
94+
When loading resources from multiple origins, setting HTTP/2
95+
dependencies and weights do very little to avoid bandwidth contention
96+
between the origins, as each origin tries to send down its most critical
97+
resource without knowing of more critical resources in other origins.
98+
Signaling resource importance to the browser can enable it to defer
99+
sending of non-critical third party requests while critical resources
100+
are still being downloaded.
101+
102+
### Provide priority signals for markup-based resources
103+
Developers need a way to provide the above signals for resources that
104+
are loaded through markup (or through markup-equivalent HTTP headers,
105+
e.g. `Link:`)
106+
107+
### Provide priority signals for dynamically loaded resources
108+
Developers need a way to provide the above signals for resources that
109+
are fetched through Javascript, e.g. using the `fetch()` API.
110+
That would enable them both to upgrade and downgrade those resource's
111+
"importance".
112+
113+
### Provide the ability to re-prioritize a resource in-flight
114+
* "Resource priority" is not always the right way of looking at it. For
115+
resources that are parsed on-the-fly (most notably HTML and progressive images),
116+
their first buffer is often more important than their last. Developers
117+
can use the ability to reprioritize resources to reflect that when
118+
downloading such resources.
119+
* There are also cases where the priority of a resource changes due to
120+
user action or condition changes. One example is the loading of
121+
images, where in-viewport images (or soon-to-be in-viewport images) are
122+
of higher priority than images that are further away from the viewport
123+
and therefore less likely to be seen by the user.
124+
125+
### Downgrade priority of an iframe and its subresources
126+
When developers load a third party iframe, they may wish to make sure
127+
that it does not contend on bandwidth and/or CPU with the more important
128+
first party content of the page. Alternatively, they may wish to
129+
signal the browser that a certain third party iframe is as important as
130+
the main page content and should be given CPU and bandwidth resources
131+
accordingly.
132+
133+
When such a signal is applied to an iframe, it should be equally applied
134+
to all the subresources that the iframe loads.

EXPLAINER.md

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Priority Hints
2+
3+
The browser's resource loading process is a complex one. Browsers discover
4+
needed resources and download them according to their heuristic priority.
5+
Browsers may also use this heuristic resource priority to delay sending
6+
certain requests in order to avoid bandwidth contention of these resources
7+
with more critical ones.
8+
9+
Currently web developers have very little control over the heuristic
10+
importance of loaded resources, other than speeding up their discovery
11+
using `<link rel=preload>`.
12+
Browsers make many assumptions on the importance of resources based on the
13+
resource's type (AKA its request destination), and based on its location
14+
in the containing document.
15+
16+
This document will detail use cases and an API/markup sketch that will
17+
provide developers with the control to indicate a resource's
18+
relative importance to the browser, and enable the browser to act on
19+
those indications to modify the time it sends out the request and its
20+
HTTP/2 dependency/weight so that important resources are fetched and used
21+
earlier, in order to improve the user's experience.
22+
23+
### Adoption path
24+
Markup based signal should be added in a way such that non-supporting
25+
browsers will simply ignore them and load all resources, potentially not
26+
in the intended priority and dependency. Script based signaling APIs
27+
should be created in a way that non-supporting browsers simply ignore
28+
the signals.
29+
30+
## Out of scope
31+
* Signal that certain images should not block the load event
32+
* Signals relating the script execution order, script execution
33+
grouping, execution dependency, etc
34+
35+
## Solution
36+
We propose to address the above use-cases using the following concepts:
37+
* We will define a new set of standard `fetch-groups` that will map to current
38+
browser priorities: `critical`, `fonts`, `functional`, `visual`, `late`
39+
* Names TBB (to be bikeshedded)
40+
* Developers would be able to assign resources into those groups or
41+
define resources as more or less important than said groups.
42+
* Developers would be able to define custom fetch groups, and assign
43+
resources to them, or define them as more or less important than said
44+
groups
45+
* This is necessary in order to be able to define two "levels" of
46+
resource importance between existing groups.
47+
* This also adds a lot of complexity - what if the group definitions
48+
as resource attributes don't match? If a group is declared to be
49+
fetched after a not-yet-discovered group, should the browser wait? How
50+
long?
51+
* TODO: Is this use case worth the extra complexity? Any examples
52+
where this is required?
53+
54+
This is how we conceptually think about different resource types under the hood in browsers today.
55+
It may translate well to user-space where different types of content share similar properties.
56+
57+
## Open questions
58+
59+
**What final form will this API take?**
60+
61+
### Alternative approach to the above proposal
62+
An early sketch for what a declarative solution could look like uses the notion of `fetch-class` groups:
63+
64+
```html
65+
<img fetch-class="shop-branding" src="logo.png" higher-priority-than="shop-scripts" lower-priority-than="shop-item">
66+
67+
<script fetch-class="shop-scripts" src="lazy-loader.js">
68+
69+
<img fetch-class="shop-item" src="product-01.png">
70+
<img fetch-class="shop-item" src="product-02.png">
71+
```
72+
73+
**Does there need to be a mechanism for limiting priorities per domain?**
74+
75+
Scenario: Third-party iframes could mark all of their resources as the highest priority.
76+
This could negatively impact the performance of the top-level document or origin.
77+
78+
Possible solution: each individual origin could have a priority controller for its
79+
connection(s) and an overall priority controller for the page load balancing them.

0 commit comments

Comments
 (0)