浏览器缓存原理以及本地存储

9次阅读

共计 4373 个字符,预计需要花费 11 分钟才能阅读完成。

作为一名前端工作人员,前端的缓存知识是必须掌握的,因为一个网站打开网页的速度直接关系到用户体验,用户粘度,而提高网页的打开速度有很多方面需要优化,其中比较重要的一点就是利用好缓存,缓存文件可以重复利用,还可以减少带宽,降低网络负荷。
1 缓存
缓存从宏观上分为私有缓存和共享缓存,共享缓存就是那些能被各级代理缓存的缓存。私有缓存就是用户专享的,各级代理不能缓存的缓存。
缓存从微观上可以分为以下几类:

浏览器缓存
代理服务器缓存
CDN 缓存
数据库缓存
应用层缓存

这里主要对浏览器的缓存进行说明:

2 http 缓存
2.1 强缓存

不会向服务器发送请求,直接从缓存中读取资源
请求返回 200 的状态码
在 chrome 控制台的 network 选项中可以看到 size 显示 from disk cache 或 from memory cache。

from memory cache 代表使用内存中的缓存,from disk cache 则代表使用的是硬盘中的缓存,浏览器读取缓存的顺序为 memory –> disk。在浏览器中,浏览器会在 js 和图片等文件解析执行后直接存入内存缓存中,那么当刷新页面时只需直接从内存缓存中读取(from memory cache);而 css 文件则会存入硬盘文件中,所以每次渲染页面都需要从硬盘读取缓存(from disk cache)。

Expires 和 Cache-Control 两者对比:其实这两者差别不大,区别就在于 Expires 是 http1.0 的产物,Cache-Control 是 http1.1 的产物,两者同时存在的话,Cache-Control 优先级高于 Expires
2.2 协商缓存
协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程
协商缓存生效,返回 304 和 Not Modified

2.2.1 Last-Modified 和 If-Modified-Since
浏览器在第一次访问资源时,服务器返回资源的同时,在 response header 中添加 Last-Modified 的 header,值是这个资源在服务器上的最后修改时间,浏览器接收后缓存文件和 header;
浏览器下一次请求这个资源,浏览器检测到有 Last-Modified 这个 header,于是添加 If-Modified-Since 这个 header,值就是 Last-Modified 中的值;服务器再次收到这个资源请求,会根据 If-Modified-Since 中的值与服务器中这个资源的最后修改时间对比,如果没有变化,返回 304 和空的响应体,直接从缓存读取,如果 If-Modified-Since 的时间小于服务器中这个资源的最后修改时间,说明文件有更新,于是返回新的资源文件和 200
缺点:1、某些服务端不能获取精确的修改时间 2、文件修改时间改了,但文件内容却没有变
2.2.2 ETag 和 If-None-Match
Etag 是上一次加载资源时,服务器返回的 response header,是对该资源的一种唯一标识,只要资源有变化,Etag 就会重新生成。浏览器在下一次加载资源向服务器发送请求时,会将上一次返回的 Etag 值放到 request header 里的 If-None-Match 里,服务器只需要比较客户端传来的 If-None-Match 跟自己服务器上该资源的 ETag 是否一致,就能很好地判断资源相对客户端而言是否被修改过了。如果服务器发现 ETag 匹配不上,那么直接以常规 GET 200 回包形式将新的资源(当然也包括了新的 ETag)发给客户端;如果 ETag 是一致的,则直接返回 304 知会客户端直接使用本地缓存即可。
2.2.3 协商缓存两种方式的对比

首先在精确度上,Etag 要优于 Last-Modified,Last-Modified 的时间单位是秒,如果某个文件在 1 秒内改变了多次,那么他们的 Last-Modified 其实并没有体现出来修改,但是 Etag 每次都会改变确保了精度;如果是负载均衡的服务器,各个服务器生成的 Last-Modified 也有可能不一致。
性能上,Etag 要逊于 Last-Modified,毕竟 Last-Modified 只需要记录时间,而 Etag 需要服务器通过算法来计算出一个 hash 值。
优先级上,服务器校验优先考虑 Etag

3 缓存机制
appcache 优先于强缓存,强制缓存优先于协商缓存进行,若强制缓存 (Expires 和 Cache-Control) 生效则直接使用缓存,若不生效则进行协商缓存(Last-Modified / If-Modified-Since 和 Etag / If-None-Match),协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,返回 200,重新返回资源和缓存标识,再存入浏览器缓存中;生效则返回 304,继续使用缓存。具体流程看下图:

