Intent to Ship: support for stale-while-revalidate (HTTP Cache-Control Extension)

194 views
Skip to first unread message

Kenji Baheux

unread,
Aug 31, 2015, 8:40:45 PM8/31/15
to blink-dev, Adam Rice

bcc: net-dev


Contact emails

Engineering: ri...@chromium.org

PM: kenji...@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:


Screen Shot 2015-08-31 at 11.32.59.png


Screen Shot 2015-08-31 at 11.33.14.png


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

  1. Extensions: how this should work from the viewpoint of extensions is still under discussion.

  2. Redirection: a bit thorny so it’s out-of-scope for now.

  3. 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).

  4. 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

  1. DevTools’ network tab shows the relevant headers.

  2. 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.

Ryan Sleevi

unread,
Aug 31, 2015, 9:11:07 PM8/31/15
to Kenji Baheux, blink-dev, Adam Rice


On Mon, Aug 31, 2015 at 5:40 PM, Kenji Baheux <kenji...@chromium.org> wrote:

bcc: net-dev


Caveats

  1. Extensions: how this should work from the viewpoint of extensions is still under discussion.

  2. Redirection: a bit thorny so it’s out-of-scope for now.

  3. 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).

  4. Authentication: no plan to support this (it doesn’t make any sense as we wouldn’t want to show an authentication UI asynchronously)


I remain fairly concerned with this feature and it's ability to be rationally explained as part of either the Blink loading stack, the Chrome network stack, or the overall Web platform. To be honest, this feels like one of those features that best works in niche environments, but either fails or complicates things spectacularly at Internet scale. HTTP Trailers and HTTP pipelining are two more examples in that space; both certainly have adoption and experience within controlled environments (typically, CDNs), but get all sorts of complicated elsewhere.

While I appreciate the design doc efforts to iterate, and the initial feedback, it feels like many of these issues - raised as core design issues from the net-stack - have been sort of punted as "Solve it in V2". While I can appreciate "Launch and Iterate" philosophy, at the same time, it's hard to change an engine in a jet once you're airborne, and I feel that's what is at risk.

What remains most deeply concerning, and which I haven't really seen any proposed solutions for, and which these problems are all symptoms of, is that we're talking about requests made to Web content without necessarily being contextually related to a renderer or to a user activity. We've seen this in the past with prerender (which some might call magic, others might rightfully call a hairy ball of hacks and bandaids upon hacks and bandaids), and we're seeing this with service worker and the challenges it presents.

On a more concrete level, I'd still like to suggest that it may be worthwhile to see if S-W-R can't be explored via a Service Worker with the Cache object first, and that the team might be able to work on some of the technical debt that's been accruing (and being punted on) for the past year that's been de-prioritized for S-W-R explorations.

David Benjamin

unread,
Sep 1, 2015, 11:52:00 AM9/1/15
to rsl...@chromium.org, Kenji Baheux, blink-dev, Adam Rice
On Mon, Aug 31, 2015 at 9:11 PM Ryan Sleevi <rsl...@chromium.org> wrote:


On Mon, Aug 31, 2015 at 5:40 PM, Kenji Baheux <kenji...@chromium.org> wrote:

bcc: net-dev


Caveats

  1. Extensions: how this should work from the viewpoint of extensions is still under discussion.

  2. 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.
 
  1. 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.

Dimitri Glazkov

unread,
Sep 1, 2015, 5:32:31 PM9/1/15
to rsl...@chromium.org, Kenji Baheux, blink-dev, Adam Rice
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?

:DG<

Ryan Sleevi

unread,
Sep 1, 2015, 7:00:53 PM9/1/15
to Dimitri Glazkov, Ryan Sleevi, Kenji Baheux, blink-dev, Adam Rice
On Tue, Sep 1, 2015 at 2:32 PM, Dimitri Glazkov <dgla...@chromium.org> wrote:

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?

I only brought it up to the extent the former influences the latter.

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. This is concerning, because unlike other work that's been postponed (in specs like CSS, in Service Workers, in Shadow DOM, etc), we don't even have a rough skeleton for how these things might work. We really just don't know and haven't come up with any ideas, other than just ignoring the bits. So we're painting ourselves into somewhat of a blind alley, with complexity along the way.

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.

