在前端开发中,性能一直都是被大家所重视的一点,然而判断一个网站的性能最直观的就是看网页打开的速度。其中提高网页反应速度的一个方式就是使用缓存。一个优秀的缓存策略可以缩短网页请求资源的距离,减少延迟,并且由于缓存文件可以重复利用,还可以减少带宽,降低网络负荷。那么下面我们就来看看服务器端缓存的原理。

缓存分类

web缓存分为很多种,比如数据库缓存、代理服务器缓存、还有我们熟悉的CDN缓存,以及浏览器缓存。对于太多文字的阅读其实我是拒绝的,于是就画了个图来解释下。

浏览器通过代理服务器向源服务器发起请求的原理如下图:

浏览器先向代理服务器发起Web请求,再将请求转发到源服务器。它属于共享缓存,所以很多地方都可以使用其缓存资源,因此对于节省流量有很大作用。

浏览器缓存是将文件保存在客户端,在同一个会话过程中会检查缓存的副本是否足够新,在后退网页时,访问过的资源可以从浏览器缓存中拿出使用。通过减少服务器处理请求的数量,用户将获得更快的体验

下面我就来着重讲下传说中的浏览器缓存。

浏览器缓存

页面的缓存状态是由header决定的,header的参数有四种:

一、Cache-Control:

1、max-age(单位为s)指定设置缓存最大的有效时间,定义的是时间长短。当浏览器向服务器发送请求后,在max-age这段时间里浏览器就不会再向服务器发送请求了。

我们来找个资源看下。比如shang.qq.com上的css资源,max-age=2592000,也就是说缓存有效期为2592000秒(也就是30天)。于是在30天内都会使用这个版本的资源,即使服务器上的资源发生了变化,浏览器也不会得到通知。max-age会覆盖掉Expires,后面会有讨论。

2、s-maxage(单位为s)同max-age,只用于共享缓存(比如CDN缓存)。

比如,当s-maxage=60时,在这60秒中,即使更新了CDN的内容,浏览器也不会进行请求。也就是说max-age用于普通缓存,而s-maxage用于代理缓存。如果存在s-maxage,则会覆盖掉max-age和Expires header。

3、public 指定响应会被缓存,并且在多用户间共享。也就是下图的意思。如果没有指定public还是private,则默认为public。

4、private 响应只作为私有的缓存(见下图),不能在用户间共享。如果要求HTTP认证,响应会自动设置为private。

5、no-cache 指定不缓存响应,表明资源不进行缓存,比如,

但是设置了no-cache之后并不代表浏览器不缓存,而是在缓存前要向服务器确认资源是否被更改。因此有的时候只设置no-cache防止缓存还是不够保险,还可以加上private指令,将过期时间设为过去的时间。

6、no-store 绝对禁止缓存,一看就知道如果用了这个命令当然就是不会进行缓存啦~每次请求资源都要从服务器重新获取。

7、must-revalidate指定如果页面是过期的,则去服务器进行获取。这个指令并不常用,就不做过多的讨论了。

二、Expires

缓存过期时间,用来指定资源到期的时间,是服务器端的具体的时间点。也就是说,Expires=max-age + 请求时间,需要和Last-modified结合使用。但在上面我们提到过,cache-control的优先级更高。 Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。

三、Last-modified

服务器端文件的最后修改时间,需要和cache-control共同使用,是检查服务器端资源是否更新的一种方式。当浏览器再次进行请求时,会向服务器传送If-Modified-Since报头,询问Last-Modified时间点之后资源是否被修改过。如果没有修改,则返回码为304,使用缓存;如果修改过,则再次去服务器请求资源,返回码和首次请求相同为200,资源为服务器最新资源。

如下图,最后修改时间为2014年12月19日星期五2点50分47秒

四、ETag

        根据实体内容生成一段hash字符串,标识资源的状态,由服务端产生。浏览器会将这串字符串传回服务器,验证资源是否已经修改,如果没有修改,过程如下:

使用ETag可以解决Last-modified存在的一些问题:

a、某些服务器不能精确得到资源的最后修改时间,这样就无法通过最后修改时间判断资源是否更新

b、如果资源修改非常频繁,在秒以下的时间内进行修改,而Last-modified只能精确到秒

c、一些资源的最后修改时间改变了,但是内容没改变,使用ETag就认为资源还是没有修改的。

使用缓存流程

还是用图说话,下面是我所总结的从浏览器请求到展示资源的过程:

cache-control指令使用

说了那么多cache-control的指令,那么如何选择使用哪些指令呢?我还是不说话==

额外的

除了开头提到的那么多缓存方式以外,还有一种我们都熟悉的缓存方式,LocalStorage和sessionStorage(好像是两种23333)。

LocalStorage是一种本地存储的公共资源,域名下很多应用共享这份资源会有风险;LocalStorage是以页面域名划分的,如果有多个等价域名之间的LocalStorage不互通,则会造成缓存多份浪费。

LocalStorage在PC上的兼容性不太好,而且当网络速度快、协商缓存响应快时使用localStorage的速度比不上304。并且不能缓存css文件。而移动端由于网速慢,使用localStorage要快于304。

在html中加载一个png图,首次加载的时候时间如下图,

然而将图片使用了LocalStorage存储后,再次刷新后加载时间为0。

而相对LocalStorage来说,SessionStorage的数据只存储到特定的会话中,不属于持久化的存储,所以关闭浏览器会清除数据。和localstorage具有相同的方法。

