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

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

缓存的配置有两种策略:

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

稳定的内容 + 长期缓存

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

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. Prometheus运⾏框架介绍

    框架结构的展⽰图 • 我们先来看下这个部分 这⾥是 prometheus的服务端也就是核⼼ prometheus本⾝是⼀个以进程⽅式启动,之后以多进程和多线程实现监控数据收集 计算 查询 更新 存储 ...

  2. fatal: HttpRequestException encountered 解决方法

    fatal: HttpRequestException encountered解决方法   之前在windows下一段时间git push都没什么问题,最近一旦提交就会弹出  无论是push前先将远程 ...

  3. SQL2008全部数据导出导入两种方法

    方法一:生成脚本导出导入sql2008全部数据第一步,右键要导出的数据库,任务--生成脚本 第二步,在设置脚本编写选项处,点击--高级(A),选择要编写脚本的数据的类型为:架构和数据 如果找不到 要编 ...

  4. BZOJ 1260:[CQOI2007]涂色paint

    (⊙o⊙)-,常规课考试又炸了!目测此次我要完蛋了... 又玩脱了,考数学的时候装B装大了! 算了,先进入正题... 题目描述:Description假设你有一条长度为5的木版,初始时没有涂过任何颜色 ...

  5. 文本分布式表示(二):用tensorflow和word2vec训练词向量

    看了几天word2vec的理论,终于是懂了一些.理论部分我推荐以下几篇教程,有博客也有视频: 1.<word2vec中的数学原理>:http://www.cnblogs.com/pegho ...

  6. Python中os和sys模块中常用的方法

    os模块 os模块:该模块提供了一些方便使用操作系统相关功能的函数 os.remove() 删除文件 os.rename() 重命名文件 os.walk() 文件目录遍历器 os.chdir() 改变 ...

  7. Redis - NoSQL数据库技术(一)

    NoSQL入门概述(一) 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 什么是NoSQL NoSQL(NoSQL - Not Only SQL),意“不仅仅是SQL”: 泛指非关系 ...

  8. Java异常处理最佳实践及陷阱防范

    前言 不管在我们的工作还是生活中,总会出现各种“错误”,各种突发的“异常”.无论我们做了多少准备,多少测试,这些异常总会在某个时间点出现,如果处理不当或是不及时,往往还会导致其他新的问题出现.所以我们 ...

  9. linux高级编程

    系统调用 01.什么是系统调用? 02.Linux系统调用之I/O操作(文件操作) 03.文件描述符的复制:dup(), dup2() 多进程实现多任务 04.进程的介绍 05.Linux可执行文件结 ...

  10. 图解CSS3-flex布局

    前言 最近笔者在复习以前基础知识,发现很多细的知识点还是需要重新再总结一番.本文对flex布局进行图解说明,以后忘了的同学可以随时过来查看,欢迎转载,烦请注明出处. 主体 万丈高楼平地起,熟悉flex ...