-
Notifications
You must be signed in to change notification settings - Fork 22
Preload headers on sub resources #92
Description
Preload is useful as it allows one to help the browser discover a resource before it would/could naturally discover it. Especially with regards to indirection (e.g. the resource is not already specified directly somewhere in the HTML document, or is sufficiently far down in the source that it makes sense to specify it higher up or in a header as well).
However, sometimes this indirection is inevitable or even by design. Three use cases laid out below:
-
Background image. Wikipedia's sidebar is toward the bottom of the HTML payload - after the main content. In addition, the main logo is actually specified by a CSS background-image, not an IMG element. As such, browser don't fetch the logo until the CSS is downloaded/parsed and the entire HTML payload is download, parsed and has its styles applied.
-
Immutable scripts from a "startup" module. ResourceLoader's design document explains how all JS modules are served from immutable urls. That is to say, the module urls are versioned using a hash of their content. However, to ensure a consistent user experience from one page to another, and to allow quick deployments, the urls are not embedded in the (CDN-cached) HTML. Instead, we may use of an (async) "startup" script - which is the only mutable script ("not versioned"). As such the urls to the main script payloads is in this script response and not fetched until the browser has downloaded, parsed and executed this first JavaScript resource.
-
Third-party sub resources. This use case doesn't apply to me personally, but I've seen it elsewhere. You include a third-party script (e.g. Google JS libraries, or stylesheet (e.g. something like jQuery UI or Bootstrap CSS). This third-party resource has sub resources (images, or other scripts) that are not discovered until run time.
These cases have three things in common:
- They fetch sub resources not present in the HTML and logically also cannot be or should not be.
- The sub resources (leaf nodes) are triggered indirectly (e.g. there is at least one sub resource in between the HTML and the leaf node).
- Hardcoding them in preload on the HTML response would inevitably lead to a situation where cached content will result in preloading resources that are ultimately not used because the resources have changed url.
In these cases I think a significant improvement can be made without violating the requirements. Namely if we could specify preload of resources on sub resources.
- The HTML cannot specify the logo url, but the stylesheet response could have a Link header that says to preload the logo. This way, regardless of download/parsing/applying HTML/CSS, it can discover the fetch instruction as soon as it receives the headers of the stylesheet. Not as good as directly on the HTML, but certainly a significant improvement.
- The JavaScript contains a url, and the response can also set this url in a preload header. Again, this means that the fetch will not be delayed until the browser has downloaded and parsed the JavaScript and has arrived at its async or deferred execution slot, but instead it will start fetching as soon as it has the start of the JS response.
- The third-party library can send preload headers on their scripts or stylesheets. This could greatly benefit the way people use libraries from CDNs. (Personally I prefer self-hosting over use of CDNs, but as shows by case 1 and 2, this is not limited to CDNs.)