不管是浏览器缓存,还是代理服务器缓存,CDN 缓存都遵循客户端与服务端之间的缓存机制
4、本地存储
本地存储主要有以下几种,localStorage,sessionStorage 和 cookie,WebSql 和 IndexDB 主要用在前端有大容量存储需求的页面上,例如,在线编辑浏览器或者网页邮箱。他们都可以将数据存储在浏览器,应该根据不同的场景进行使用。
4.1 Cookie
Cookie 主要是由服务器生成,且前端也可以设置,保存在客户端本地的一个文件,通过 response 响应头的 set-Cookie 字段进行设置,且 Cookie 的内容自动在请求的时候被传递给服务器。如下:
[HTTP/1.1 200 OK]
Server:[bfe/1.0.8.18]
Etag:[“58860415-98b”]
Cache-Control:[private, no-cache, no-store, proxy-revalidate, no-transform]
Connection:[Keep-Alive]
Set-Cookie:[BDORZ=27315; max-age=86400; domain=.baidu.com; path=/]
Pragma:[no-cache]
Last-Modified:[Mon, 23 Jan 2017 13:24:37 GMT]
Content-Length:[2443]
Date:[Mon, 09 Apr 2018 09:59:06 GMT]
Content-Type:
Cookie 包含的信息:它可以记录你的用户 ID、密码、浏览过的网页、停留的时间等信息。当你再次来到该网站时,网站通过读取 Cookies,得知你的相关信息,就可以做出相应的动作,如在页面显示欢迎你的标语,或者让你不用输入 ID、密码就直接登录等等。一个网站只能读取它自己放置的信息,不能读取其他网站的 Cookie 文件。因此,Cookie 文件还保存了 host 属性,即网站的域名或 ip。这些属性以名值对的方式进行保存,为了安全,它的内容大多进行了加密处理。Cookie 文件的命名格式是:用户名 @网站地址[数字].txt
Cookie 的优点:

给用户更人性化的使用体验,如记住“密码功能”、老用户登录欢迎语
弥补了 HTTP 无连接特性
站点统计访问人数的一个依据

Cookie 的缺点:

它无法解决多人共用一台电脑的问题,带来了不安全因素
Cookie 文件容易被误删除
一人使用多台电脑
Cookies 欺骗。修改 host 文件,可以非法访问目标站点的 Cookie
数量和长度有限制,最多 20 条,最长不能超过 40k
在请求头上带着数据安全性差

4.2 localStorage
localStorage 主要是前端开发人员,在前端设置,一旦数据保存在本地后,就可以避免再向服务器请求数据,因此减少不必要的数据请求,减少数据在浏览器和服务器间不必要地来回传递。
可以长期存储数据,没有时间限制,一天,一年,两年甚至更长,数据都可以使用。localStorage 中一般浏览器支持的是 5M 大小,这个在不同的浏览器中 localStorage 会有所不同
优点:

localStorage 拓展了 cookie 的 4k 限制
localStorage 可以将第一次请求的 5M 大小数据直接存储到本地,相比于 cookie 可以节约带宽
localStorage 的使用也是遵循同源策略的,所以不同的网站直接是不能共用相同的 localStorage

缺点:

需要手动删除,否则长期存在
浏览器大小不一,版本的支持也不一样
localStorage 只支持 string 类型的存储,JSON 对象需要转换
localStorage 本质上是对字符串的读取,如果存储内容多的话会消耗内存空间,会导致页面变卡

4.3 sessionStorage
sessionStorage 主要是前端开发人员,在前端设置,sessionStorage(会话存储),只有在浏览器被关闭之前使用,创建另一个页面时同意可以使用,关闭浏览器之后数据就会消失
存储上限限制:不同的浏览器存储的上限也不一样,但大多数浏览器把上限限制在 5MB 以下
4.4 websql
Web SQL 是在浏览器上模拟数据库,可以使用 JS 来操作 SQL 完成对数据的读写。它使用 SQL 来操纵客户端数据库的 API,这些 API 是异步的,规范中使用的方言是 SQLlite。数据库还是在服务端,不建议使用,已废弃
4.5 indexDB
随着浏览器的功能不断增强,越来越多的网站开始考虑,将大量数据储存在客户端,这样可以减少从服务器获取数据,直接从本地获取数据。
现有的浏览器数据储存方案,都不适合储存大量数据:Cookie 的大小不超过 4KB,且每次请求都会发送回服务器;LocalStorage 在 2.5MB 到 10MB 之间(各家浏览器不同),而且不提供搜索功能,不能建立自定义的索引。所以,需要一种新的解决方案,这就是 IndexedDB 诞生的背景。
通俗地说,IndexedDB 就是浏览器提供的本地数据库,它可以被网页脚本创建和操作。IndexedDB 允许储存大量数据,提供查找接口,还能建立索引。这些都是 LocalStorage 所不具备的。就数据库类型而言,IndexedDB 不属于关系型数据库(不支持 SQL 查询语句),更接近 NoSQL 数据库。
关于 indexDB 的知识可以查看这篇文章 http://www.ruanyifeng.com/blo…
这里,我只是根据自己的理解整理了一下关于缓存,存储方面的知识,还有很多不足的地方,更多实践的知识,还请查看其他文章,如有错误,请指出
参考文章:https://www.jianshu.com/p/54c…https://segmentfault.com/a/11…http://www.cnblogs.com/etoah/…https://blog.csdn.net/zhouche…

正文完
 0