前端缓存知识点汇总

最近看了几篇关于前端缓存和存储相关的文章,知识点零零散散,所以想要写个汇总

总体分为以下三个大点:
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
2
3
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./sw-demo-cache.js');
}

sw-demo-cache.js这个JS中复制如下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
var VERSION = 'v1';

// 缓存
self.addEventListener('install', function(event) {
event.waitUntil(
caches.open(VERSION).then(function(cache) {
return cache.addAll([
'./start.html',
'./static/jquery.min.js',
'./static/mm1.jpg'
]);
})
);
});

// 缓存更新
self.addEventListener('activate', function(event) {
event.waitUntil(
caches.keys().then(function(cacheNames) {
return Promise.all(
cacheNames.map(function(cacheName) {
// 如果当前版本和缓存版本不一致
if (cacheName !== VERSION) {
return caches.delete(cacheName);
}
})
);
})
);
});

// 捕获请求并返回缓存数据
self.addEventListener('fetch', function(event) {
event.respondWith(caches.match(event.request).catch(function() {
return fetch(event.request);
}).then(function(response) {
caches.open(VERSION).then(function(cache) {
cache.put(event.request, response);
});
return response.clone();
}).catch(function() {
return caches.match('./static/mm1.jpg');
}));
});

把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缓存及离线开发

欢迎随时交流~

分享到:
Disqus 加载中...

如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理