详解浏览器的缓存机制

目录
  • 前言
  • 1 浏览器缓存
    • 1.1 浏览器缓存
    • 1.2 浏览器缓存的意义
  • 2 缓存类型
    • 2.1 第一次请求数据
    • 2.2 强制缓存
    • 2.3 协商缓存
    • 2.4 强制缓存和协商缓存的关系
  • 3 缓存相关header
    • 3.1 强制缓存
    • 3.2 协商缓存
    • 3.3 缓存请求
  • 4 实例分析
    • 4.1 官网首页:
    • 4.2 社区
    • 4.3 云市场
    • 4.4 个人中心
    • 4.5 论坛
    • 4.6 App
  • 总结

前言

浏览器缓存是前端性能优化的重要一环,对于前端效率提升的重要性,不言而喻。

之前对于浏览器缓存也是一知半解,这次借着H5页面缓存优化的东风整理了一下本地浏览器端的缓存机制,如强制缓存、协商缓存等,并且然后结合门户域各部件(官网、云社区、云市场、个人中心、APP)当前的缓存机制进一步分解,旨在呈现下当前华为云官网的缓存策略,供大家参考。

1 浏览器缓存

1.1 浏览器缓存

缓存是一种本地保存远端资源的机制,不管是在客户端、还是在服务端存储着,用相同的URL进行数据请求,可以直接从缓存中请求资源而不再访问源服务器。

Web前端缓存大致可以分为:数据库缓存、服务器端缓存(代理服务器缓存、CDN缓存)、浏览器缓存。

浏览器缓存也包含很多内容:HTTP 缓存、indexDB、cookie、localstorage 等等。这里我们只讨论 HTTP 缓存相关内容。

1.2 浏览器缓存的意义

浏览器在本地对用户对最近请求过的文档进行存储,当用户再次访问同一页面时,浏览器就可以直接从本地磁盘加载文件。浏览器缓存的意义主要在:

a. 避免了冗余的数据传输,节省流量;

b. 加快了用户访问网页的速度;

c. 减小了服务器的压力。

2 缓存类型

2.1 第一次请求数据

浏览器第一次请求数据时,浏览器缓存中没有对应的缓存数据,此时需要请求服务器,浏览器返回数据后,会把请求的数据存储至缓存数据库中。

当浏览器中存在缓存数据后,可以根据是否需要向服务器发送请求,将缓存类型分为:强制缓存和协商缓存。

2.2 强制缓存

用户请求数据,如果命中强缓存,则不向服务器请求,而直接从本地资源获取,返回200状态码,并提示from disk cache或from memory cache(比从disk快)。

2.3 协商缓存

在用户请求资源时,浏览器直接向服务器发送请求,协商对比服务端和本地的资源,验证本地资源是否失效。

2.4 强制缓存和协商缓存的关系

强制缓存和协商缓存命中缓存资源后,都是从本地读取资源。如果强制缓存生效,则不需要再向服务器发出请求;而协商缓存,不管是否使用缓存,必须向服务器发送一个请求来协商。

两类缓存规则可以同时存在,强制缓存优先级高于协商缓存,也就是说,当执行强制缓存的规则时,如果缓存生效,直接使用缓存,不再执行协商缓存规则。如果强制缓存规则不生效,则需要进行协商缓存判断。

3 缓存相关header

上文介绍了强制缓存与协商缓存的流程,那么在浏览器中,浏览器如何判定缓存数据是否失效呢?如何确认是否使用缓存数据呢?

3.1 强制缓存

强制缓存的response header中会有两个字段来表明失效规则(Expires/Cache-Control)

1. Expires:Expires的值为服务端返回的到期时间,即下一次请求时,请求时间小于服务端返回的到期时间,直接使用缓存数据。不过Expires 是HTTP 1.0的东西,现在默认浏览器均默认使用HTTP 1.1,所以它的作用基本忽略。另一个问题是,到期时间是由服务端生成的,但是客户端时间可能跟服务端时间有误差,这就会导致缓存命中的误差。 所以HTTP 1.1 的版本,使用Cache-Control替代。

