一、前言
缓存思想是计算机领域最伟大的思想之一,缓存对web应用有多重要,大家可以百度一下雅虎前端性能优化军规,看看启用缓存的排序有多靠前。对服务端而言缓存也异常重要,memcache已经变成互联网产品的标配,缓存服务器一旦停止工作,大量获取数据的请求涌入数据库导致数据库运行缓慢,进而导致整个系统响应缓慢甚至崩溃,这就是“雪崩现象”。当然,今天我们要聊的主要是前端静态资源服务器应该采用的缓存策略。
二、常见的缓存策略
(1)Expires 设置失效时间,精确到时分秒
(2)Cache-Control: max-age,最大存活时间,单位为秒
(3)Last-Modified,文件修改时间
(4)E-Tag,针对文件内容生产的hash字符串用于唯一标识文件
三、根据用户请求资源的方式,浏览器与web服务器将启用不同的策略
- 正常请求。web前端根据版本号组装完整的URL,浏览器判断该URL是否有缓存,如果有缓存且缓存未失效,则直接返回缓存副本;缓存失效,则发送新的HTTP请求,服务器获取最新的文件,并设置缓存策略:Expires、Cache-Control: max-age、Last-Modified,最后以状态码200响应浏览器,浏览器缓存该文件后展现文件。具体流程如下:
- 用户刷新页面。如果用户刷新页面,则不管浏览器的缓存是否有效,总是会发送新的HTTP请求,服务器将根据请求头部If-Modified-Since决定是否获取最新的文件,如果If-Modified-Since的时间与文件的修改时间一致,则响应304,响应体为空,浏览器将采用缓存副本展现;如果If-Modified-Since的时间与文件的修改时间不一致,则服务器获取最新的文件,并设置该文件的缓存头部,响应200。具体流程如下:
通常有用户投诉某个功能无法使用时,我们提示用户请刷新一下页面,如果你的web服务器设置了Last-Modified 或者 E-Tag,仅刷新是没用的,必须清空浏览器缓存,如何清缓存,不同浏览器用不同的途径,对于前端工程师而言无需多讲。
四、同时设置Expires与 Cache-Control: max-age
为了解决服务端与客户端时钟不一致的问题我们需要设置Cache-Control: max-age 。需要注意的是HTTP1.0不支持Cache-Control: max-age,所以我们还需要设置Expires。对于同时支持Expires与 Cache-Control: max-age的浏览器,Cache-Control: max-age将覆盖Expires
五、慎用E-Tag
Etag的格式与web容器是耦合的,站点在服务器集群(多种web容器)下导致Etag值不一致,命中率很低。两种解决方案:
1、禁用Etag
2、自定义Etag
六、参考资料
《高性能JavaScript》
《高性能网站建设指南》
《HTTP权威指南》