0

这是我的.htaccess文件的片段:

# ------------------------------------------------------------------------------
# | ETag removal                                                               |
# ------------------------------------------------------------------------------

# Since we're sending far-future expires headers (see below), ETags can
# be removed: http://developer.yahoo.com/performance/rules.html#etags.

# `FileETag None` is not enough for every server.
<IfModule mod_headers.c>
    Header unset ETag

  <filesMatch "\.(ico|jpe?g|png|gif|swf)$">
    Header set Cache-Control "max-age=2592000, public"
  </filesMatch>
  <filesMatch "\.(css)$">
    Header set Cache-Control "max-age=604800, public"
  </filesMatch>
  <filesMatch "\.(js)$">
    Header set Cache-Control "max-age=216000, public"
  </filesMatch>
  <filesMatch "\.(x?html?|php)$">
    Header set Cache-Control "max-age=600, private, must-revalidate"
  </filesMatch>
</IfModule>

FileETag None

# ------------------------------------------------------------------------------
# | Expires headers (for better cache control)                                 |
# ------------------------------------------------------------------------------

# The following expires headers are set pretty far in the future. If you don't
# control versioning with filename-based cache busting, consider lowering the
# cache time for resources like CSS and JS to something like 1 week.

<IfModule mod_expires.c>

    ExpiresActive on
    ExpiresDefault                                      "access plus 1 month"

  # CSS
    ExpiresByType text/css                              "access plus 1 year"

  # Data interchange
    ExpiresByType application/json                      "access plus 0 seconds"
    ExpiresByType application/xml                       "access plus 0 seconds"
    ExpiresByType text/xml                              "access plus 0 seconds"

  # Favicon (cannot be renamed!)
    ExpiresByType image/x-icon                          "access plus 1 week"

  # HTML components (HTCs)
    ExpiresByType text/x-component                      "access plus 1 month"

  # HTML
    ExpiresByType text/html                             "access plus 0 seconds"

  # JavaScript
    ExpiresByType text/javascript                       "access plus 1 year"
    ExpiresByType application/javascript                "access plus 1 year"
    ExpiresByType application/x-javascript              "access plus 1 year"

  # Manifest files
    ExpiresByType application/x-web-app-manifest+json   "access plus 0 seconds"
    ExpiresByType text/cache-manifest                   "access plus 0 seconds"

  # Media
    ExpiresByType audio/ogg                             "access plus 1 month"
    ExpiresByType image/gif                             "access plus 1 month"
    ExpiresByType image/jpeg                            "access plus 1 month"
    ExpiresByType image/jpg                            "access plus 1 month"
    ExpiresByType image/png                             "access plus 1 month"
    ExpiresByType video/mp4                             "access plus 1 month"
    ExpiresByType video/ogg                             "access plus 1 month"
    ExpiresByType video/webm                            "access plus 1 month"

  # Web feeds
    ExpiresByType application/atom+xml                  "access plus 1 hour"
    ExpiresByType application/rss+xml                   "access plus 1 hour"

  # Web fonts
    ExpiresByType application/font-woff                 "access plus 1 month"
    ExpiresByType application/vnd.ms-fontobject         "access plus 1 month"
    ExpiresByType application/x-font-ttf                "access plus 1 month"
    ExpiresByType font/opentype                         "access plus 1 month"
    ExpiresByType image/svg+xml                         "access plus 1 month"

</IfModule>

可以看出,我在适当的语法中有 Cache-Control 和 Expires。然而 Google PageSpeed 工具却说我的 JS 没有利用浏览器缓存。有什么我想补充的吗?

我知道同时包含 Cache-Control 和 Expires 标头不是一个好习惯。所以我删除了 Cache-Control 部分。本地文件(目前不关心第三方外部文件)在通过 Google 运行时仍显示为未缓存。需要缓存的文件是http://www.peppyburro.com/sandboxassets/js/burroinline.js。有问题的.htaccess位于文档根目录,即http://www.peppyburro.com/.htaccess。具有上述缓存片段的.htaccess也位于包含burroinline.js的/js文件夹中。

更令人困惑的是,https ://www.giftofspeed.com/cache-checker/ 说我的文件按预期缓存,而 Google PageSpeed 和 GTMetrix 说它不是。

