-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Speculation Rules - Navigational prefetching and prerendering #620
Comments
Hello. We have an extension to the speculation rules syntax to allow the referrer policy of a speculative request to be set explicitly. A key use case for this is to allow a site with a lax referrer policy to adopt cross-site prefetching by using a strict policy specifically for the prefetch. Explainer: https://github.com/WICG/nav-speculation/blob/main/triggers.md#explicit-referrer-policy (Note that as of this writing, the most recent version of the spec hasn't yet been published at that link, but should be available soon.) Please take a look. |
Just dropping a note here to mention that Chrome is planning an experiment with an expanded subset of this feature soon, notably including document rules, an HTTP response header as an alternative to using an inline Thanks! |
hi @jeremyroman, I have a question - I was trying to collect usage from Chrome and some sample URLs and I do see percentage of page loads over time in https://chromestatus.com/metrics/feature/timeline/popularity/3932 showing over 4%, but then the "Adoption of the feature on top sites" section is empty, as well as returning empty results when I run the sample query at the bottom in BigQuery:
Do you know what's going on with this data? |
Hi @bgrins, HTTP Archive relies on a crawl that takes a while to update and doesn't cover all the cases that we see with Chrome in the wild. In particular, I doubt the HTTP Archive includes any results from search engines, which is one of the primary use cases for speculation rules. That said, it does look like there are a few URLs listed now: But Google.com is also definitely using this feature and is perhaps the most interesting case for you to look at. Jeremy probably missed the GitHub notification for your comment but feel free to reach out to us (eg. rbyers@chromium.org / jbroman@chromium.org) if there's anything we can do to help with testing and evaluation. |
Apologies for the slow response and thanks @RByers for giving a quick summary. We tried to internally look into what exactly is and isn't covered by the archive data that feeds this, and weren't sure whether the Google mobile SERP (which as Rick mentions is one of the largest users in the wild) was intentionally not indexed, was missed due to some quirk of the data collection methodology (for example, the User-Agent string), or something else. We didn't find a great answer to that before the holidays (and then I subsequently fell ill) but Rick's answer covers the overall conclusion. |
Hi. We have delta updates on how the speculation rules should interact with Content Security Policy. Explainer: https://github.com/WICG/nav-speculation/blob/main/triggers.md#content-security-policy We added We also added In short, we clarify how the speculation rules are handled in CSP, and provide a new source keyword to permit safe inline speculation rules without allowing unsafe inline script under the strict CSP environment. Here is an example use.
|
Hello. We have an extension to the speculation rules syntax to explicitly set a No-Vary-Search hint on a speculative request. The hint is useful because prefetches that depend on No-Vary-Search header to match to navigations do not benefit the user if the navigation happens before prefetch headers return from the server. Using the hint, the web browser will wait for a matching in-flight prefetch and will expect, but verify, that the No-Vary-Search hint matches the No-Vary-Search header. If the No-Vary-Search hint does not match the No-Vary-Search header received then the web browser will send a new request to the server. Explainer: https://github.com/WICG/nav-speculation/blob/main/triggers.md#no-vary-search-hint (Note that as of this writing, the most recent version of the spec hasn't yet been published at that link, but should be available soon.) |
Hi, we're expanding the syntax for speculation rules to allow developers to specify the This field provides a hint to indicate a target navigable where a prerendered page will eventually be activated. For example, when <script type=speculationrules>
{
"prerender": [{
"target_hint": "_blank",
"urls": ["page.html"]
}]
}
</script>
<a target="_blank" href="page.html">click me</a> Please see the explainer for the motivation of this extension. Explainer: https://github.com/WICG/nav-speculation/blob/main/triggers.md#window-name-targeting-hints |
We think the use case is good and the user experience when a prerendered page is navigated to seems compelling. We struggle a lot with the JSON syntax and the introduction of a new query language. We have Selectors, and it seems possible to add URL patterns to Selectors. Furthermore, the rebuttals for Example: <link rel="nav-prerender" selector=":link-href('/*'):not(:link-href('/logout?*'), .no-prefetch *)">
<link rel="nav-prefetch" hrefset="next.html, next2.html" requires="anonymous-client-ip-when-cross-origin" referrerpolicy="no-referrer">
...
<a href="other.html" target="_blank" rel="nav-prerender">other</a> The motivation for external speculation rules is "it would be convenient", but that could apply to any HTML metadata? Is it necessary to support external rules? (Filed WICG/nav-speculation#307 for the above.) The cost of mispredicting a prerender (i.e. fetching, parsing, and rendering without using) looks to be significant in terms of CPU time and network bandwidth. Is there a story for minimizing wasted prerenders, if the feature is widely adopted in the future? |
In addition to negative performance impact from wasted prerenders, another downside to prerendering is that it increases complexity to the entire platform by adding a special mode (DelayWhilePrerendering) that can affect the behavior of every other API for both implementers and authors. This is fundamental to the design of having prerender actually load the page. Prefetch with subresources sidesteps this complexity entirely, so it's a pretty compelling option from that standpoint. I would like to know more about this comment, and your experience with NoState prefetch more generally https://github.com/WICG/nav-speculation/blob/main/prerendering-same-site.md#prefetching-with-subresources:
How much more resource consumption, and how much faster were the loads compared with (a) normal prefetch and (b) no speculation at all? What are the same numbers with the new prerendering feature? And what specifically is causing the performance difference between NoState and prerendering - is it mostly executing the page load itself, follow-on requests within the new document that aren't speculated, something else? |
Thanks @zcorpan and @bgrins for chiming in! It seems like there are a few issues here. First, we want to reemphasize that there are at least three separate efforts here, and a clear signal from you would be valuable on all of them:
Regarding the performance impact of prerendering, it's important to keep in mind that a typical web page loads many other web pages that are never interacted with: e.g., ads in iframes. Because of how prerendering delays the loading of cross-origin iframes in a prerendered page, and because of how layout and painting can (if the browser wishes) be delayed until activation, we find that the typical cost to a user's CPU and bandwidth of a prerendered page is about the same order as a single iframe. So although we certainly want to be cautious, it's good to keep the scale of the problem in mind. How prefetch and prerendering use of the HTTP cache also helps reduce waste. Typically, for same-origin prerenders, many assets are reused (site-wide CSS, JS, logos…etc.), so the additional extra cost is due to the document itself (usually quite small), and media (often lazy loaded). Even when a speculation is not used, it can still help prime the cache for future usage so is often not completely wasted (for example if product A is prerendered, but product B is then navigated to instead). One reason we're excited about prerendering as a first-class technology is because it is under the control of the user agent. Without prerendering in the browser, if a page author wants an instant experience, they need to "prerender" by converting their application to a single-page app, and then manually rendering the next page's content offscreen and doing a DOM swap. This is very complicated, so you only see it on highly-resourced SPAs. But also it's opaque to the user agent. With MPA-based navigational preloading, the browser gets to be in complete control of prerender eligibility. For example, Chromium prevents prerendering when the user is in Battery Saver mode, Data Saver mode, under memory pressure, or just chooses to disable preloading through their settings pages. There are also automatic limits on how many prerenders can be ongoing. The user agent is also well positioned to implement more sophisticated triggering heuristics that can improve precision (which would minimize wasted resources) while still having recall/lead times that make preloading viable and useful. And finally, prerendering processes can be intentionally down-prioritized in scheduling algorithms. When pages are doing "prerendering" themselves, they are often not so conscientious about the user's resources. Similar reasoning holds for navigational prefetching, by the way: compared to websites manually using This is also a reason we've so far held the line against exposing the status of an ongoing prerender. We want to make it relatively hard for pages to take a dependency on a prerender: it should always be possible for the user agent to deny a prerender request, or evict a prerendered navigable. (That said, we've gotten repeated requests to expose such state from web developers; see e.g. WICG/nav-speculation#306 and WICG/nav-speculation#162. We're hoping that most of the motivation for such requests will be solved by automatically falling back from prerender to prefetch.) So yes, we think there's a pretty good story for minimizing wasted prerenders :).
Yes, the implementation complexity of prerender is substantial. We've found the developer excitement and movement of metrics it generates to be worthwhile, but we understand the reluctance. We're happy to talk more through the challenges we've faced as part of this if that'd be helpful. But in the meantime we're hopeful that in our role as the first implementer, by writing an exhaustive spec and set of tests, we can ease the burden on second-onward implementations.
Figuring out which of this data I can share exactly is tricky. But let me quote some of our public numbers, as well as a bit of new information I was able to find about the NSP-vs-prefetch live experiment.
(If you have more specific questions that could be answered with data, I can try to see if there is more we could dig up and get approval for sharing. However, the process is somewhat heavyweight, so I'd appreciate it if we saved that for cases that would truly make a difference in Mozilla's priorities.) Note however that, separate from any concerns about resource usage, we are seeing some requests from partners to bring back prefetch-with-subresources: WICG/nav-speculation#305. The basic summary is that navigational prefetch is not exciting enough---the core capability is a more user-respectful version of
It depends on the site. For simple static sites, the difference is mostly in things like setting up the new process, creating all the global JavaScript objects, and initial layout and paint. For complex SPAs, it's a lot of JavaScript processing and subresource fetching, and especially the extra server round trips to get the main content. You can kind of answer this question for any given site by taking a trace for that site and removing all the statically-discoverable resource fetching time. Or, at least for some sites with good caching headers, you can note that an NSP prefetch-powered load is basically the same as a normal warm-HTTP-cache load, which is usually not the same sort of instant (<200 ms) experience you get with prerender. |
Thanks for the detailed reply, and sorry for the delay on our part.
We're positive here and interested in implementing.
We're neutral here. The greatest win over something like NoState Prefetch seems to be for sites that rely on scripts to run for the initial render, especially if needed subresource fetches can only be discovered by running script. When the prerender is successful this can create a much better user experience for page navigation, and which likely outweighs the waste created from unsuccessful prerenders in most cases. However, there are enormous complexity costs to consider with prerendering. Not only within the engines themselves, but also as collateral to all other web APIs and user libraries, which will need to consider their behavior while prerendering. We'd like to better understand the improvement over NoState in a variety of scenarios, and may do our own prototyping with a NoState-style system when a prerender is requested before we consider a full prerender implementation within Gecko.
We had concerns here, but we can live with it and it doesn't seem worth it to change direction on the syntax after the current level of adoption. Neutral. |
Thanks so much Simon and others for taking the time to work through this complex feature! Given the positive position on navigational prefetch, we'll likely spend some time in the new year working on moving the spec to HTML. It sounds like we shouldn't necessarily do that for speculation rules, though? So it'd be some sort of implementation-defined trigger for now (e.g. browser UI). Let us know if that sounds right.
This makes perfect sense to us, and we'd be supportive of speccing this as a possible behavior for prerender. |
Request for Mozilla Position on an Emerging Web Specification
Other information
#613 (comment) :
The text was updated successfully, but these errors were encountered: