为什么 Google App Engine 似乎没有在我的 CSS 样式表和 JavaScript 文件上设置适当的缓存友好 header (例如遥远的到期日期)? GAE 什么时候 gzip 这些文件?我的 app.yaml
将相应的目录标记为 static_dir
,因此缺少远期到期日期让我感到有些惊讶。
这是一个社区 wiki,用于展示有关 GAE 上的静态文件缓存和 gzip 压缩的最佳实践!
最佳答案
GAE 如何处理缓存?
GAE 似乎设置了近期的缓存过期时间,但确实使用了 etag
header 。这用于浏览器可以询问,“自从它具有 X68f0o
的 etag
以来,该文件是否发生了变化?”并听到“不——304 Not Modified
”作为回应。
与遥远 future 的到期日期相反,这有以下权衡:
- 您的最终用户将获得您资源的最新副本,即使他们具有相同的名称(与远期过期不同)。这很好。
- 但是,您的最终用户仍然需要提出检查该文件状态的请求。这确实会减慢您的网站速度,并且在内容未更改时是“纯粹的开销”。这不理想。
选择远期缓存过期而不是(仅)etag
要使用远期到期日期需要两个步骤和一点理解。
您必须手动更新您的应用程序以请求新版本的资源,例如通过将文件命名为
mysitestyles.2011-02-11T0411.css
而不是mysitestyles.css
。有一些工具可以帮助自动执行此操作,但我不知道有任何工具与 GAE 直接相关。使用
app.yaml
中的default_expiration
和/或expiration
配置 GAE 以设置您想要的到期时间。 GAE docs on static files
第三种选择:应用程序 list
缓存 list 是一种覆盖缓存 header 的 HTML5 功能。 MDN article , DiveIntoHTML5 , W3C .然而,这不仅仅影响脚本和样式文件的缓存。小心使用!
GAE gzip
什么时候运行?
根据 Google’s FAQ ,
Google App Engine does its best to serve gzipped content to browsers that support it. Taking advantage of this scheme is automatic and requires no modifications to applications.
We use a combination of request headers (Accept-Encoding, User-Agent) and response headers (Content-Type) to determine whether or not the end-user can take advantage of gzipped content. This approach avoids some well-known bugs with gzipped content in popular browsers. To force gzipped content to be served, clients may supply 'gzip' as the value of both the Accept-Encoding and User-Agent request headers. Content will never be gzipped if no Accept-Encoding header is present.
This is covered further in the runtime environment documentation (Java | Python).
一些现实世界的观察确实表明这通常是正确的。假设一个支持 gzip 的浏览器:
- GAE gzip 实际页面(如果它们有适当的
content-type
header ,如text/html; charset=utf-8
) - GAE gzip 脚本和样式在
static_dir
中(在app.yaml
中定义)。 - 请注意,您不应期望 GAE 对 GIF 或 JPEG 等图像进行 gzip 压缩,因为它们已经被压缩。
关于google-app-engine - GAY 上的缓存和 GZip(社区维基),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4974924/