更新:看起来我的 CDN (CloudFlare) 与缓存问题有关,因为一旦我禁用 CF,缓存就开始工作了。我这么说是因为 Google PageSpeed 在缓存和未缓存之间随机交替,尽管我的 htaccess 没有任何变化!此外,GTMetrix 仍将文件显示为未缓存。这是我的浏览器上的标题:

**General**
Request URL:http://peppyburro.com/sandboxassets/js/burroinline.js
Request Method:GET
Status Code:200 OK (from disk cache)
Remote Address:209.99.16.94:80
**Response Headers**
Accept-Ranges:bytes
Access-Control-Allow-Origin:*
Age:0
Cache-Control:max-age=216000, public
Content-Encoding:gzip
Content-Length:38611
Content-Type:application/javascript
Date:Wed, 01 Mar 2017 16:22:41 GMT
Expires:Thu, 01 Mar 2018 16:22:41 GMT
Last-Modified:Wed, 01 Mar 2017 02:18:53 GMT
Server:Apache Phusion_Passenger/4.0.10 mod_bwlimited/1.4 mod_fcgid/2.3.9
Vary:Accept-Encoding,User-Agent
Via:1.1 varnish-v4
X-Varnish:31524632

这是否意味着文件实际上正在被缓存?如果是这样,如何才能在 Google PageSpeed 和 GTMetrix 中得到一致的反映?我怎样才能使它在启用 CF 的情况下工作?

PS:在共享主机上,我无权访问httpd.conf

4

1 回答 1

1

编辑:答案最终是 CloudFlare 和 .htaccess 文件之间的冲突。这篇文章的评论讨论了这个问题的故障排除和解决方案。

我通过 pingdom 的工具运行此资源以查看请求/响应的样子。

https://tools.pingdom.com/#!/d8QPQx/http://www.peppyburro.com/sandboxassets/js/burroinline.js

它实际上没有被缓存。标头设置为无缓存。

"no-cache" 表示返回的响应不能用于满足对同一 URL 的后续请求,除非先与服务器检查响应是否已更改。因此,如果存在正确的验证令牌 (ETag),则 no-cache 会产生往返以验证缓存的响应,但如果资源未更改,则可以消除下载。

来源:https ://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching

服务器的响应是:

Cache-Control public, max-age=216000

因为它是 javascript,所以建议将其延长到一周或更长时间。此外,这里的响应是公开的,而您的设置是

Header set Cache-Control "max-age=216000, private"

年龄是正确的,但能见度是悬殊的。

“公共”与“私人”

如果响应被标记为“公共”,那么它可以被缓存,即使它具有与之关联的 HTTP 身份验证,即使响应状态代码通常不可缓存。大多数时候,“public”不是必需的,因为显式缓存信息(如“max-age”)表明响应无论如何都是可缓存的。

相比之下,浏览器可以缓存“私人”响应。但是,这些响应通常是针对单个用户的,因此不允许中间缓存来缓存它们。例如,用户的浏览器可以缓存包含私人用户信息的 HTML 页面,但 CDN 无法缓存该页面。

来源:https ://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching

我也看到了一些 cloudflare (CDN) 标头,表明它没有被缓存。通常,私人响应适用于敏感内容。我会首先尝试将其设置为公开,但前提是您不关心敏感信息。

如果您关心敏感信息,请将此设为私有

虽然我认为这可能是问题所在,但还有其他几个因素(以 CDN 为中心)也可能导致该问题。

Accept-Ranges:bytes
Access-Control-Allow-Origin:*
Age:0
Cache-Control:public, max-age=216000
CF-Cache-Status:MISS
CF-RAY:338d062cb1035a6e-BOS
Connection:Keep-Alive
Content-Type:application/javascript
Date:Wed, 01 Mar 2017 15:07:08 GMT
Expires:Sat, 04 Mar 2017 03:07:08 GMT
Last-Modified:Wed, 01 Mar 2017 02:18:53 GMT
Proxy-Connection:Keep-Alive
Server:cloudflare-nginx
Vary:Accept-Encoding
Via:1.1 varnish-v4
X-Varnish:18615326

这些是来自服务器的响应标头。它们在 CF(cloudflare)缓存中包含一个“MISS”。此外,这里的缓存控制也设置为公共。

因此,我认为中间 CDN 可能会导致缓存问题。

如果您有任何其他信息要提供(例如 CDN/CloudFlare 信息),我很乐意再看一看。

于 2017-03-01T15:09:58.483 回答