最近看了几篇关于前端缓存和存储相关的文章,知识点零零散散,所以想要写个汇总
总体分为以下三个大点:
1.浏览器缓存机制
2.前端存储方案
3.PWA的缓存处理
浏览器缓存机制
http报文
三个部分组成,CRLF隔开,消息头最后有两个CRLF
起始行
请求时–请求行; 响应时–状态行,比如 200 OK
消息头
键值对组成,CRLF隔开,最后一个有两个CRLF
消息体
字符串,长度由消息头content-length决定,
请求时,get是没有消息体的,post消息体存放表单数据
响应时,返回的json数据就放在这里的。
格式
请求报文
响应报文
强制缓存
强制缓存就是向浏览器缓存查找该请求结果
三种情况:
1.不存在该缓存结果和缓存标识,强制缓存失效,则直接向服务器发起请求(跟第一次发起请求一致)
2.存在该缓存结果和缓存标识,但该结果已失效,强制缓存失效,则使用协商缓存(暂不分析)
3.存在该缓存结果和缓存标识,且该结果尚未失效,强制缓存生效,直接返回该结果
规则
控制强制缓存的字段分别是Expires和Cache-Control,其中Cache-Control优先级比Expires高
expires
1.是HTTP/1.0控制网页缓存的字段,其值为服务器返回该请求结果缓存的到期时间;
2.是一个绝对值;
3.因为某些原因(例如时区不同;客户端和服务端有一方的时间不准确)发生误差,那么强制缓存则会直接失效
Cache-Control
1.是HTTP/1.1控制网页缓存的字段
2.是相对值
3.优先级高
协商缓存
就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程
两种情况
协商缓存生效,返回304
协商缓存失效,返回200和请求结果结果
规则
控制协商缓存的字段分别有:Last-Modified / If-Modified-Since和Etag / If-None-Match,其中Etag / If-None-Match的优先级比Last-Modified / If-Modified-Since高。
Last-Modified / If-Modified-Since
Last-Modified是服务器响应请求时,返回该资源文件在服务器最后被修改的时间
若服务器的资源最后被修改时间大于If-Modified-Since的字段值,则重新返回资源,状态码为200;否则则返回304,代表资源无更新,可继续使用缓存文件
Etag / If-None-Match
Etag是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成)
服务器会根据If-None-Match的字段值与该资源在服务器的Etag值做对比,一致则返回304,代表资源无更新,继续使用缓存文件;不一致则重新返回资源文件,状态码为200
存储位置
1.from memory cache代表使用内存中的缓存,from disk cache则代表使用的是硬盘中的缓存,浏览器读取缓存的顺序为memory –> disk
2.特点:
(1)内存缓存(from memory cache):
快速读取,时效性(一旦该进程关闭,则该进程的内存则会清空)
(2)硬盘缓存(from disk cache):
硬盘缓存则是直接将缓存写入硬盘文件中,读取缓存需要对该缓存存放的硬盘文件进行I/O操作,然后重新解析该缓存内容,读取复杂,速度比内存缓存慢。
3.具体应用:
js和图片等文件解析执行后直接存入内存缓存中,刷新页面时只需直接从内存缓存中读取(from memory cache);
而css文件则会存入硬盘文件中,每次渲染页面都需要从硬盘读取缓存(from disk cache)
小结
强制缓存优先于协商缓存进行,若强制缓存(Expires和Cache-Control)生效则直接使用缓存,若不生效则进行协商缓存(Last-Modified / If-Modified-Since和Etag / If-None-Match);
协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,重新获取请求结果,再存入浏览器缓存中;生效则返回304,继续使用缓存,主要过程如下:
前端存储方案
最常见的三个
Cookies
大小:4K
生命期:过期时间之前都可用
适用:存储登陆信息
访问权限:设置顶级域名,其下子域名可以共享
Webstorage
包括下面两种
Session Storage
大小:5M
生命期:刷新页面仍存在,其他情况都会丢失;
适用:网页音乐播放器进度条;
访问权限:本域才能用;
Local Storage
大小:5M
生命期:永久存在,除非故意删除;
访问权限:本域才能用;新开tab也能访问
重型武器 Web SQL和IndexDB
和localstorage类似,性能更好
没有大小限制
速度更快
Web SQL
现在不维护了
类似关系型数据库,用sql脚本
IndexDB
最新标准
类似no sql数据库,js方法操作
ORM库
ORM对象关系映射,把对数据库的操作转成对对象的操作,方便开发人员以面向对象的思想来实现对数据库的操作。
localforage
使用简单但功能强大的API来包装IndexedDB,WebSQL或localStorage。
可以实现前端缓存的负载均衡
PWA完成缓存的控制
Service Worker概念和特点
1.Service Worker是走的主线程之外的另一个的线程,可以理解为在浏览器背后默默运行的一个线程,脱离浏览器窗体,因此,window以及DOM都是不能访问的,此时我们可以使用self访问全局上下文
2.Service Worker设计为完全异步,同步API(如XHR和localStorage)不能在Service Worker中使用
3.必须是https协议
4.大量使用Promise,因为通常它们会等待响应后继续,并根据响应返回一个成功或者失败的操作,这些场景非常适合Promise
SW的生命周期
installing → installed → activating → activated
三个基本事件
‘install’用来缓存文件
‘activate’用来缓存更新
‘fetch’用来拦截请求直接返回缓存数据
三者齐心,构成了完成的缓存控制结构。
Cache和CacheStorage
1.Cache和CacheStorage都是Service Worker API下的接口
2.Cache直接和请求打交道,CacheStorage和Cache对象打交道
我们可以直接使用全局的caches属性访问CacheStorage
3.Cache和CacheStorage的出现让浏览器的缓存类型又多了一个:之前有memoryCache和diskCache,现在又多了个ServiceWorker cache
4.具体的增删改查API直接去官网查,Service Worker API的知识体量还是很大的
借助Service Worker和cacheStorage离线开发的固定套路
页面上注册一个Service Worker
1 | if ('serviceWorker' in navigator) { |
sw-demo-cache.js这个JS中复制如下代码
1 | var VERSION = 'v1'; |
把cache.addAll()方法中缓存文件数组换成你希望缓存的文件数组
恭喜你,简单3步曲,复制、粘贴、改路径。你的网站已经支持Service Worker缓存,甚至离线也可以自如访问,支持各种网站,PC和Mobile通杀,不支持的浏览器没有任何影响,支持的浏览器天然离线支持,想要更新缓存,v1换成v2就可以,so easy!。
PWA的核心技术
- Web App Manifest – 在主屏幕添加app图标,定义手机标题栏颜色之类
- Service Worker – 缓存,离线开发,以及地理位置信息处理等
- App Shell – 先显示APP的主结构,再填充主数据,更快显示更好体验
- Push Notification – 消息推送
参考文章:
掘金: 小哥哥,小姐姐,我有一份tcp、http面试指南你要吗?
前端早读课: 彻底理解浏览器的缓存机制
segmentfault: [聊一聊系列]聊一聊前端存储那些事儿
张鑫旭的博客: 借助Service Worker和cacheStorage缓存及离线开发
欢迎随时交流~
如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理