2. Cache-Control:Cache-Control 是最重要的规则。常见的取值有private、public、no-cache、max-age,

Expires和Cache-Control的关系:

a. 相同点:两者都是强缓存。

b. 不同点:

  • Expires是http1.0规定的,而Cache-Control是http1.1规定的。
  • Expires的过期时间采用的是绝对时间,容易造成差错; 而Cache-Control的过期时间采用的时相对时间,在缓存上不会出现问题。
  • 两者可以同时存在于一次请求中,但是不会同时在一次请求中起作用。 在HTTP1.0的环境下,Cache-Control不起作用,Expires起作用; 在HTTP1.1的环境之下, Expires不起作用,而Cache-Control起作用。当前一般都是http1.1的情况,所以Expires是作为一种向下兼容的形式而存在的。
  • Cache-Control的选择更多,功能更为强大,推荐使用。 Expires作为强缓存,功能单一,不推荐使用。

例如:下图(华为云官网首页)中,文件global.js的Cache-Control指定的缓存失效时间max-age为86400s(1天):

3.2 协商缓存

协商缓存一般是使用 if-modified-since/Last-Modified 和 if-none-match/Etag 由服务器来决定浏览器缓存的资源是否可以使用。

1. Last-Modified / If-Modified-Since

Last-Modified:服务器响应请求时,告诉浏览器资源最后的修改时间。

If-Modified-Since:浏览器再次请求资源时,浏览器通知服务器,上次请求时,返回的资源最后修改时间。

若最后修改时间小于等于If-Modified-Since,则response header返回304,告知浏览器继续使用所保存的cache。若大于If-Modified-Since,则说明资源被改动过,返回状态码200;

2. If-none-match / Etag

Etag:服务器响应请求时,告诉浏览器当前资源在浏览器的唯一标识(生成规则由服务器确定)

If-None-Match:再次请求服务器时,通过此字段通知服务器客户端缓存数据的唯一标识。服务器收到请求后发现有If-None-Match 则与被请求资源的唯一标识进行比对,不同,说明资源又被改动过,则响应整片资源内容,返回状态码200;相同,说明资源无新修改,则响应HTTP 304,告知浏览器继续使用所保存的cache。

Etag与Last-Modified对比:

1.在精确度上,Etag优于Last-Modified。Last-Modified精确到s,如果1s内,资源多次改变,Etag是可以判断出来并返回最新的资源。

2.在性能上,Last-Modified优于Etag,因为Last-Modified只需要记录时间,而Etag需要服务器重新生成hash值,所以性能上略差。

3.在优先级上,Etag优于Last-Modified,Etag和Last-Modified可同时存在。本地缓存时间到期后,浏览器向服务端发送请求报文,其中Request Header中包含If-none-match和Last-Modified-Since(与服务端Etag和Last-Modified对比,Etag优先级高),用以验证本地缓存数据验证是否与服务端保持一致。在服务器端会优先判断Etag。如果相同,返回304;如果不同,就继续比较Last-Modified,然后决定是否返回新的资源。若服务端验证本地缓存与服务端一致,返回304,浏览器加载本地缓存;否则,服务器返回请求的资源,同时给出新的Etag以及Last-Modified时间。

3.3 缓存请求

以下为浏览器缓存的流程:

4 实例分析

对于客户端来说,浏览器在使用本地缓存数据时,需要对齐本地与服务器的资源;但是,对于服务端,服务器将资源下发给客户端,服务端就失去了对齐的控制权。比如,服务端设定缓存失效的max-age,在这段时间内,哪怕服务端资源已发生更改,服务端也无法通知客户端资源更新通知。所以,对于一个网页来说,需要合理的指定缓存的废弃与更新的响应策略,从而既能提升页面加载速度,同时确保页面的准确性。

