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

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

缓存的配置有两种策略:

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

稳定的内容 + 长期缓存

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

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. Java 读书笔记 (一) 基本知识

    1. 基本概念 对象 对象是类的一个实例,有状态和行为. 例如,一条狗是一个对象,它的状态有:颜色.名字.品种:行为有: 摇尾.叫.吃等. 类 类是一个模板,它描述一类对象的行为和状态. 方法 方法就 ...

  2. guid.go

    ] = byte(g)     hex.Encode(h[:], b[:])     return h }

  3. C++中char类型的溢出问题

    C++中什么经常会运用到char类型,也会将char类型作为循环语句的循环条件,但往往这里最容易出现错误,容易出现溢出,进入死循环.这里我们就来简单介绍下为什么会出现这种情况. 首先,了解下char类 ...

  4. Java基础系列--基础排序算法

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9082138.html 一.概述 基础排序算法包括:桶排序.冒泡排序.选择排序.插入排序等 ...

  5. ruby整理

    参考博客:https://www.cnblogs.com/felixzh/p/8081622.html 官网地址 https://rvm.io/rvm/install 一.前提  centos6.8下 ...

  6. ssh框架整合笔记

    1.建立普通的Javaweb项目,导入项目所必须的jar包. 2.配置web.xml文件. web.xml  3.在src下建立struts.xml. struts.xm 4.在实体包下配置  实体名 ...

  7. Android 8.1 源码_启动篇(二) -- 深入研究 zygote(转 Android 9.0 分析)

    前言 在Android中,zygote是整个系统创建新进程的核心进程.zygote进程在内部会先启动Dalvik虚拟机,继而加载一些必要的系统资源和系统类,最后进入一种监听状态.在之后的运作中,当其他 ...

  8. knowledge, Experience & Creativity

    In a training session, the trainer asked the audience "knowledge is power, how many of you agre ...

  9. java对象与Json字符串之间的转化(fastjson)

    1. 首先引入jar包 在pom.xml文件里加入下面依赖: <dependency> <groupId>com.alibaba</groupId> <art ...

  10. JVM 第一次学习总结(2019年4月)

    1.内存模型 起源:在计算机系统,加入了一层读写速度尽可能接近处理器运算速度的高速缓存来作为内存和处理器之间的缓冲. 问题:缓存一致性.在多处理器系统中,每个处理器都有自己的高速缓存(抽象为工作内存) ...