mathdown icon indicating copy to clipboard operation
mathdown copied to clipboard

Caching headers

Open cben opened this issue 10 years ago • 4 comments

GH Pages sends Cache-Control:max-age=600 header (and corresponding Expires in 10minutes). http://www.webpagetest.org/performance_optimization.php?test=150216_4T_H0J&run=1&cached=0 Also it was served via Fastly CDN.

Heroku and RHcloud [http://www.webpagetest.org/result/150216_TV_HNP/, http://www.webpagetest.org/result/150216_CH_HP2/] also set 10 minutes.

So at least I'm not worse off...

Background reading: http://tomayko.com/writings/things-caches-do I see 3 approaches:

  • Longer fixed max-age. Not good when rolling out new version; in fact 10min can also cause breakage.
  • ETag with hash of content. Still requires request but probably cheap with HTTP pipelining?
  • Change URL when content changes (e.g. include git commit), so max-age can be set to infinity. This is hard to do with dev/prod parity — if index.html from checkout works, then dynamic server must rewrite links? Also, unless every single file changes (which requires more extensive rewriting) this may end up caching less than stable URL + ETag.

Oh, should also read up cache manifests (or is that only for browser extensions?).

cben avatar Feb 16 '15 20:02 cben

http://security.stackexchange.com/a/7008/31246 - set Cache-control: public to allow caching on HTTPS

cben avatar Feb 17 '15 18:02 cben

Turns out there is some caching:

Load Time First Byte Start Render Speed Index DOM Elements Time Requests Bytes In Time Requests Bytes In
Document Complete Fully Loaded
First View 7.617s 0.373s 4.100s 7258 75 7.617s 37 426 KB 12.441s 52 466 KB
Repeat View 0.995s 1.993s 0.995s 2273 74 0.995s 0 0 KB 4.377s 8 29 KB

[http://www.webpagetest.org/result/150220_21_CGX/]

There are basically 2 kinds of caching:

  • Expiration (max-age and/or expires) — the period when no request is needed at all — is not effective at 10min.
  • Then the browser falls back to validation (etag — sending a request but hopefully getting a short "304 Not Modified" response. This works.

Relevant headers in our response from RHcloud-hosted mathdown.net (on codemirror.js):

cache-control:public, max-age=600
etag:"64770-742663784-1418313063000"
last-modified:Thu, 11 Dec 2014 15:51:03 GMT

The last-modified time here is matches the file date (verified via ssh into rhcloud & heroku run):

  • On RHcloud it's Dec 11, matching the CodeMirror git commit that last affected codemirror.js.
  • On heroku it's FEb 20, mathcing time of last deploy.
  • On my local filesystem (with default git settings), it's whenever I did git pull etc...

The etag is generated based on the dev, ino, and last modified date. Stat results are cached. [https://www.npmjs.com/package/st]

cben avatar Mar 02 '15 16:03 cben

I actually want to get rid of max-age — for 10min after each deploy it may cause unpredictable bugs due to mixed versions. The sane way to use max-age is to make it infinite and change URLs every time content changes. This is the most optimal approach but I don't see an easy way to make same it work with static files without rewriting relative paths in HTML and CSS. There is one non-intrusive way of putting the whole static hierarchy under a subdir (named e.g. static-G1THA5H/). Perhaps aided by `1

cben avatar Mar 02 '15 17:03 cben

During developement, changing a file still serves the old file for a short time (minute?), even with Shift+refresh.

cben avatar Aug 07 '15 08:08 cben

As part of #172 I moved to Netlify, which does something sensible as a CDN, and I no longer care what exactly :eyeglasses:

cben avatar Dec 17 '22 18:12 cben