网络中数据传输是很耗时的,数据要在漫长的路径中奔波,客户端在数据完整到达前只能等待。如果能够复用已经请求过的资源,势必会让整个页面加载高效许多。这可以通过合理地设置服务器的缓存,与浏览器的缓存机制配合以达到最优。

缓存设置得当不但可减少用户等待时间,提升体验,还节省服务器开销省流量带宽。

缓存的配置有两种策略:

  • 稳定的内容 + 长期缓存
  • 经常变动的内容 + 使用前询问

稳定的内容 + 长期缓存

在知道文件内容不太可能变化的情况下,可对该资源进行长期缓存。

Cache-Control: max-age=31536000

这种模式下浏览器获取资源流程如下:

  1. 页面:请求资源 a.v1.js,b.v1.css
  2. 缓存:本地没有,向服务器获取。
  3. 服务器:找到资源并返回,同时告知浏览器缓存该资源,比如,缓存一年。
  4. 页面:一段时间后再次请求 a.v2.js,b.v1.css
  5. 缓存:发现本地有对 b.v1.css 的缓存,直接使用,对于 a.v2.js 则询问服务器。
  6. 服务器:找到资源并返回 a.v2.js,同时告知浏览器缓存该资源。

可以看到,这种模式下,我们更新的是文件名,即资源的 URI 地址,而不是直接更新文件内容。因为文件被缓存后,如果文件名没变,浏览器是不会重新去获取的。

经常变动的内容 + 使用前询问

对于经常变动的资源,但地址又不能变,比如静态博客页面,则不能像上面那样缓存。这种情况下可设置缓存为 no-cache

Cache-Control: no-cache

需要注意的是,缓存 Header 的值不能按照字面意思来解释,需要去理解它,比如:

  • no-cache 并不是表示不要缓存,而是缓存该资源,但使用前先询问服务器该资源是否有更新,而 no-store 才表示完全不缓存。
  • must-revalidate 不是必需重新验证资源有效性的意思,而是暗含了一个前提,就是资源如果还没有超过设置的缓存时限 max-age 才重新验证。

此模式下,服务器可通过下发 ETagLast-Modified 响应头,浏览器下次再请求时会查检查已缓存的资源,并带上相应的 If-None-MatchIf-Modified-Since 请求头,然后服务器再决定是否返回新的资源或告知浏览器直接使用本地缓存。

使用 ETag 的场景示例:

  1. 浏览器请求资源。
  2. 服务器返回资源,并且带上 ETag (可以是 hash 或者其他能够跟随资源内容而变的 id)。
  3. 过段时间,浏览器再次请求该资源,通过设置 If-None-Match 请求头带上前面得到的 ETag。
  4. 服务器将 ETag 与资源内容进行比较,发现资源没有更新过,返回 304 (not modified)告诉浏览器资源没有变化,可使用本地已经缓存的版本。
  5. 浏览器得到 304 响应,直接使用本地缓存。

整个过程没有对资源进行重复下载。

ETag/Last-Modified 不可用的情况下,服务器始终下发完整资源。

相比方式一,这种方式始终会和服务器进行一次沟通。

max-age 的注意事项

对易变的内容设置 max-age 方式的缓存容易引起各资源不一致的问题。


比如设置缓存为如下格式时,

Cache-Control: must-revalidate, max-age=600

对于缓存时间小于 10 分钟的资源,浏览器不会重新请求而是直接使用缓存。

假设一个场景,页面 A 包含一个公共脚本 common.js 和页面 A 的业务脚本 a.js。当页面 A 首页加载时,所有资源都正确缓存。

过了一段时间,切换到页面 B,页面 B 也包含公共脚本 common.js,同时有自己的业务脚本 b.js

在请求页面 B 之前,因为已经缓存过 common.js,所以会使用缓存,但这期间文件有可能已经更新。此时浏览器使用旧的 common.js 运行页面 B 势必会出问题。

所以,对于经常变动的内容设置 max-age 是不推荐的做法。

多数情况下针对上面的问题,一次强刷就解决了,这也是有 bug 时研发会给出的高频回复。

参考内容

