美文网首页
前端缓存机制之http篇

前端缓存机制之http篇

作者: Yubble | 来源:发表于2018-11-04 21:35 被阅读0次

           大家好哇,这几天家里搞装修,一到周末就回家跑工地,吃苦受罪还花钱。好在我还有不得不学习的理由,是穷,是穷让我成为了一只勤奋的猿(/奋斗脸)。

           这两天重点补充了一下前端的缓存机制。缓存是个好东西啊,可以减少网络IO消耗,提高访问速度,对前端性能优化有着显著的效果。

           依在下愚见,前端的存储分为两个方向,本地缓存以及浏览器缓存。今天主要介绍一下浏览器缓存的原理。

    浏览器缓存是依赖于http协议的,所以一下就成之谓HTTP缓存

    HTTP缓存也可以分为两种,强缓存协商缓存,优先级较高的是强缓存,在命中强缓存失败的情况下,才会走协商缓存

    强缓存的实现原理:

            强缓存是利用http头中的Expires和Cache-Control两个字段来控制的。当请求“再次”发起,浏览器来检测expire和cache-control来判断目标资源是否符合强缓存,若符合则直接从缓存中获取资源,不会再与服务端发生通信。

    来看一张配图吧,我们把目光关注到Expires和Cache-Control上,这两位爷台想表达什么意思呢?

            我看过的资料中把Expires翻译成一个时间戳,其实在下看来,从字面意思理解,它就是个过期时间嘛,就像是我们超市里买的营养快线一样,都有保质期的嘛汪。所以当浏览器再次,一定是再次向服务器请求资源的时候,浏览器就会先对比本地时间和expires的保质期,如果本地时间小于expires的保质期,那么就直接去缓存中取这个资源喵。

           “那要是我把本地时间改了的话,是不是就无法达到预期的效果啦?”

           “不错!问得好,紫薇”

            在考虑到expires这个过期时间的方案不靠谱之后,HTTP1.1新增了Cache-Control来接expires的班儿。Cache-Control可以视作是expires的完全替代方案,那么它是怎么给expires干掉的呢,灯光师,来个特写来。

            各位官爷请看,在Cache-Control中,我们通过max-age来控制资源的有效期。这次我们用的不是一个时间点,而是一个时间长度,31536000代表31536000秒,在31536000秒之内不管访问几次,都是走我浏览器缓存,如果cache-control和expires同时存在,那么优先考虑cache-control。耶!

            关于Cache-Control的另一个参数public,是在告诉浏览器是否可以被代理服务器缓存,如果我们只想浏览器缓存,默认设置private便可,Cache-Control还有一个为代理浏览器服务的参数叫做s-maxage,如果两者同时出现且s-maxage未过期,则向代理服务器请求其缓存内容。在大型项目中,架构会依赖各种代理服务器,所以我们不得不去考虑代理服务器的缓存问题(这一块儿只是在下还未参透,就不在各位看官面前妄言了)。


    协商缓存的实现原理:

            前文书说到,强缓存会比协商缓存的优先级要高,这是因为协商缓存也会向服务器发送http请求的!

            协商缓存是依赖Last-Modified和Etag,他们会埋伏在响应头中,来告诉浏览器这个服务器中的资源有没有修改过呀,如果有的话从服务器中拉取最新资源,如果没有的话继续使用浏览器中缓存汪。

            Last-Modified也是个时间戳,它会在我们首次请求的时候随着Response Headers返回,告诉浏览器我们最后一次修改时间是18年六月,随后我们每次请求都会带上一个叫If-Modified-Since的时间戳字段,它的值正是上一次请求时Last-Modified的值。

            此时服务器接收到了这个时间戳,会比对该时间戳和服务器上资源的最后修改时间是否一致,如果一致则返回304状态码告诉浏览器就用缓存就好啦~

            但是!!!

            1,如果我们编辑了文件,但是并没有对文件内容做修改,Last-Modified时间戳也会变,不该重新请求的时候也去重新请求了。

            2,当我们修改文件的手速巨快,由于If-Modified-Since只能检查到以秒为最小计量单位的时间差,所以它是感知不到这个改动的,该重新请求的时候也不会重新请求了。

            所以,etag作为Last-Modified的补充就出现了。

            Etag和Last-Modified类似,当我们首次请求时,会在响应头里获取到一个最初的标识字符串,这个是服务器算出的hash值,比last-modified更准确:

            等到用户下一次请求的时候,请求头里会带上一个名为If-None-Match的值给服务器来比对,是的,这个值就是etag中取出来的

            服务器在比对了这串hash值之后就可以知道文件有没有修改过,从而是返回304还是获取最新资源了。

            但是etag的hash值在生成过程中也是需要服务器额外付出开销的,这也是他的弊端喵。


            到此为止http的缓存已经全部讲完了,在下再为各位模拟一下协商缓存中浏览器与服务器的对话哦。

    强缓存:

            场景:我访问了一下自己的网站,刷出了自己的帅照~

            浏览器:“老服,我要一张 Yabble最帅.jpg 图片,我展示用”

            服务器:“知道了,给你这个 Yabble最帅.jpg 你先用着,这货也不爱打扮,3个月之内用它都可以(cache-control: 大概3个月的秒数)。”

            场景:我立刻又访问了一次~

            浏览器:“老服,这糙货又访问了,快给我图片...诶,还没过期呀,那直接用旧的就得了呗”

    协商缓存:

            场景:我访问了一下自己的网站,刷出了自己的帅照~

            浏览器:“老服,我要一张 Yabble最帅.jpg 图片,我展示”(嘿嘿,原谅我偷懒了)

            服务器:“知道了,给你这个 Yabble最帅.jpg 你先用着,这货最近还敷上面膜了,不知道哪儿天就变小鲜肉了,给你个暗号(etag)记着点,等他哪天捯饬的不一样了我告诉你~”

            场景:我又访问了一次

            浏览器:“老服,他又访问了,快给我这糙货的图片,这是暗号(If-none-match)”

            服务器:“来,暗号给我看看,没变样嘛,还用那张旧的吧”

            场景:我面膜美颜加刮胡子之后上传替换了一张自拍照,访问网站ing~

            浏览器:“老服,他又访问了,快快,这是暗号(If-none-match)”     

            服务器:“哦哦,暗号给我来看,哟呵,和现在的照片不一样了嘿,给你新的。刷刷刷~”


            哈哈,看到这里的看官,到此为止这篇文章已经接近尾声了,原谅在下文笔拙掠,技术有限,与其说分享还是当成自己的学习笔记更贴切,现在已经到了Q4,工作压力不是一般的大,各位同行老铁注意休息,周末多出门运动,健康是多少钱都买不回来的。

    相关文章

      网友评论

          本文标题:前端缓存机制之http篇

          本文链接:https://www.haomeiwen.com/subject/kgklxqtx.html