前端缓存总结-HTTP缓存

前言

在前端面试中,可能或多或少都会被提及缓存问题,而这个问题大多数都是作为业务中不得不考虑的一个性能优化点,如果平时没有怎么关注或是特意去了解这块的童鞋们,可能就是不太了解其中的原由,那么今天我们就这个缓存问题来细细分析,帮助一些还不是太明白的或是刚入门的前端童鞋们梳理梳理,理解理解,那就话不多说,开始吧-

概述

其实缓存有很多种,包括:HTTP缓存DNS缓存CDN缓存等等。今天主要介绍的就是HTTP缓存,在开始介绍之前,先简单说说HTTP报文。

HTTP报文就是浏览器和服务器之间通信时发送响应的数据块。
浏览器向服务器请求数据,发送请求(request)报文;服务器向浏览器返回数据,返回响应(response)报文。

报文主要包含以下两部分:

  1. 属性的头部(header);
  2. 数据的主体部分(body);

浏览器缓存策略

浏览器每次发起请求时,先在本地缓存中查找结果以及缓存标识,根据缓存标识来判断是否使用本地缓存。如果缓存有效,则使用本地缓存;否则,向服务器发起请求并携带缓存标识。根据是否需要向服务器发起HTTP请求,将缓存过程划分为两个部分:

  1. 强制缓存:服务器通知浏览器一个缓存时间,在缓存时间内,下次请求直接使用缓存,不在时间内,执行比较缓存策略;
  2. 协商缓存:让客户端与服务器之间能实现缓存文件是否更新的验证、提升缓存复用率,将缓存信息中的EtagLast-Modified通过请求发送给服务器,由服务器校验,返回304状态码时,浏览器直接使用缓存;

强缓存优先于协商缓存。

缓存运作的整体流程图如下:


流程图

强制缓存

当请求命中强制缓存时,浏览器不会将本次请求发往服务器,而是直接从缓存中读取内容,在Chrome中打开控制台,在network中显示的是memory cache或者是disk cache

强制缓存

强缓存可以通过设置两种HTTP Header实现:Expires(1.0)Cache-Control(1.1)

Expires

Expires是一个绝对时间,是缓存过期时间。用以表达在这个时间点之前发起请求可以直接从浏览器中读取数据,而无需重新发起请求。

Expires = max-age + 到期时间。由于受限于本地时间,如果修改了本地时间,可能会造成缓存失效。

该字段是服务器响应消息头字段,告诉浏览器在过期时间之前可以直接从浏览器缓存中存取数据。由于是绝对时间内,用户可能将本读时间进行修改,从而导致浏览器判断缓存失效,重新请求资源。在不考虑修改,时差或者误差等因素也可能照成客户端于服务端的时间不一致,致使缓存失效。

优点:

  1. HTTP 1.0产物,可以在HTTP 1.0和1.1中使用,简单、易用。
  2. 以时刻标识失效时间。

缺点:

  1. 时间是由服务器发送的,如果服务器时间和客户端时间不一致,可能会出现问题。
  2. 存在版本问题,到期之前的修改客户端是不可知的。

Cache-Control

Cache-Control的优先级比Expires的优先级高。该字段表示资源缓存最大有效时间,在该时间内,客户端不需要向服务器发送请求。前者的出现是为了解决Expires在浏览器中,时间被手动更改导致缓存判断错误的问题。如果同时存在则使用Cache-Control

常见的取值有(完整的列表可以查看MDN):

  • private(默认值):客户端可以缓存,代理服务器不能缓存
  • public:客户端和代理服务器都可缓存
  • no-cache:在发布缓存副本之前,强制要求缓存把请求提交给原始服务器进行验证(协商缓存验证)
  • max-age:设置缓存存储的最大周期,超过这个时间缓存被认为过期(单位秒)
  • no-store:缓存不应该存储有关客户端请求或服务器响应的任何内容,即使不使用任何缓存

举个栗子🌰:

强制缓存

图中Cache-Control指定了max-agepublic,缓存时间为31536000秒(365天)。
也就是说,在365天内再次请求这条数据,都会直接获取缓存数据库中的数据,直接使用。

优点:

  1. HTTP 1.1产物,以时间间隔标识失效时间,解决了Expires服务器和客户端相对时间的问题。
  2. 比Expires多了很多选项设置。

缺点:

  1. 存在版本问题,到期之前的修改客户端是不可知的。

协商缓存

协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程。而整个过程是需要发出请求的。

协商缓存由2组字段(不是2个),控制协商缓存的字段有:

  • Last-Modified/If-Modified-since(http 1.0): 表示的是服务器的资源最后一次修改的时间;
  • Etag/If-None-match(http 1.1): 表示的是服务器资源的唯一标识,只要资源有变化,Etag就会重新生成;

Etag/If-None-match 的优先级高于Last-Modified/If-Modified-since。

Last-Modified/If-Modified-since

  1. 服务器通过 Last-Modified 字段告知客户端(返回资源的同时在header添加),表示资源最后一次被修改的时间,浏览器将这个值和内容一起记录在缓存数据库中
  2. 下一次请求相同的资源时,浏览器会从自己的缓存中找出“不确定是否过期的”缓存,因此在请求头中将上次的Last-Modified的值写入到请求头的If-Modified-since字段
  3. 服务器会将If-Modified-since的值与Last-Modified字段进行对比。如果相等,这表示未修改,响应304;反之则表示修改了,响应 200 状态码,并返回数据

优点:

  1. 不存在版本问题,每次请求都会去服务器进行校验。服务器对比最后修改时间如果相同则返回304,不同返回200及资源内容。
  2. 如果返回的是 304,返回的仅仅是一个状态码而已,并没有实际的文件内容,因此在响应体的体积上节省是很好的优点

缺点:

  1. 只要资源发生了修改,无论内容是否发生了实质性的改变,都会将该资源返回客户端。例如周期性重写,但这种情况下资源包含的数据实质是一样的。
  2. 以时刻作为标识,无法识别一秒内多次修改的情况。如果资源更新的速度是秒以下的单位,那么该缓存是不能被使用的,因为它的时间最低单位是秒。
  3. 某些服务器不能精确的得到文件最后修改时间。
  4. 如果文件是服务器动态生成的,那么该方法的更新时间永远是生成的时间,尽管文件可能并没有变化,所以也起不到缓存的作用。

Etag/If-None-match

为了解决上述问题,出现了一组新的字段Etag/In-None-Match

  1. Etag是上一次加载资源时,服务器返回的。它的作用是唯一用来标识资源是否有变化
  2. 浏览器在下一次发起请求时,会将上一次返回的Etag值赋值给If-None-Match并添加在 Request Header 中。服务端匹配传入的值与上次是否一致,如果一致返回304,浏览器则读取本地缓存,否则返回200和更新后的资源及新的Etag

优点:

  1. 可以更加精确的判断资源是否被修改,可以识别一秒内多次修改的情况
  2. 不存在版本问题,每次请求都会去服务器进行校验

缺点:

  1. 计算Etag值需要性能损耗
  2. 分布式服务器存储情况下下,计算Etag的算法如果不一致,会导致浏览器从一个服务器上获取得页面内容后到另一台服务器上进行验证时出现Etag不匹配的情况

总结

对于强制缓存,服务器通知浏览器一个缓存时间,在缓存时间内,下次请求,直接用缓存,不在时间内,执行比较缓存策略。

对于协商缓存,将缓存信息中的EtagLast-Modified通过请求发送给服务器,由服务器校验,返回304状态码时,浏览器直接使用缓存。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容