Preemptive Cache Validation: Pushing 304s |
May 19th, 2015 |
tech |
This means there are very many times when a resource is sitting stale
in the browser cache while the server knows it's still valid. In this
case the browser has to check with the server and wait for a 304
Not Modified
before it can use the resource. If the server could
preemptively notify the client in cases where a cached result was
still valid, this would cut out lots of blocking round trips and speed
up pages a lot.
When I posted about this on public-webappsec
one of the responses was that with SPDY or HTTP/2 it's possible to do
this for your own resources by pushing down a preemptive 304 Not
Modified
response for the resource. You just set the
ETag
on the response to the current ETag
, and then
if the cached-but-stale resource has a matching ETag
the
browser should be able to use it.
When I tested this, however, both Chrome and Firefox don't seem to
implement it this way. I wrote a little web app based on node-spdy
[2]
that tests the three combinations:
- Push nothing: browser requests resource normally.
- Push everything: browser receives full response as push.
- Push 304: on first view browser receives useless 304 as push, requests resource normally. On later views browser uses pushed 304 to avoid re-requesting the resource that's already in cache.
jefftk.com:3232
.
Unfortunately it doesn't work:
That should be including a line for "ran 304-pushed external js" and saying something interesting in the console, but it seems to have stopped with the 304. I see the same thing running on WebPageTest.
I still need to figure out if this is something that is supposed to be supported, but at least for now it's not working in Chrome or Firefox.
[1] Though this is one of the optimizations PageSpeed
makes, and on nearly all sites it works well. It's just that very
occasionally this will confuse existing JavaScript on the page, and
including hashes in urls is also a very user-visible change.
[2] I tried to use node-http2
first, but I couldn't get Chrome or Firefox to talk to it over HTTP/2.
Instead they both fell back to HTTPS, which means no server push. I
think the problem may be that node-http2
implements an older
draft version of HTTP/2 that the browsers have dropped support for?
Comment via: google plus, facebook