每次访问网页,通常浏览器会从服务器下载所 需的资源,例如 HTML 文档、图片、CSS、JavaScript,甚至包括字体文件等。这里面的许多文件(例如图片)都是很少变动的,如果每次都要从服务器重新下载,会不必要 地增加网页载入时间,同时也会对服务器造成一定压力。通过合理配置缓存策略,可令浏览器以某种方式把这些静态的文件缓存起来,下次请求同一资源时,直接使 用本地存储的副本,而不是从服务器重新下载。
启用缓存至少有两点显而易见的好处:
- 减少页面加载时间
- 减少服务器负载
浏览器是否使用缓存、缓存多久,是由服务器控制的。准确来说,当浏览器请求一个网页(或者其他资源)时,服务器发回的响应的「响应头」部分的某些字段指明了有关缓存的关键信息。
Cache-Control
Cache-Control
HTTP 响应头是 HTTP 1.1 协议新增的指令,每个资源都可以通过设定 Cache-Control 来建立缓存策略。通常,可为它指定一个max-age
,表示缓存的最长时间,单位为秒。例如,若设定Cache-Control: max-age=604800
,则表示这个资源的有效时间为 7 天。浏览器第一次获取这个资源后,7 天之内若再次请求,通常都不会与服务器进行任何通信,而是直接使用本地副本。
此外,还可以为 Cache-Control 指定public
或private
标 记。如果使用 private,则表示该资源仅仅属于发出请求的最终用户,这将禁止中间服务器(如代理服务器)缓存此类资源。对于包含用户个人信息的文件(如一个包含用 户名的 HTML 文档),可以设置 private,一方面由于这些缓存对其他用户来说没有任何意义,另一方面用户可能不希望相关文件储存在不受信任的服务器上。需要指出的 是,private 并不会使得缓存更加安全,它同样会传给中间服务器(如果网站对于传输的安全性要求很高,应该使用传输层安全措施)。对于 public,则允许所有服务器缓存该资源。通常情况下,对于所有人都可以访问的资源(例如网站的 logo、图片、脚本等),Cache-Control 设为 public 是合理的。
Expires
同样是用来控制缓存,Expires
响 应头从另一个角度——指明缓存的具体过期日期,来控制资源何时过期。在过期时间以内,若再次发起请求,通常浏览器都不会与服务器进行任何通信,而是直接使 用本地副本。Apache 服务器允许以多种方式,例如基于该资源的访问时间或上次修改时间来设定 Expires 的值。注意,这里的时间一律使用格林威治时间(Greenwich Mean Time, GMT),而非本地时间。
当 Expires 和 Cache-Control 同时出现时,通常后者会覆盖前者的设定。由于 Expires 对用户的系统时间有所依赖,因此通常认为使用 Cache-Control 是更好的选择(基本上所有的浏览器都支持 Cache-Control 指令)。
Last-Modified 和 ETag
服务器可在 HTTP 返回头中包含Last-Modified
字段或者ETag
字段。Last-Modified 表示被请求资源在服务器端的上次修改时间,而 ETag 则是一个唯一文件标识符,每次文件修改后都会生成一个新的 ETag。服务器通过向浏览器发送这两个字段,来告知浏览器其获得的资源的版本。
无论通过 Cache-Control 还是 Expires 设置缓存,在过期时间以内,当用户点击浏览器刷新按钮时,为了确保用户所加载的资源是最新的,大部分浏览器不会再直接使用缓存中的数据,而是发出一个条件请求(Conditional GET Request)。对于这类请求,浏览器会在请求头中包含If-Modified-Since
或If-None-Match
字 段。前者即浏览器当初得到的 Last-Modified;后者即浏览器当初得到的 ETag。当服务器发现资源的更新时间晚于 If-Modified-Since 所提供的时间,或者资源在服务器端当前的 ETag 和 If-None-Match 提供的不符时,会响应整个资源,否则只会响应一个 304 Not Modified 状态码(因此浏览器将不需要重新下载整个资源)。这种机制可以最大程度上减少数据下载量。此外,如果缓存的资源已过期,浏览器通常有两种选择:重新下载这 个资源,或发出一个条件请求。很多浏览器都会采取后者,以节约资源。
由于 Last-Modified 和 ETag 的作用是相同的(均为向服务器验证资源是否最新),因此只使用一个即可。通常认为 Last-Modified 更好(它和 Expires 不同,由服务器生成,不依赖浏览器端时间)。
我的网站启用缓存了吗?
用浏览器的开发者工具或插件查看
为了确定是否启用了缓存,只需要检查服务器发回的「响应头」就可以。许多浏览器以及工具都可以检查这些信息,我们以 Firefox 的插件 Firebug 为例。如图所示:
下面再来看一个没有启用缓存的资源的例子:
没有包含Cache-Control
以及Expires
信息。
在线检测
也有一些方便的在线检测服务,用于对网站速度给出建议,其中就会检测缓存设置情况。比如 Yahoo! 公司的 YSlow,以及百度站长工具等,都有相应的功能。大家可以去百度那里检测一下,目前是不需要登录即可检测的。
使用缓存的策略
为静态资源设置长缓存时间
有些资源是很长时间不会改变的,比如网站的 logo 图片、jQuery 库、字体等,因此可以为它们设定「永不过期」的缓存时间,例如设定为 10 年。
确保文件修改生效
有 些时候我们会修改一些资源,比如更新了 jQuery 版本,或网站的 CSS 样式。如果这些资源已经被缓存,那么除非用户手工刷新页面,否则要等缓存自然过期之后用户才会获得新版本。如何在这种情况下强制浏览器重新下载呢?最有效 的一个办法就是在这类资源的文件名中包含版本信息,并在更改之后对应地修改文件名。浏览器发现文件更换后,自然无法使用缓存,而会重新下载。
对于 HTML 文档谨慎设定过期时间
大 部分情况下,对于其他图片、CSS、JavaScript 等资源的请求都来自一个单一的 HTML 文档。对于这类页面通常应该设定比较短的过期时间,或者干脆不设定。因为如果这类页面被缓存,那么页面中包含的资源的文件名等等信息都会一并被缓存,导致 对它的更新难以确保立即对用户生效。
引用静态资源时,不要使用 Query String
Query String 就是例如?key=val
的字符串,如
<script src="/static/js/func.js?v=a87ff8"></script>
这会阻止一部分较老的浏览器(包括 IE6 )对该资源进行缓存。
设定缓存的方法
对于 Apache 服务器,可以通过 mod_expires 模块来设定Expires
HTTP 头或Cache-Control
HTTP 头的max-age
指令。编辑相应目录下的 .htaccess
文件,或直接对 Apache 的配置文件(根据服务器系统版本不同,可能为httpd.conf
或apache2.conf
等)作出修改。
分文件类别设定
使用ExpiresByType
可以按照文件的 MIME Type 设定某一类文件的过期日期。例如:
<IfModule mod_expires.c> ExpiresActive On ExpiresByType text/css "access plus 1 week" ExpiresByType application/javascript "access plus 2 weeks" ExpiresByType image/x-icon "access plus 6 months" ExpiresByType image/gif "access plus 6 months" ExpiresByType image/png "access plus 6 months" ExpiresByType image/jpeg "access plus 6 months" ExpiresByType video/x-flv "access plus 6 months" ExpiresByType application/pdf "access plus 6 months" </IfModule>
其中access plus 1 week
表示将缓存过期设置为访问时间(即当前时间)之后的一周。如果将access
替换为modification
,则缓存过期会被设定为文件修改时间之后的一周。可以使用的时间单位包括:
- years
- months
- weeks
- days
- hours
- minutes
- seconds
不同的时间也可以进行组合,例如:
ExpiresByType text/html "access plus 1 month 15 days 2 hours" ExpiresByType image/gif "modification plus 5 hours 3 minutes"
根据文件扩展名进行设置
如果希望根据扩展名来指定缓存规则,可以使用FilesMatch
配合正则表达式。为了简洁,我这里只规定了ExpiresDefault
。它的优先级很低,只会在对应文件没有任何其他规则能够匹配(包括上层目录下的缓存规则)时生效。
<IfModule mod_expires.c> <FilesMatch "\.(css|js)$"> ExpiresActive on ExpiresDefault "access plus 1 week" </FilesMatch> </IfModule>
对某些文件设定
同理,也可以对某些文件启用特定的缓存策略。注意,文件名中的点(.
)是需要转义的。
<IfModule mod_expires.c> <FilesMatch "^(example\.css|example\.js)$"> ExpiresActive on ExpiresDefault "access plus 1 week" </FilesMatch> </IfModule>
对某一文件夹下的所有文件设定
对于静态文件,一个比较方便的做法是将它们全部放到一个目录下,并对该目录下的所有文件设定。但是,此处需要注意防止其他规则将ExpiresDefault
覆盖掉。
<IfModule mod_expires.c> ExpiresActive On ExpiresDefault "access plus 10 years" </IfModule>
有用的工具及参考资料
- Cache-Control header checker(可检测给定的地址是否启用了 Cache-Control,还会教你如何设定)
- Caching Tutorial for Web Authors and Webmasters
- HTTP 缓存 - Web Fundamentals(来自 Google Developers)
- 百度站长工具-页面优化建议
- h5bp/server-configs(HTML5 Boilerplate 提供了所有最流行的服务器的配置文件样例)
相关推荐
为 Web 访问配置策略和过滤器 72 过滤 Access Gateway 连接的必要条件 73 基于 Access Gateway 连接应用策略过滤器 73 基于现有 Access Gateway 策略应用策略过滤器 73 将策略应用于除基于 Access Gateway 的连接...
集中式管理的简介 配置单向和双向委托 理解委托域和受托域之间的差别 使用内建组管理委托 理解传递身份审核 跨越委托向用户授权访问资源 管理被破坏的委托关系理解委托的不可传递性问题 服务器分析及优化简介 ...
5.8.5 hibernate的二级缓存配置 334 5.9 hibernate应用的性能优化 336 5.10 多数据源的应用 338 5.11 jdbc的应用 343 5.12 hibernate调用存储过程 343 5.13 xml数据持久化 346 5.14 小结 348 第6章 充分利用...
搜索引擎优化器 ...多种缓存策略 支持异步页面 普罗米修斯指标 选择您的配置系统(YAML,TOML或JSON) 容器准备好 什么是搜索引擎优化程序? Search Engine Optimizer可以看作是位于您的后端服务器
特别在无线、认证、策略路由、带宽控制和防火墙过滤等功能上有着非常突出的功能,其极高的性价比,受到许多网络人士的青睐。 桥接功能 RouterOS能将多张网卡组建为一个桥模式,使路由器变成一个透明的桥设备,同样...
learningnotes ... 性能优化(包含浏览器缓存策略) Jenkins 配置及部署 Mongo 在 Docker 下安装过程 微信授权本地项目如何调试 Git Promise async await 聊聊 XSS CSRF 那些事 webScoket 那些事
FireFox推介一种新的网站加速策略: 链接预加载。什么是链接预加载?MDN描述如下: 预加载是一种浏览器机制,使用浏览器空闲时间来预先下载/加载用户接下来很可能会浏览的页面/资源。页面提供给浏览器需要预加载的...
2、经过以上三步,我们其实可以很好的清除那些临时文件了,不过不能就此满足哦,我们的目标是让Windows自动清空,解放我们的双手:打开组策略(运行gpedit.msc),依次打开“计算机配置-Windows 设置-脚本(启动/...
友点企业网站管理系统集电脑站、手机站、...12.[增加]模板配置变量,频道列表增加了【不显示当前版块】,以便控制前台版块隐藏和显示 13.[增加]在后台可以设置搜索页面分页条数 14.[优化]简化上传步骤,点击【上传】
(对于NOKIA手机及其它部分手机,由于安全策略的限制,在Anyview的文件管理器中无法查看后缀为.jar的文件) 自定义问候语(系统路径下dictum.rc文件,格式参见jar包中的dictum.rc文件,保存时使用UTF-8编码,可写条目为...
采用Zend Optimizer做最佳化处理,数据库优化、页面缓存,性能优越,为服务器减压提高性能,支持大流量网站; 高安全: 系统采用PHP脚本语言与MySQL数据库制作而成,底层程序采用Zend进行加密。 系统要求 ...
14.3.1 配置的和非配置的组件 447 14.3.2 COM+类别 447 14.4 创建一个ASP COM组件 447 14.4.1 组件的接口 449 14.4.2 创建组件 449 14.5 小结 457 第15章 COM+应用程序 458 15.1 微软组件服务(COM+) 458 ...
14.3.1 配置的和非配置的组件 447 14.3.2 COM+类别 447 14.4 创建一个ASP COM组件 447 14.4.1 组件的接口 449 14.4.2 创建组件 449 14.5 小结 457 第15章 COM+应用程序 458 15.1 微软组件服务(COM+) 458 ...