In the context of an "Intent to Ship", these are all dimensions to be looked at. Are we moving the web forward if it's possible to polyfill? If we know the code has high complexity (demonstrated by the past year of effort), and also a non-trivial chunk of compatibility risk and sharp edges (from the original quoted caveats)? And what's the compatibility risk, given no signals from other UAs, and knowing that we've identified a number of areas where, even for Chrome, we don't really know how to solve or, for web developers and other possible implementers, to explain?

I think it's reasonable to ask "If we failed to solve any/every single caveat, would we still want to ship?" - how do the compatibility risks and benefits look then? How do we measure success - or whether it's time to unship? Is there benefit from such a minimal MVP?

From my perspective, this _seems_ like it falls in the bucket of "low compatibility risk [to existing/new content], high compatibility risk [to other potential implementers], isn't expected to significantly move the web forward [if the alternatives are, in fact, viable, and potentially more flexible], and high technical complexity". From the Blink balancing metric, it seems like the deciding factor here is really about the technical complexity (see the CSS Variables discussion), and my bringing up the topic of code health/priorities was mostly in the context that the evaluation of technical complexity here may be understated, because unlike some of the other caveats we've done with an Intent to Ship, we really haven't made a lot of progress on the S-W-R issues.

Kenji Baheux

unread,
Sep 1, 2015, 10:07:01 PM9/1/15
to David Benjamin, Ryan Sleevi, blink-dev, Adam Rice


Caveats

  1. Extensions: how this should work from the viewpoint of extensions is still under discussion.

  2. 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.
 
  1. 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?


Kenji Baheux

unread,
Sep 1, 2015, 10:33:42 PM9/1/15
to Ryan Sleevi, Dimitri Glazkov, blink-dev, Adam Rice


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.

Based on David's comment, I believe that we have a clear path for the remaining caveats.
But maybe I'm missing something.


 
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.

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.
  1. Extension are not relevant to the benefits we are hoping for.
  2. Lack of support for redirection has no material impact on the benefit we are hoping for.
  3. Requiring conditional revalidation should in fact increase the potential benefit
  4. Lack of support for authentication has no material impact on the benefit we are hoping for.


Ryan Sleevi

unread,
Sep 2, 2015, 12:49:56 AM9/2/15
to Kenji Baheux, Ryan Sleevi, Dimitri Glazkov, blink-dev, Adam Rice
On Tue, Sep 1, 2015 at 7:33 PM, Kenji Baheux <kenji...@chromium.org> wrote:
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.

That doesn't sound like a technical limitation, it sounds more political? And the politics are only easier because Chrome's the first client considering implementing S-W-R, thus doesn't have any interoperability concerns to worry about, right?
 
Finally, a SW approach for third parties would not work on first encounters

Isn't this true for S-W-R? So not really a limitation, per-se.
 
and has interesting performance concerns that we will need to think about.

Now we're getting to the good stuff - real concerns :)
 
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).
 
In such a world where foreign fetch exists, does S-W-R offer benefits? It seems like all of the functionality could be implemented there as well, and the only real difference that would remain is... performance and that Service Workers require HTTPS? Is there some other benefit here?

Put differently, S-W-R seems like a hyperspecialization of explaining either Service Workers or foreign fetch, but with a number of limitations and unsolved problems, and without being explaininable in terms of Fetch, where SW/FF offers a more robust solution, and where the benefits compared to SW are... performance?

Is there benefit from such a minimal MVP?

I believe so.
  1. Extension are not relevant to the benefits we are hoping for.
  2. Lack of support for redirection has no material impact on the benefit we are hoping for.
  3. Requiring conditional revalidation should in fact increase the potential benefit
  4. Lack of support for authentication has no material impact on the benefit we are hoping for.
This is precisely my concern. You're measuring benefit for, say, the 90% of use cases, while providing a piece of web platform technology that doesn't work like developers expect - either extension developers (case 1; creating new ways to hide requests from extensions) or site authors (case 2; making S-W-R already have special cases and implementation quirks). And for users, you're saying that sites working non-deterministically (case 4) is acceptable, because they're not your target user. And in the course of things, you're introducing a new requirement for site operators (conditional revalidation) - which, don't get me wrong, is a good thing, but also would seem to have the same concerns re: DevRel of being something not widely supported.

