前端缓存
- http缓存
- 强缓存
- 协商缓存
- 浏览器缓存
- cookie
- localStroage
- sessionStroage
- serviceWorker
- 离线储存
- 页面间的通信
前端缓存用来干什么?
前端缓存可以帮我们减少网络请求次数,减少流量消耗。
http缓存
- chrome disable cache 取消勾选后查看缓存情况
- 强缓存
-
浏览器自己会做一些缓存策略
-
强缓存优于协商缓存
-
强缓存中 Cache-control 优先级高于 Expries
-
第一次网络请求后,第二次请求头部有 Cache-control 字段且未过期,则从缓存取数据
-
Cache-control (相对值) / Expries(绝对值)
-
Expries是http1.0的标准
let nowTime = new Date(); nowTime.setTime(new Date().getTime() + 3600*1000); ctx.set("Expires",nowTime.toUTCString()); -
到了HTTP/1.1,Expire已经被Cache-Control替代
ctx.set("Cache-control","max-age=3600") //设置缓存时间 3600s(1)public:所有内容都将被缓存(客户端和代理服务器都可缓存)
(2)private:所有内容只有客户端可以缓存,Cache-Control的默认取值
(3)no-cache:客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定
(4)no-store:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存
(5)max-age=xxx :缓存内容将在xxx秒后失效
-
根据文件类型自动分配存储位置
-
from memory cache代表使用内存中的缓存,速度快
-
from disk cache则代表使用的是硬盘中的缓存
-
浏览器读取缓存的顺序为memory –> disk
-
网站终止,内存会清空,而硬盘中的数据不主动清除则会一直存在
-
- 协商缓存
- Last-Modify / if-Modify-Since
- ETag / if-None-Macth
- 协商缓存中 ETag / If-None-Match 优先级高于 Last-Modified / If-Modified-Since
- 是否读缓存,由服务器端决定
- 协商缓存的标识也是在响应报文的HTTP头中和请求结果一起返回给浏览器的,控制协商缓存的字段分别有:Last-Modified / If-Modified-Since和Etag / If-None-Match,其中Etag / If-None-Match的优先级比Last-Modified / If-Modified-Since高。
- 过程:Last-Modify 记录文件/接口修改时间 -> 客户端收到 response header 的 Last-Modify, 下次请求时,request header 带if-Modify-Since -> 无论如何都会发送请求,返回200或者304,服务器拿到时间后与服务器上的修改时间对比,如一致则返回304状态,此时比直接200的带宽损耗小。
- Etag / If-None-Match 与 Last-Modified / If-Modified-Since 的区别在于:
- Etag / If-None-Match : 服务端提取哈希值或者md5的摘要,更精确且时间更短
- Last-Modified / If-Modified-Since : 文件的修改时间,内容改了而时间未被修改,可能监控不到。对比服务器的时间间隔为1s
浏览器缓存
本地存储
-
cookie
-
主要功能
-
客户端与服务端之间通信
- 每次通信间会携带 (如果非必要会消耗流量)
-
本地存储
- 大小小于4k
-
设置cookie
let d = new Date(); d.setTime(d.getTime()+3600*1000); document.cookie = "uss=lisi; expires="+d.toGMTString();- 读取cookie
document.cookie- 前后端都可以设置
- 可以用来标志网络请求的状态
-
-
-
webstroage
-
localStroage(大小不大于5M,【每个浏览器大小不一定】没有过期时间)
-
本地储存
-
存储
localStroage.setItem(key,value); -
读取
localStorage.getItem('key')
-
-
利用localStroage做本地缓存
if(localStorage.getItem("test")){ let res = eval(localStorage.getItem("test")); }else{ let xhr = new XMLHttpRequest(); xhr.open("GET","./test.js",true); xhr.onload = function(){ eval(xhr.responseText); localStorage.setItem("test",xhr.responseText); } xhr.send(); }
-
-
sessionStroage
- 会话存储,提高用户体验,关闭浏览器时自动清除(整个浏览器退出)
- 接口同上
- 用途:表单填写时,如中途刷新页面,已填写的数据可以保存下来
-
-
service worker
-
拦截客户端请求,离线缓存;
-
不占用js主线程
-
针对域名存储,可存储所有东西
-
离线缓存
-
注册service worker
if ('serviceWorker' in window.navigator) { navigator.serviceWorker.register('./sw.js', { scope: './' }) .then(function (reg) { console.log('success', reg); }) .catch(function (err) { console.log('fail', err); }); } -
监听install事件将文件缓存到cache Stroage
this.addEventListener("install",function(event){ console.log('Service Worker install'); event.waitUntil( caches.open("mytest").then(cache=>{ return cache.addAll(["./a.js","./style.css","./index.html","index.js"]); }) ) }) -
拦截网络请求
this.addEventListener("fetch",event=>{ event.respondWith( caches.match(event.request).then( function (res) { return res }) ) })
-
-
页面间通信
-
注册service worker
navigator.serviceWorker.register("./messagesw.js",{scope:"./"}).then(res=>{ console.log("ServiceWorker work success"); }).catch(err=>{ console.log(err); }) -
发送消息到serviceWorker
// 发送消息到servicework document.querySelector(".btn").onclick = function(){ let value = document.querySelector(".myinp").value; // console.log(value); navigator.serviceWorker.controller.postMessage(value); } -
serviceWorker接收信息
this.addEventListener("message",function(event){ // console.log(event); var promise = this.clients.matchAll().then ( function (clientList) { var senderID = event.source ? event.source.id : 'unknown' clientList.forEach( function (client) { if (client.id == senderID) { return } else { client.postMessage({ client: senderID, message: event.data }) } }) }) event.waitUntil(promise) }) -
前端js监听消息
navigator.serviceWorker.addEventListener("message",e=>{ // console.log(e.data); let div = document.createElement("div"); div.innerHTML = `${e.data.message}`; document.querySelector("body").appendChild(div); })
-
-