大家好,明人不说暗话,我叫富婆(未来的,要对我抱有希望哦),富婆每天优哉游哉的敲着代码,日子过得贼舒服,但是近日掐指一算,冥冥之中有神明指引着我,你离富婆的日子不远啦,只要你每天写文章,马上就会成为富婆的,按着神明的指引这次准备给自己立个flag《持续写作30天》。写一些文章来整理一些最近学习的东西,还有一些自己的知识盲点。
进入正题,这次我们来讲一下关于前端缓存的问题。
看图说话
前端缓存有3大种:如图,分为HTTP缓存、浏览器缓存、应用程序缓存。
1.HTTP缓存
分为强缓存与协商缓存。
1.强缓存
强缓存之Expires:
(1)值为服务端返回的到期时间,即下一次请求时,请求时间小于服务端返回的到期时间,直接使用缓存数据;
(2)到期时间是由服务端生成的,客户端时间跟服务端时间可能存在误差,这就会导致缓存命中的误差;
(3)被Cache-Control替代;
强缓存之Cache-Control:
来举个栗子:
图中Cache-Control仅指定了max-age,所以默认为private,缓存时间为31536000秒(365天) 也就是说,在365天内再次请求这条数据,都会直接获取缓存数据库中的。
2.协商缓存:(相当于就是浏览器与服务器通过一个值作为更新flag,一个协商一个判断)
协商缓存之Etag/If-None-Match:
(1)当浏览器请求服务器的某项资源(A)时,服务器会根据A算出一个哈希值,并通过Etag返回给浏览器,浏览器把ETAG和资源A同时缓存到本地。
(2)当下次向服务器请求该资源时,会通过If-None-Match把ETAG发送给服务器。
(3)服务器再次计算A的哈希值并和浏览器的返回值作比较,如果A发生了变化就把A返回给浏览器(返回值200),如果未发生变化就返回浏览器304(未修改)
协商缓存之Last-Modified/If-Modified-Since:
(1)在浏览器请求服务器的某项资源时,返回资源的同时还有一个Last-Modified的属性标记此文件在服务器端的最后修改时间;(2)浏览器第二次访问该资源时,会向服务器传送If-Modified-Since报头,询问该时间之后文件是否被修改过;
(3)如果服务器的资源没有变化,则时间一致,返回304的状态吗,浏览器使用本地缓存;
(4)如果时间不一致,返回200,显示新文件并缓存。
那么Etag和Last-Modified,他们之间有什么区别呢???
-
Etag是标识传输,Last-Modified是时间传输;
-
Etag的优先级高于Last-Modified;
-
Last-modified标注的最后修改时间只能精确到秒,如果文件在1秒以内被多次修改,它不能准确标注文件的最后修改时间;
-
如果文件定期生成,但内容没有任何变化,但是last-modified却改变了,导致没法使用缓存;
-
有可能存在服务器没有准确获取文件修改时间,或与代理服务器时间不一致的情况;
-
etag每次服务端生成都需要进行读写操作,而last-modified只需要读取操作,etag消耗更大些;
各有优劣!
那强缓存与协商缓存,他们的规则分别是什么?
强缓存规则:
- 已失效时,请求服务器,服务器返回数据和缓存规则,客户端将数据和缓存规则存入缓存数据库;
- 未失效时,请求缓存数据库,返回数据并渲染;
协商缓存规则:
- 先到缓存数据库中获取标识Etag/Last-Modified,
- 再通过If-None-Match/If-Modified-Since字段带上缓存标识请求服务器,服务器判断内容是否失效;
这两种缓存的执行流程是怎么样的?
- 强缓存未失效,从缓存中读取数据,cache-control优先级高于Expires;
- 强缓存已失效,执行协商缓存,Etag的优先级高于last-Modified;
- 缓存未失效从缓存中读取数据返回304状态码;
- 缓存已失效返回资源和200状态码;
怎么清除缓存?
- 浏览器默认会缓存图片,css和js等静态资源,所以开发环境下经常会因为强缓存导致资源没有及时更新而看不到最新的效果,需要清除缓存可以使用一下几种方法:
- 直接ctrl+f5,这个办法能解决页面直接引用的资源更新的问题;
- 使用ctrl+shift+delete清除缓存;
- 如果用的是chrome,可以F12在network那里把缓存给禁掉,选中“disable Cache”: 或者给资源文件加一个时间戳;
- 或者禁止修改html中的缓存字段为禁止使用;
- 或者在谷歌浏览器刷新按钮上,点击右键,选择“清空缓存并硬性重新加载”;
2.浏览器缓存
这个前端很多时候会用到
有本地小容量存储与本地大容量存储
1.小容量的使用场景
(1)小容量的Cookie:
记住用户名密码,欢迎语
(2)小容量的LocalStorage:
记录后只要不手动清除就会一直存在。
(3)小容量的SessionStorage:
仅在本次会话时有效。关闭当然窗口后就没有了。
Storage的API如下:
(以localStorage为例,sessionStorage一样)
(1)保存数据:(3种写法均可)
写法1:
localStorage.setItem("key",value)
写法2:
localStorage["key"]=1
写法3:
localStorage.key=1
(2)读取数据:(相对也有3种) 写法1:
var value=localStorage.getItem("key")
写法2:
var value=localStorage["key"]
写法3:
var value=localStorage.key
(3)删除单个数据:
localStorage.removeItem(key);
(4)删除所有数据:
localStorage.clear();
(5)得到某个索引的key:
localStorage.key(index);
比较一下Cookie、LocalStorage、sessionStorage的异同:
- cookie会在在同源的http请求中携带,不能超过4K,参与和服务器交互;
- sessionStorge和locaStorage保存数据在本地,限制最多5M,不参与和服务器交互;
- sessionStorage仅在当前窗口关闭前有效;
- localstorage会一直保存在浏览器中,除非手动删除;
- cookie在设置过期时间之前一直有效,不设置过期时间窗口关闭则清除;
- sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面,
- localstorage和cookie在所有同源窗口中共享
本地大容量存储之WebSql:
表保存数据,用sql操作数据库(写的是sql语句,懂mysql数据库的完全不在话下)
- 创建表:
create table if not exists product(id integer primary key autoincrement,name text not null,price double);
- 添加一条数据:
insert into product(name,price) values('斗战圣皇','1.2');
insert into product(name,price) values('布衣神探:最后的证据','0.9');
- 删除一条数据:
delete from product where id=2;
- 更新一条数据:
update product set name='斗战圣皇第二部',price='0.99' where id=1;
- 查询表格:
select * from product;
- 删除表格:
drop table IF EXISTS product;
2.本地大容量存储
1.本地大容量存储之IndexDB:
- 保存的是对象类型的数据
- open()打开或创建数据库
- deleteDatabase()删除数据库;
- transaction()打开事物
- add()添加数据
- get()查找数据
- delete()根据ID删除数据
- clear()清除全部数据
3.应用程序缓存
分为应用缓存和PWA
1.应用缓存
HTML5 引入了应用程序缓存,这意味着 web 应用可进行缓存,并可在没有因特网连接时进行访问。
应用程序缓存为应用带来三个优势:
(1)离线浏览 - 用户可在应用离线时使用它们
(2)速度 - 已缓存资源加载得更快
(3)减少服务器负载 - 浏览器将只从服务器下载更新过或更改过的资源。
2.PWA
在了解pwa前先了解一下APP和web网页存在的一些不足:
(1)APP应用存在的不足:
-
开发成本高(IOS和安卓)
-
软件上线需要审核
-
版本更新需要上传到应用商店
-
想使用APP必须下载
(2)web网页存在的不足:
-
手机桌面入口不够便捷,需要记住URL或加入书签
-
不能像APP一样推送消息
PWA弥补了APP和web网页存在的一些缺点:
-
是一个web网页应用
-
可以添加至主屏幕,点击主屏幕的图标可以实现启用动画以及隐藏地址栏
-
实现了离线缓存功能,即使手机没有网络,依然可以实现一些离线功能
-
实现了消息推送
举个栗子
今天就暂时写这么多啦,嘻嘻嘻(手动狗头)
本人资历尚浅,如有不对的地方,希望大佬指正,共同学习,共同进步
关注富婆的公众号,带你一起学前端,早日走上人生巅峰,迎娶白富美,抱住富婆的大腿!!!