以下结合华为云官网各部件,分析缓存的废弃和更新的响应策略:

4.1 官网首页:

注释:

  • Html:缓存有效时间为0s,页面加载时,强制浏览器每次向源服务器确认数据;
  • Css:改动频率较低,允许使用本地缓存,且存在强制缓存时间(各个css文件不同,按需设置);强制缓存失效再进行协商缓存;
  • Js:允许使用本地缓存,且存在强制缓存时间(各个js文件不同,按需设置);强制缓存失效再进行协商缓存;
  • Image:图片修改频率更低,允许使用本地缓存,且存在强制缓存时间(各个image文件不同,按需设置);强制缓存失效再进行协商缓存;
  • Gif:官网中gif主要存在于banner轮播,因此确保时效性,使用no-cache,不允许缓存,强制每次向源服务器确认数据。

注意(以下已官网首页为例,介绍缓存与版本号的关系,其余各部件都存在相同问题,后续不一一解释。):

上图描述的是可缓存文件的缓存策略。但是,网页中还有很多文件,比如global.js、global.css等,更新频率较快,如果一直使用本地缓存可能会影响页面的正确性。因此,在引用这部分文件时,会在文件后添加个版本号,用以刷新缓存,以此确保本地资源的时效性,添加版本号的目的是为了强制要求文件每次加载重新向服务端请求。如下,左图给出了部分文件的版本号后缀。这部分文件在浏览器重新加载后,请求报文的头文件,Request Header的Cache-control值为no-cache,即无缓存,重新请求数据。如下右图所示:

4.2 社区

注释:

  • Html:缓存权限为public;本地缓存到期时间expires为固定Thu, 19 Nov 1981 08:52:00 GMT,也就是本地缓存永远是到期的;因此,每次加载页面都需要重新向源服务器获取资源。
  • Css:改动频率较低,允许使用本地缓存,且强制缓存时间为1天;强制缓存失效再进行协商缓存;
  • Js:允许使用本地缓存,且强制缓存时间为1天;强制缓存失效再进行协商缓存;
  • Image:图片修改频率更低,png格式文件允许使用本地缓存,且强制缓存时间为1周,jpg格式文件为一月; 本地缓存到期后,会继续通过判定Etag和Last-Modified,验证本地缓存的有效性,(方法见3.2,优先级)。图片的缓存策略中,强缓存和协商缓存同时存在,因为页面中一般图片资源较大,但是修改频率较低,所以使用缓存可以提升浏览器加载速度。

4.3 云市场

注释:

  • Css:强制缓存时间为1天;强制缓存失效再进行协商缓存;
  • Js:强制缓存时间为1天;强制缓存失效再进行协商缓存;
  • Image:强制缓存时间为1周;强制缓存失效再进行协商缓存;

4.4 个人中心

注释:

  • Css:强制缓存时间为1天;强制缓存失效再进行协商缓存;
  • Js:强制缓存时间为1天或1周,不同文件不同;强制缓存失效再进行协商缓存;
  • Image:强制缓存时间为1周;强制缓存失效再进行协商缓存;

4.5 论坛

注释:

  • Css:强制缓存时间为1周;强制缓存失效再进行协商缓存;
  • Js:强制缓存时间为1周,不同文件不同;强制缓存失效再进行协商缓存;
  • Image:强制缓存时间为1周;强制缓存失效再进行协商缓存;

4.6 App

移动端缓存策略参考其余部件缓存机制,不另做展示。

总结

在现网页面中,css、js、image等不同类型文件的缓存策略大致相同。即同时存在强缓存和协商缓存策略。对于强缓存,给定本地缓存的有效时间max-age,一般根据不同文件类型的确定max-age大小;对于协商缓存,给定Last-Modified和Etag标识,服务器端验证客户端缓存的有效性。本章中给出了,官网各部件浏览器端缓存策略的简介。但是,部分文件会存在特殊的缓存设置。比如,页面中很多的js、css、image等会添加版本号,强制刷新缓存等。

