bcc: net-dev
Contact emails
Engineering: ri...@chromium.org
Spec
http://tools.ietf.org/html/rfc5861
Summary
We are closing in on adding support for the stale-while-revalidate Cache-control extension in Chrome. This HTTP header extension allows developers to specify an extra period of time during which stale assets can be re-used provided that the browser asynchronously revalidates them.
Not having to block rendering on revalidations should lead to significant improvements to the Load aspect of the RAIL performance model. In particular, mobile should benefit a lot from this given that even revalidations can be quite expensive due to long connection setup and/or Time-To-First-Byte characteristics. See this example on a HSDPA connection:
Implementation status
For a while we had a do-nothing stub that communicated insights about the potential wins via the Resource-freshness header. Implementing the actual behavior proved harder than we originally thought. However, the latest iteration seems to be on the right track and should land in the coming weeks.
Caveats
Extensions: how this should work from the viewpoint of extensions is still under discussion.
Redirection: a bit thorny so it’s out-of-scope for now.
Requires conditional revalidation: assets must be served with Last-modified and/or Etag headers in order to allow for a conditional revalidation. Note: we currently have no plan to relax this requirement (feedback on the associated bug is welcomed).
Authentication: no plan to support this (it doesn’t make any sense as we wouldn’t want to show an authentication UI asynchronously)
Link to “Intent to Implement” blink-dev discussion
N/A (heads up thread; pre Net-dev’s decision to follow the blink process)
Is this feature supported on all six Blink platforms (Windows, Mac, Linux, Chrome OS, Android, and Android WebView)?
Yes.
Demo link
The following services have already deployed or are experimenting with s-w-r:
Debuggability
DevTools’ network tab shows the relevant headers.
We are considering different options for surfacing the asynchronous revalidation requests.
Compatibility Risk
Compatibility risk: low
the header extension has been in use for a while on proxy servers
if we were to unship the header, we wouldn’t break anything
OWP launch tracking bug
https://code.google.com/p/chromium/issues/detail?id=348877
Entry on the feature dashboard
https://www.chromestatus.com/feature/5050913014153216
Experiment with us!
As soon as the new implementation lands and provided this intent to ship is LGTMed, we’ll start an experiment, monitor key metrics as well as feedback from developers, and launch the feature if it’s indeed effective. I will update the thread as soon as the experimental phase starts.
Here is how you will be able to participate in the experiment:
Serve the relevant assets with:
a Cache-control header containing max-age and stale-while-revalidate values
a Last-modified or ETag header
Provided that the user agent is in the experimental group, for any assets served with a strictly positive stale-while-revalidate value, the revalidation requests should include a “Resource-Freshness” header.
Use this header to record the outcome and fine tune max-age and stale-while-revalidate.
You will want to balance asynchronous revalidations (desired outcome) vs. version lag concerns.
Example
When serving an asset, specify the following headers with relevant values:
Last-modified: [...] or ETag: [...]
Cache-control: max-age=86400,stale-while-revalidate=604800
In the revalidation request, you will then see something like:
Resource-Freshness: max-age=86400,stale-while-revalidate=604800,age=95938
max-age and stale-while-revalidate correspond to the original values on the response
age represents how old the asset is relative to the time of the last known fresh state (i.e. initial request or subsequent revalidation)
if (max-age < age <= max-age+stale-while-revalidate) then the revalidation request was asynchronous (desired outcome)
if (age > max-age+stale-while-revalidate) then the revalidation was of the regular synchronous flavor (best avoided)
if you see a Cache-Control:max-age=0 then the revalidation was forced (e.g. reload) and therefore synchronous. Note: the Resource-freshness header will still be present.
Caveats
Extensions: how this should work from the viewpoint of extensions is still under discussion.
Redirection: a bit thorny so it’s out-of-scope for now.
Requires conditional revalidation: assets must be served with Last-modified and/or Etag headers in order to allow for a conditional revalidation. Note: we currently have no plan to relax this requirement (feedback on the associated bug is welcomed).
Authentication: no plan to support this (it doesn’t make any sense as we wouldn’t want to show an authentication UI asynchronously)
Caveats
Extensions: how this should work from the viewpoint of extensions is still under discussion.
Redirection: a bit thorny so it’s out-of-scope for now.
Requires conditional revalidation: assets must be served with Last-modified and/or Etag headers in order to allow for a conditional revalidation. Note: we currently have no plan to relax this requirement (feedback on the associated bug is welcomed).
Ryan, this seems like a fairly strongly negative feedback. It sort of mixes concerns on code health and project priorities with an opinion on the platform API itself. Could we decouple the two? I would like the "intents to ship" to be only about the latter. The former -- however valid and/or strong -- is decided by the team and their technical leadership.Is your main API-related concern that this feature will not have a high enough impact?
Caveats
Extensions: how this should work from the viewpoint of extensions is still under discussion.
Redirection: a bit thorny so it’s out-of-scope for now.
I think we've decided that it's okay to require extensions which use chrome.webRequest to intercept cookies to update and pay attention to a new hook. Given that, redirection should be fairly straight-forward now, no?
URLRequestDelegate sends out some OnAsyncRevalidateNeeded hook and hands you a handle to some AsyncRevalidation object. That may be called multiple times if multiple revalidations are needed. AsyncRevalidation has a Start method so that it may integrate with the ResourceScheduler, at least until we get scheduling more integrated into //net properly, and then all this can go away.
Requires conditional revalidation: assets must be served with Last-modified and/or Etag headers in order to allow for a conditional revalidation. Note: we currently have no plan to relax this requirement (feedback on the associated bug is welcomed).
Why is this requirement necessary? You may need to fetch the entire resource in stale-while-revalidate state too. I could send a random string for the Etag header and ignore If-None-Match headers.
There's a complexity/cost/benefit tradeoff. We know from the past year+ of work on S-W-R that it's high complexity/cost. We also know that there are a number of problems with S-W-R not yet solved, which, after a year, we're somewhat declaring bankruptcy on and punting to the next implementation.
With the benefit, the question is, can we realize these benefits through other means, perhaps with less complexity. For example, for a single site, do Service Workers offer a way to ameliorate the performance concerns? Alternatively, since one of the examples given was Google Fonts, are there other paths - ones where we have a better idea of what the solutions might look like - to meet the design? https://mkruisselbrink.github.io/navigator-connect/use-cases.html is one example of this.
Is there benefit from such a minimal MVP?
I would argue that a service worker based solution for third parties is more complex, if not for us then definitely for the developers. Also, publishers/devrel/partner-relation/... will have a much harder time trying to convince a third party service to support Service Worker vs. supporting s-w-r.
Finally, a SW approach for third parties would not work on first encounters
and has interesting performance concerns that we will need to think about.
Note: the latest on SW for third parties is a very nascent proposal called foreign fetch which I'm still excited about because there is so much more interesting things you could do with a SW than a s-w-r like behavior (e.g. use background sync to update existing assets or prefetch key assets).
Is there benefit from such a minimal MVP?I believe so.
- Extension are not relevant to the benefits we are hoping for.
- Lack of support for redirection has no material impact on the benefit we are hoping for.
- Requiring conditional revalidation should in fact increase the potential benefit
- Lack of support for authentication has no material impact on the benefit we are hoping for.
Caveats
Extensions: how this should work from the viewpoint of extensions is still under discussion.
Redirection: a bit thorny so it’s out-of-scope for now.
I think we've decided that it's okay to require extensions which use chrome.webRequest to intercept cookies to update and pay attention to a new hook. Given that, redirection should be fairly straight-forward now, no?I think that Adam is indeed more confident about it, it's just extra work that we can work on as a follow-up.
URLRequestDelegate sends out some OnAsyncRevalidateNeeded hook and hands you a handle to some AsyncRevalidation object. That may be called multiple times if multiple revalidations are needed. AsyncRevalidation has a Start method so that it may integrate with the ResourceScheduler, at least until we get scheduling more integrated into //net properly, and then all this can go away.
Requires conditional revalidation: assets must be served with Last-modified and/or Etag headers in order to allow for a conditional revalidation. Note: we currently have no plan to relax this requirement (feedback on the associated bug is welcomed).
Why is this requirement necessary? You may need to fetch the entire resource in stale-while-revalidate state too. I could send a random string for the Etag header and ignore If-None-Match headers.I think the important point is that with this requirement in place, fetching a new asset is an eventuality not a necessity which I believe is best for our users. Sure, you can send a dummy ETag and always ignore it but why would you?
Quick point about discussion (and attempt at reiterating Dimitri's point): Let's try to separate out the "Should this be part of the Web Platform API" from the "Is current implementation ready to ship" discussion.Unless I'm missing something, it doesn't seem like there's something fundamentally unsolvable with the current state of the implementation that would require rethinking the API contract.
Re: interoperability, the s-w-r spec has been stable for years. The lack of support for redirection in our MVP is a temporary caveat, it will be fixed. As for the requirement on conditional revalidation, if the correct thing is to relax it then so be it, that's why I left the bug opened. Last, Authentication on the async revalidation doesn't make sense (this seems obvious but I've reached back to Mark to get his take on whether or not the spec need to be more explicit about user agent specifics).
Re lack of support for extension (not really an interop matter), it will be fixed too.
As for the catering to a subset of the use cases, that's exactly the point of an MVP. Does it end there? Absolutely not or we wouldn't call it an MVP.
Finally, regarding the "how about doing this through SW + foreign fetch":
- foreign fetch isn't yet a thing but let's assume it delivers.
- let's assume that a good chunk of the commonly used third parties roll their own SW just to do s-w-r.
- on a typical website, how many third parties do you think are used on average? Do you think having all these SW to start and run will actually scale and still be a performance win? I'm highly skeptical of it.
Re: interoperability, the s-w-r spec has been stable for years. The lack of support for redirection in our MVP is a temporary caveat, it will be fixed. As for the requirement on conditional revalidation, if the correct thing is to relax it then so be it, that's why I left the bug opened. Last, Authentication on the async revalidation doesn't make sense (this seems obvious but I've reached back to Mark to get his take on whether or not the spec need to be more explicit about user agent specifics).
On Wed, Sep 2, 2015 at 5:22 PM Kenji Baheux <kenji...@chromium.org> wrote:Re: interoperability, the s-w-r spec has been stable for years. The lack of support for redirection in our MVP is a temporary caveat, it will be fixed. As for the requirement on conditional revalidation, if the correct thing is to relax it then so be it, that's why I left the bug opened. Last, Authentication on the async revalidation doesn't make sense (this seems obvious but I've reached back to Mark to get his take on whether or not the spec need to be more explicit about user agent specifics).
I agree that punting authentication on an async revalidations is fine. Though you could argue that we risk silently turning SWR into max-age=infinity.
--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+unsubscribe@chromium.org.
Hi Timo,
Thanks for chiming on this thread!
Is Wikimedia interested in stale-while-revalidate? Can you share more details about the use case and expected impact?
Also, did you have the chance to talk about the feature with engineers at Mozilla or other browser vendors?
Done.☆PhistucK
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.
[..] refresh is asynchronously, instead of blocking the JS pipeline on the page view. [1] [..]