HTTP 缓存相关的更多相关文章

  1. 浏览器缓存相关http头

    近期看雅虎黄金34条,学习下优化站点性能的方法. 当中有一条:"为文件头指定Expires或Cache-Control",详细来说指对于静态内容:设置文件头过期时间Expires的 ...

  2. 《前端之路》之 Cookie && localStorage && Session Storage 缓存相关

    08: Cookie && localStorage && Session Storage 缓存相关 客户端.前端 存储 一. 起 因 首先解释下为什么想来写这个关于前 ...

  3. Java缓存相关memcached、redis、guava、Spring Cache的使用

    随笔分类 - Java缓存相关 主要记录memcached.redis.guava.Spring Cache的使用 第十二章 redis-cluster搭建(redis-3.2.5) 摘要: redi ...

  4. Django的contenttypes应用、缓存相关

    一.django的contenttypes contenttypes 是Django内置的一个应用 , 可以追踪项目中所有app 和 model 的对应关系, 并记录djang_content_typ ...

  5. http中有关缓存相关的几个字段

    转载自:http://blog.csdn.net/lifeibo/article/details/5979572 Expires.Cache-Control.Last-Modified. ETag是R ...

  6. MySQL的Innodb缓存相关优化

    MySQL的Innodb缓存相关优化 INNODB 状态的部分解释 通过 命令 SHOW STATUS LIKE  'Innodb_buffer_pool_%' 查看  Innodb缓存使用率  (I ...

  7. contenttype应用 , 缓存相关

    一. Django的contenttypes contenttypes 是Django内置的一个应用,可以追踪项目中所有 app和model 的对应关系,并记录在 django_content_typ ...

  8. 网页缓存相关的HTTP头部信息详解

    前言 之前看完了李智慧老师著的<大型网站技术架构-核心原理与案例分析>这本书,书中多次提起浏览器缓存的话题,恰是这几天生产又遇到了一个与缓存的问题,发现自己书是没少看,正经走心的内容却不多 ...

  9. 浏览器缓存相关的Http头介绍:Expires,Cache-Control,Last-Modified,ETag

    转自:http://www.path8.net/tn/archives/2745 缓存对于web开发有重要作用,尤其是大负荷web系统开发中. 缓存分很多种:服务器缓存,第三方缓存,浏览器缓存等.其中 ...

  10. ios 缓存相关信息收集

    链接:http://www.cnblogs.com/pengyingh/category/353093.html 使用NSURLCache让本地数据来代替远程UIWebView请求 摘要: 原文作者: ...

随机推荐

  1. Centos7下安装PHP5.5,5.6,7.0----(转载记录一下)

    由于centOS7 默认的php版本是5.4的,偏低,所以收录了一下怎样安装5.5/5.6/7.0版本 默认的版本太低了,手动安装有一些麻烦,想采用Yum安装的可以使用下面的方案: 1.检查当前安装的 ...

  2. MVC之图片验证码

    MVC之图片验证码 controller中的action方法public ActionResult GetValidateCode() { ValidateCode vCode = new Valid ...

  3. volume_manager.go

    package ) type) ],,) ,)             vms.CanCreateVolume = false         } else {             vms.Can ...

  4. 「关于一种处理关于$p$成多项式的数论函数筛法」

    张博航原知乎网址 张博航原博客网址 引入: 给一个完全积性函数$f$,求其前缀和 $$S(n)=\sum_{i=1}^nf(i)$$ 初步思考: 考虑由于所求函数为完全积性函数,我们很容易用一个线性筛 ...

  5. HEOI2018——welcome to NOI2018

    我不得不和烈士和小丑走在同一道路上,  万人都要将火熄灭,  我一人独将此火高高举起,  我借此火得度一生的茫茫黑夜. ——海子 弹指一瞬间,翘首以盼的HEOI2018就来了. 我,一个滑稽的小丑,带 ...

  6. 【BZOJ 2744】【HEOI2012】朋友圈

    题目链接: TP 题解: 对于A国,我们发现,最大团一定不大于2.对于B国,发现同奇偶性点之间都有边,不同奇偶性之间可能有边,也就是说对于B国是一个二分图最大团,也就是求B国补图的二分图最大独立集.然 ...

  7. BZOJ_1877_[SDOI2009]晨跑_费用流

    BZOJ_1877_[SDOI2009]晨跑_费用流 题意: Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等 等,不过到目前为止,他 坚持下来的只有晨跑. 现在给出 ...

  8. Python并发编程之深入理解yield from语法(八)

    大家好,并发编程 进入第八篇. 直到上一篇,我们终于迎来了Python并发编程中,最高级.最重要.当然也是最难的知识点--协程. 当你看到这一篇的时候,请确保你对生成器的知识,有一定的了解.当然不了解 ...

  9. 对于zuul服务网关框架资料整理

    本次博客只是整理了一些 看过的博客.源码等 zuul入门(1)zuul 的概念和原理 https://www.cnblogs.com/lexiaofei/p/7080257.html 深入理解Zuul ...

  10. Python 视频转字符画 - 进阶

    这篇文章是 视频转字符动画-Python-60行代码 的后续,如果感兴趣,请先看看它. 1. 速度优化 要是每次播放都要等个一分钟,也太痛苦了一点. 所以可以用 pickle 模块把 video_ch ...