以上就是详解浏览器的缓存机制的详细内容,更多关于浏览器的缓存机制的资料请关注我们其它相关文章!

(0)

相关推荐

  • JS清除IE浏览器缓存的方法

    js中自动清除ie缓存方法 - 常用 对于动态文件,比如 index.asp?id=... 或者 index.aspx?id=... 相信有经验的程序员都知道怎样禁止浏览器缓存数据了. 但是对于静态文件(css,jpg,gif等等), 在什么场合下面我们需要禁止浏览器缓存他们,怎么做? 方法一:Dojo中我们可以用简单的方法完成:在dojo.xhrGet(包括post)等方法中都包含preventCache属性,此属性的含义: "默认为启用浏览器缓存,否则将通过自动增加不同的参数来确保浏览器缓存

  • 浏览器缓存知识小结及应用分析

    浏览器缓存,也就是客户端缓存,既是网页性能优化里面静态资源相关优化的一大利器,也是无数web开发人员在工作过程不可避免的一大问题,所以在产品开发的时候我们总是想办法避免缓存产生,而在产品发布之时又在想策略管理缓存提升网页的访问速度.了解浏览器的缓存命中原理,是开发web应用的基础,本文着眼于此,学习浏览器缓存的相关知识,总结缓存避免和缓存管理的方法,结合具体的场景说明缓存的相关问题.希望能对有需要的人有所帮助. 1. 浏览器缓存基本认识 它分为强缓存和协商缓存: 1)浏览器在加载资源时,先根据这

  • JavaWeb如何实现禁用浏览器缓存

    这篇文章主要介绍了JavaWeb如何实现禁用浏览器缓存,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.禁用浏览器缓存可以通过设置响应头的方式,有如下3个响应头可禁用浏览器缓存问题 1.Cache-control 2.pragma 3.expires 二.代码示例 package cn.xxx.Servlet; import java.io.IOException; import javax.servlet.ServletException;

  • 解析浏览器端的AJAX缓存机制

    AJAX的缓存是由浏览器维持的,对于发向服务器的某个url,ajax仅在第一次请求时与服务器交互信息,之后的请求中,ajax不再向服务器提交请求,而是直接从缓存中提取数据. 有些情况下,我们需要每一次都从服务器得到更新后数据.思路是让每次请求的url都不同,而又不影响正常应用:在url之后加入随机内容. e.g. url=url+"&"+Math.random(); Key points: 1.每次请求的url都不一样(ajax的缓存便不起作用) 2.不影响正常应用(最基本的)

  • 清除浏览器缓存的几种方法总结(必看)

    关于浏览器缓存 浏览器缓存,有时候我们需要他,因为他可以提高网站性能和浏览器速度,提高网站性能.但是有时候我们又不得不清除缓存,因为缓存可能误事,出现一些错误的数据.像股票类网站实时更新等,这样的网站是不要缓存的,像有的网站很少更新,有缓存还是比较好的.今天主要介绍清除缓存的几种方法. 清理网站缓存的几种方法 meta方法 //不缓存 <META HTTP-EQUIV="pragma" CONTENT="no-cache"> <META HTTP-

  • JSP实现屏蔽浏览器缓存的方法

    本文实例讲述了JSP实现屏蔽浏览器缓存的方法.分享给大家供大家参考,具体如下: 很多时候因为浏览器的缓冲经常导致页面不能即时加载,以至于以为数据错误,那么在JSP内,设置如下几行代码,每次页面张开浏览器都将重新从服务器上读取数据,以保证浏览器上看到的数据为最新.   通过设置响应首部,就能够让浏览器和代理服务器不缓存页面.   方法一: <% response.addHeader("Pragma", "no-cache"); response.setHeade

  • 屏蔽浏览器缓存另类方法

    有时候我们不希望浏览器使用缓存加快网页的显示,尤其是那些论坛之类的频繁更新内容的网页,在网上有说可以使用下面的方法来屏蔽缓存,但是我试了效果不好. <META HTTP-EQUIV="Pragma" CONTENT="no-cache"> 某日我突发奇想,找到了一种在任何情况下都会显示最新的网页内容的方法,描述如下: 请将网页的链接改为: http://xxx.yyy.zzz/page.php?rand=XXXXXXX 其中http://xxx.yyy.

  • 多种浏览器清除缓存的方法小结

    有关说明,请从以下浏览器中选择您的浏览器: Firefox 在 PC 的 Firefox 中: 关闭所有其他打开的浏览器窗口. 在浏览器顶部,点击工具菜单,选择清除私有数据.... 选中 Cookie 和高速缓存复选框. 点击立即清除私有信息. 在 Mac 的 Firefox 中: 关闭所有其他打开的浏览器窗口. 在浏览器顶部点击 Firefox 菜单,然后选择首选项... 选择隐私标签. 在对话框最下方点击立即清除.... 在新对话框中选中缓存和 Cookie 旁边的框. 点击立即清除私有信息

  • 详解浏览器缓存和webpack缓存配置

    浏览器缓存 浏览器缓存分为两种类型: 强缓存:也称为本地缓存,不向服务器发送请求,直接使用客户端本地缓存数据 协商缓存:也称304缓存,向服务器发送请求,由服务器判断请求文件是否发生改变.如果未发生改变,则返回304状态码,通知客户端直接使用本地缓存:如果发生改变,则直接返回请求文件. 浏览器缓存机制的过程如下: 强缓存(本地缓存) 强缓存是最彻底的缓存,无需向服务器发送请求,通常用于css.js.图片等静态资源.浏览器发送请求后会先判断本地是否有缓存.如果无缓存,则直接向服务器发送请求:如果有

  • 详解浏览器的缓存机制

    目录 前言 1 浏览器缓存 1.1 浏览器缓存 1.2 浏览器缓存的意义 2 缓存类型 2.1 第一次请求数据 2.2 强制缓存 2.3 协商缓存 2.4 强制缓存和协商缓存的关系 3 缓存相关header 3.1 强制缓存 3.2 协商缓存 3.3 缓存请求 4 实例分析 4.1 官网首页: 4.2 社区 4.3 云市场 4.4 个人中心 4.5 论坛 4.6 App 总结 前言 浏览器缓存是前端性能优化的重要一环,对于前端效率提升的重要性,不言而喻. 之前对于浏览器缓存也是一知半解,这次借着

  • 详解java实践SPI机制及浅析源码

    1.概念 正式步入今天的核心内容之前,溪源先给大家介绍一下关于SPI机制的相关概念,最后会提供实践源代码. SPI即Service Provider Interface,属于JDK内置的一种动态的服务提供发现机制,可以理解为运行时动态加载接口的实现类.更甚至,大家可以将SPI机制与设计模式中的策略模式建立联系. SPI机制: 从上图中理解SPI机制:标准化接口+策略模式+配置文件: SPI机制核心思想:系统设计的各个抽象,往往有很多不同的实现方案,在面向的对象的设计里,一般推荐模块之间基于接口编

  • 详解JavaScript 的执行机制

    一.关于javascript javascript是一门单线程语言,在最新的HTML5中提出了Web Worker,但javascript是单线程这一核心仍未改变. 为什么js是单线程的语言?因为最初的js是用来在浏览器验证表单操纵DOM元素的.如果js是多线程的话,两个线程同时对一个DOM进行了相互冲突的操作,那么浏览器的解析是无法执行的. Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行.在主线程运行的同

  • 详解 MySQL的FreeList机制

    一.前言 MySQL启动后,BufferPool就会被初始化,在你没有执行任何查询操作之前,BufferPool中的缓存页都是一块块空的内存,未被使用过也没有任何数据保存在里面. 而且你也知道了通过缓冲页的描述信息可以直接且唯一的找到它所指向的缓存页. 那你有没有想过,我们从磁盘里面读取出来的 数据页 应该放到那个缓冲页中去呢? 这个问题就引出了Free List. 二.Free List 其实Free List是Buffer Pool中基于缓存页描述信息 组织起来的双向链表.换言之,Free

  • 详解Java 虚拟机垃圾收集机制

    1 垃圾收集发生的区域 之前我们介绍过 Java 内存运行时区域的各个部分,其中程序计数器.虚拟机栈.本地方法栈三个区域随线程共存亡.栈中的每一个栈帧分配多少内存基本上在类结构确定下来时就已知,因此这几个区域的内存分配和回收都具有确定性,不需要考虑如何回收的问题,当方法结束或线程结束,内存自然也跟着回收了 而 Java 堆和方法区这两个区域则有显著的不确定性,只有在程序运行时我们才能知道程序究竟创建了哪些对象,创建了多少对象,所以这部分内存的分配和回收是动态的,垃圾收集器所关注的正是这部分内存该

  • 详解vue3的沙箱机制

    前言 vue3 沙箱主要分两种 浏览器编译版本,浏览器版本是使用with语法加上proxy代理拦截 本地预编译版本,通过在模版预编译阶段转换阶段,使用转换插件transformExpression将非白名单标识符挂在在组件代理对象下 浏览器编译版本 render 函数编译结果 <div>{{test}}</div> <div>{{Math.floor(1)}}</div> to const _Vue = Vue; return function render

  • 详解CocosCreator项目结构机制

     一.项目文件夹结构 初次创建并打开一个 Cocos Creator 项目后,开发者的项目文件夹将会包括以下结构: 下面我们将会介绍每个文件夹的功能. 1.资源文件夹(assets) assets 将会用来放置游戏中所有的本地资源.脚本和第三方库文件.只有在 assets 目录下的内容才能显示在 资源管理器 中.assets 中的每个文件在导入项目后都会生成一个相同名字的 .meta 文件,用于存储对应的资源配置和索引信息..meta 文件需要一并提交到版本控制系统,详见 资源管理注意事项 --

  • 详解Java的类加载机制及热部署的原理

    一.什么是类加载 类的加载指的是将类的.class文件的二进制数据读入到内存中,将其放在运行数据区的方法去,然后再堆区创建一个java.lang.Class对象,用来封装类在方法区的数据结构.类的加载的最终产品是位于堆区中的Class对象,Class对象封装了类在方法区的数据结构,并且向Java程序员提供了访问方法区的数据结构的接口. 类加载器并不需要等到某个类被"首次主动使用"时再加载它,JVM规范允许类加载器在预料某个类将要被使用时就预先加载它,如果在预先加载的过程中遇到了.cla

  • 详解php内存管理机制与垃圾回收机制

    一.内存管理机制 先看一段代码: <?php //内存管理机制 var_dump(memory_get_usage());//获取内存方法,加上true返回实际内存,不加则返回表现内存 $a = "laruence"; var_dump(memory_get_usage()); unset($a); var_dump(memory_get_usage()); //输出(在我的个人电脑上, 可能会因为系统,PHP版本,载入的扩展不同而不同): //int 240552 //int

  • SpringBoot详解整合Redis缓存方法

    目录 1.Spring Boot支持的缓存组件 2.基于注解的Redis缓存实现 3.基于API的Redis缓存实现 1.Spring Boot支持的缓存组件 在Spring Boot中,数据的缓存管理存储依赖于Spring框架中cache相关的org.springframework.cache.Cache和org.springframework.cache.CacheManager缓存管理器接口. 如果程序中没有定义类型为CacheManager的Bean组件或者是名为cacheResolve

随机推荐