在前端开发中缓存是必不可少的,那么使用怎样的缓存方式更高效、让我们项目的性能更优,还是需要我们仔细斟酌。

原创文章转载请注明:

转载自AlloyTeam:http://www.alloyteam.com/2016/03/discussion-on-web-caching/

浅析Web缓存的更多相关文章

  1. Web缓存相关知识整理

    一.前言  工作上遇到一个这样的需求,一个H5页面在APP端,如果勾选已读状态,则下次打开该链接,会跳过此页面.用到了HTML5 的本地存储 API 中的 localStorage作为解决方案,回顾了 ...

  2. 作为前端应当了解的Web缓存知识

    缓存优点 通常所说的Web缓存指的是可以自动保存常见http请求副本的http设备.对于前端开发者来说,浏览器充当了重要角色.除此外常见的还有各种各样的代理服务器也可以做缓存.当Web请求到达缓存时, ...

  3. Web缓存杂谈

    一.概述 缓存通俗点,就是将已经得到的‘东东’存放在一个相对于自己而言,尽可能近的地方,以便下次需要时,不会再二笔地跑到起始点(很远的地方)去获取,而是就近解决,从而缩短时间和节约金钱(坐车要钱嘛). ...

  4. 前端应当了解的Web缓存知识

    缓存优点 通常所说的Web缓存指的是可以自动保存常见http请求副本的http设备.对于前端开发者来说,浏览器充当了重要角色.除此外常见的还有各种各样的代理服务器也可以做缓存.当Web请求到达缓存时, ...

  5. 浅谈Web缓存

    在前端开发中性能一直都是被大家所重视的一点,然后判断一个网站的性能最直观的就是看网页打开的速度. 其中提高网页反应的速度的一个方式就是使用缓存.一个优秀的缓存策略可以缩短网页请求资源的距离,减少延迟, ...

  6. web缓存

    web缓存HTTP协议的一个核心特性,它能最小化网络流量,并且提升用户所感知的整个系统响应速度. 什么能被缓存? *Logo和商标图像 *普通的不变化的图像(例如,导航图标) *CSS样式表 *普通的 ...

  7. Web 技术人员需知的 Web 缓存知识(转)

    最近的译文距今已有4年之久,原文有一定的更新.今天踩着前辈们的肩膀,再次把这篇文章翻译整理下.一来让自己对web缓存的理解更深刻些,二来让大家注意力稍稍转移下,不要整天HTML5, 面试题啊叨啊叨的~ ...

  8. c# web 缓存管理

    using System; using System.Collections; using System.Text.RegularExpressions; using System.Web; usin ...

  9. HTML5时代的Web缓存机制

    HTML5 之离线应用Manifest 我们知道,使用传统的技术,就算是对站点的资源都实施了比较好的缓存策略,但是在断网的情况下,是无法访问的,因为入口的HTML页面我们一般运维的考虑,不会对其进行缓 ...

随机推荐

  1. Angular--学习

    18:28:34 Angular简介 AngularJS通过指令 扩展了HTML,并通过 表达式 绑定数据到HTML Angular扩展了HTML AngularJS 通过 ng-directives ...

  2. MYSQL中 ENUM 类型的详细解释

    ENUM 是一个字符串对象,其值通常选自一个允许值列表中,该列表在表创建时的列规格说明中被明确地列举. 在下列某些情况下,值也可以是空串("") 或 NULL: 如果将一个无效值插 ...

  3. c中的可重入和不可重入函数

    可重入和不可重入 的基本概念 ---简介--- 可重入函数主要用于多任务环境中,一个可重入的函数简单来说就是可以被中断的函数,也就是说,可以在这个函数执行的任何时刻中断它,转入OS调度下去执行另外一段 ...

  4. Tensorflow学习笔记---0--TensorBoard

    运行mnist_with_summaries学习TensorBoard时,由于需要GPU支持,运行窗口报错:Couldn't open CUDA library cupti64_80.dll 解决办法 ...

  5. 第一章:Druid简介

    第一章:Druid简介 声明 公司的项目中用到了Druid(不是阿里的连接池),由于网上没有中文的文档,所以只好阅读官方文档.本人第一次阅读英文的文档,非常吃力,借助翻译工具和自己的理解阅读了Duri ...

  6. JS和CSS中引号的使用

        font-family属性值如果是英文可以不加引号,如果是中文按照CSS标准则应该加引号,但不加引号也没关系.比如:font-family:Arial,"宋体"," ...

  7. ES6 深入let的作用域

    说到ES6的let变量声明,我估计很多人会想起下面几个主要的特点: 没有变量声明提升 拥有块级作用域 暂时死区 不能重复声明 很多教程和总结基本都说到了这几点(说实话大部分文章都大同小异,摘录的居多) ...

  8. NodeJS+express+mogondb学习笔记01

    0.准备工作  安装nodejs环境  官网地址:https://nodejs.org/en/  下载好了 直接一路安装 也没有什么可以说的 不得不说nodejs对于新手上手还是很友好的,再加上现在n ...

  9. TCP三次握手四次挥手过程及各过程中客户端和服务器端的状态。

    #三次握手 客户端向服务器端发送SYN包,客户端进入SYN_SEND状态 服务器端收到客户端发送的包返回ACK+SYN包,服务器端进入SYN_RECV状态 客户端收到服务器端返回的包再发回ACK包,客 ...

  10. ST-LINK调试完成

    今天真是一波三折啊. 买回来的st-link刚开始不会用,各种百度,还好有两个很好的教程.连接发在下面吧. http://blog.csdn.net/TXF1984/article/details/4 ...