I suspect the wording was entirely unintentional, but I hope you can see how it would come to a conclusion that these use cases may end up never being addressed. That is, the focus is on the potential benefit, but without much concern for the potential complexity being introduced, or the inability to explain how the implementation behaves with respect to the rest of the Web primitives (such as the Fetch spec)

As to the answer it self, perhaps I could have put the question clearer: Are there benefits from such a minimal MVP, when alternatives like Service Worker exist? The main arguments seem to be that it's a simpler API for site operators to adopt (which I can understand, although disagree to the level of degree of ease), and that it's more performant than Service Workers (which I can buy as an argument, but is the performance worth the tradeoff?)

David Benjamin

unread,
Sep 2, 2015, 2:28:43 PM9/2/15
to Kenji Baheux, Ryan Sleevi, blink-dev, Adam Rice
(We can move technical discussions elsewhere if preferred. I'm not really clear on what's meant to be discussed in an Intent to Ship. It's worth mentioning that, although on blink-dev, I believe this feature would be primarily implemented in the net stack, which is why we net people are chiming in.)

On Tue, Sep 1, 2015 at 10:06 PM Kenji Baheux <kenji...@chromium.org> wrote:


Caveats

  1. Extensions: how this should work from the viewpoint of extensions is still under discussion.

  2. 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.

I would argue, particularly now that the extensions issue no longer constrains layering, that redirects being challenging is a symptom of the implementation being off. Rather than create a new URLRequest and duplicate all the processing between URLRequest and HttpCache (including calling out to code we don't control in extensions!) and having to support redirects funny, async revalidations could work as I wrote below (OnAsyncRevalidateNeeded on URLRequestDelegate). Redirects work transparently because it just gets called multiple times.

On a platform level, I don't think it's good for us to ship features that don't work in random edge cases. That's surprising for developers and, if we aren't careful to think though the complete behavior at the beginning, it's easy to get stuck in situations where it's impossible to rationalize all our features with respect to each other.

(To be clear, in this case I think the rationalization is quite within reach. We just have to implement it accordingly. With those issues properly handled, I actually think this is a fairly reasonable platform feature.)

W.r.t. extensions, we should be careful about shipping this without extensions plumbing in place (which shouldn't actually be too hard---just route up a new event to chrome.webRequest). Extensions can be used to enforce privacy/security properties ("this host shall not set cookies"), and so we must be mindful about breaking them. Now, it turns out the way this property is enforced is crazy and the one extension I've seen is suuuuper hacky. So we basically have to break it. But "you now also need to hook this additional event" is a very different thing from "we explicitly do not support your use case with this API and this extension can't be made to work at all in the next Chrome"[1].

[1] I actually would not be unhappy if we went with the latter, but that's somewhat more drastic. Anyway, that discussion is probably better had on the bug.
 
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.
 
  1. 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?

Perhaps I want to use stale-while-revalidate, my server setup doesn't make it easy to do ETags, but I read on the internet that <?php header('ETag: 12345'); ?> is how you make it work in Chrome. :-)

It's just more complexity on our end and in how the platform works in general. Certainly participating in ETags is a good thing, but it's a good thing independent of SWR. Likewise, SWR against a server that always fetches the resource anew is also a win over that server only sending max-age=N. That suggests the features shouldn't be coupled.

David

Chris Bentzel

unread,
Sep 2, 2015, 3:00:03 PM9/2/15
to David Benjamin, Kenji Baheux, Ryan Sleevi, blink-dev, Adam Rice
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.

Perhaps it makes sense to have API discussion on blink-dev and implementation discussion on net-dev?

Ryan Sleevi

unread,
Sep 2, 2015, 3:05:08 PM9/2/15
to Chris Bentzel, David Benjamin, Kenji Baheux, Ryan Sleevi, blink-dev, Adam Rice
On Wed, Sep 2, 2015 at 11:59 AM, Chris Bentzel <cben...@chromium.org> wrote:
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.

Well, the API contract itself is extremely light (the header), the question is, can multiple UA vendors deliver something interoperable, that works as developers and site operators expect? I think the current (and proposed) implementation both suggest a conclusion of "Unlikely", and that's understandably problematic.

And as far as the process goes, it seems the implementation strength/maturity is a core part of http://www.chromium.org/blink#new-features so it doesn't seem that we can easily detach these two concerns.

Kenji Baheux

unread,
Sep 2, 2015, 5:22:15 PM9/2/15
to rsl...@chromium.org, Chris Bentzel, Adam Rice, David Benjamin, blink-dev

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.

David Benjamin

unread,
Sep 2, 2015, 5:29:44 PM9/2/15
to Kenji Baheux, rsl...@chromium.org, Chris Bentzel, Adam Rice, blink-dev
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.

If we need to resolve that, I propose the following: if an async revalidation fails because it needs auth, we update the cache entry to require a synchronous revaildation on next fetch. This way we preserve the freshness behavior of stale-while-revalidate without having to ever show an out-of-context prompt since the revalidation may outlive the document.

(It is a little weird that freshness behavior is different depending on whether the request came in before or after the async revalidation completed or failed. But I think this doesn't make it any worse.)

Kenji Baheux

unread,
Sep 2, 2015, 5:59:34 PM9/2/15
to David Benjamin, rsl...@chromium.org, Chris Bentzel, Adam Rice, blink-dev


On Thu, Sep 3, 2015, 6:29 AM David Benjamin <davi...@chromium.org> wrote:
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.

Note that the worst that can happen is that we keep using the stale asset until it's older than max-age + stale-while-revalidate which is totally spec compliant (SHOULD):

Quote: "If a cached response is served stale due to the presence of this extension, the cache SHOULD attempt to revalidate it while still serving stale responses (i.e., without blocking)."

Chris Bentzel

unread,
Sep 2, 2015, 7:57:10 PM9/2/15
to Kenji Baheux, David Benjamin, rsl...@chromium.org, Adam Rice, blink-dev
Kenji mentioned running an experiment in the initial email. 

It seems like running one on Android (which avoids the WebRequest interaction issues) to better understand the potential benefit of this feature would be useful.

After getting results, we'll be in a better position to answer questions about cost/benefit tradeoff of supporting the feature longer term.

Malte Ubl

unread,
Sep 20, 2015, 11:26:11 AM9/20/15
to blink-dev, kenji...@chromium.org, davi...@chromium.org, rsl...@chromium.org, ri...@google.com
Hey, I just wanted to check in if progress is being made here?

I'm not sure categorizing this feature as having niche impact is correct. This new HTTP header is providing exactly the right semantics needed for bootstrap third party scripts. Under this umbrella fall all initial ad requests, social widgets such as the FB like button or twitter embeds where one wants to be able to ship new versions to users but it is completely fine if they are only available on the next page view.

From Google's point of view our core static resource serving infrastructure supports this and it could be quickly rolled out to a significant percentage of page views.

Chris Bentzel

unread,
Sep 20, 2015, 1:46:49 PM9/20/15
to Malte Ubl, blink-dev, kenji...@chromium.org, davi...@chromium.org, rsl...@chromium.org, ri...@google.com
The plan is to still run an experiment, measure, and then make an evaluation. This is a process we'd want to do for launching anyway.

timot...@gmail.com

unread,
Mar 7, 2017, 8:58:30 PM3/7/17
to blink-dev, ri...@google.com
Could someone add <https://bugzilla.mozilla.org/show_bug.cgi?id=995651> as the Firefox launch bug?

-- Timo

PhistucK

unread,
Mar 8, 2017, 1:55:23 AM3/8/17
to timot...@gmail.com, blink-dev, Adam Rice
Done.


PhistucK

--
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.

Kenji Baheux

unread,
Mar 10, 2017, 3:51:40 AM3/10/17
to blink-dev, timot...@gmail.com, ri...@google.com

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?


On our side, we've had a behind the flag implementation and did an experiment for a while but haven't been able to ship it due to some tough remaining issues... We believe that these issues are specific to Chrome's current architecture. In particular, problems with redirects and cookies have been noted as serious show-stopper because getting both of these to work correctly would require some major changes to the way the cache interfaces with the rest of Chrome's net layer.

Given upcoming major refactors (e.g. PlzNavigate, Servicification of //net) that would be impaired by the current implementation of S-W-R, we have decided to temporarily remove our implementation.

We still believe that this primitive has significant potential. So, we hope that Mozilla won't face the same hurdles and will be able to ship this primitive soon so that the community can help us better understand its impact and therefore facilitate a proper follow-up in Chrome.

Done.


PhistucK

To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.

Anne van Kesteren

unread,
Mar 10, 2017, 4:01:14 AM3/10/17
to Kenji Baheux, blink-dev, timot...@gmail.com, ri...@google.com
On Fri, Mar 10, 2017 at 9:51 AM, 'Kenji Baheux' via blink-dev
<blin...@chromium.org> wrote:
> We still believe that this primitive has significant potential. So, we hope that Mozilla won't face the same hurdles and will be able to ship this primitive soon so that the community can help us better understand its impact and therefore facilitate a proper follow-up in Chrome.

Since we're a couple years further, also seems good to figure out how
this affects Fetch (in particular the HTTP cache interaction rewrite
at https://github.com/whatwg/fetch/pull/496 and perhaps if we need API
changes to give control to JavaScript).


--
https://annevankesteren.nl/

Adam Rice

unread,
Mar 10, 2017, 4:48:53 AM3/10/17
to Kenji Baheux, blink-dev, timot...@gmail.com
Just adding a bit of technical detail on the issues:

The current Chrome implementation lives outside the network stack proper. When it sees a cached entry where stale-while-revalidate was applied, it clones the original URLRequest and sends it again asynchronously (with s-w-r disabled this time).

We'd really like to clone the HttpTransaction object which is used in the lower layer of the network stack. There's no guarantee that creating an identical URLRequest will result in an identical HttpTransaction. But for solid architectural reasons we can't do that. So this business of cloning the URLRequest is fragile. The most obvious case where it breaks down is when redirects happen. If the new network request redirects to a different place to the original cached request, we can't properly clone it, and we are stuck. So the current implementation disables itself if it sees a redirect as a workaround. The workaround has issues.

I think a better architecture is to clone the request inside the cache layer, and send it asynchronously to the network from there. I wrote a previous implementation that did this. This is where the cookie problem happens. In Chrome, cookies are persisted on the browser-side of the cache. If the async network request happens invisibly below the cache layer, there's no way for cookies it sets to end up persisted. Chrome doesn't store cookies in the cache, so if we didn't persist it immediately we'd never do so.

This is solvable, but cookies are subtle and dangerous. Any change to the way Chrome processes cookies has to be carefully designed and evaluated.

An interesting issue we never got as far as addressing was what the interaction between stale-while-revalidate and extensions should be.

timot...@gmail.com

unread,
Mar 22, 2017, 12:15:36 AM3/22/17
to blink-dev, timot...@gmail.com, ri...@google.com
Hi Kenji,

As part of my work with the Performance Team at Wikimedia, I am indeed considering use of stale-while-revalidate. Specifically, for responses from ResourceLoader. ResourceLoader is MediaWiki's delivery system for CSS and JavaScript modules. Part of its design are immutable module responses (as versioned urls), as well as a so-called "startup" module - which, unlike most modules, is the only module that has a short cache max-age.

Because it requires a short expiry, clients naturally need to make a roundtrip (usually met with a 304 Not Modified) on the first page view after every 5 minute mark, throughout a user session. This needless roundtrip impacts the time to mwLoadEnd (after primary JS modules have initialised).

Ideally, clients would only need to make this roundtrip when the cache is cold (e.g. first view). And after that, refresh is asynchronously, instead of blocking the JS pipeline on the page view. [1] There are, of course, many different ways one could solve this, but stale-while-revalidate seems like a natural fit!

We already use Varnish's obj.grace in our custom VCL code (which is similar to stale-while-revalidate) to reduce TTFB by letting our edge caches respond with a stale copy in most cases and perform revalidation to web servers in the background.


-- Timo

timot...@gmail.com

unread,
Mar 22, 2017, 12:20:05 AM3/22/17
to blink-dev, timot...@gmail.com, ri...@google.com


On Tuesday, 21 March 2017 21:15:36 UTC-7, timot...@gmail.com wrote:
[..]  refresh is asynchronously, instead of blocking the JS pipeline on the page view. [1] [..]

I meant to add:

[1] By "blocking" I mean conceptually (the time before JS-powered widgets are responsive). The JS pipeline is fully async as of https://phabricator.wikimedia.org/T107399, so this isn't "blocking" the critical path.
 
Reply all
Reply to author
Forward
0 new messages