前端缓存

前端缓存

http缓存

Expires

HTTP1.0的内容,服务器使用Expires头来告诉Web客户端它可以使用当前副本,直到指定的时间为止。 

Cache-Control

HTTP1.1引入了Cathe-Control,它使用max-age指定资源被缓存多久,主要是解决了Expires一个重大的缺陷,就是它设置的是一个固定的时间点,客户端时间和服务端时间可能有误差。

Last-Modified / If-Modified-Since

Last-Modified是服务器告诉浏览器该资源的最后修改时间,If-Modified-Since是请求头带上的,上次服务器给自己的该资源的最后修改时间。然后服务器拿去对比。

若资源的最后修改时间大于If-Modified-Since,说明资源又被改动过,则响应整片资源内容,返回状态码200;

若资源的最后修改时间小于或等于If-Modified-Since,说明资源无新修改,则响应HTTP 304,告知浏览器继续使用当前版本。 

Etag / If-None-Match

前面提到由文件的修改时间来判断文件是否改动,还是会带来一定的误差,比如注释等无关紧要的修改等。所以推出了新的方式。

Etag是由服务端特定算法生成的该文件的唯一标识,而请求头把返回的Etag值通过If-None-Match再带给服务端,服务端通过比对从而决定是否响应新内容。这也是304缓存。

浏览器缓存

Storage

简单的缓存方式有cookie,localStorage和sessionStorage。 

前端数据库

前端数据库有WebSql和IndexDB,其中WebSql被规范废弃,他们都有大约50MB的最大容量,可以理解为localStorage的加强版。 

应用缓存 -- PWA

应用缓存主要是通过manifest文件来注册被缓存的静态资源,已经被废弃,因为他的设计有些不合理的地方,他在缓存静态文件的同时,也会默认缓存html文件。这导致页面的更新只能通过manifest文件中的版本号来决定。所以,应用缓存只适合那种常年不变化的静态网站。如此的不方便,也是被废弃的重要原因。

PWA也运用了该文件,不同于manifest简单的将文件通过是否缓存进行分类,PWA用manifest构建了自己的APP骨架,并运用Servie Worker来控制缓存

Service Worker

简述

浏览器支持情况:

通俗来说,PWA就是渐进式web应用(Progressive Web App),service worker做为PWA的核心技术之一,多年来一直被Google大力推广。

- 基于web worker(一个独立于JavaScript主线程的独立线程,在里面执行需要消耗大量资源的操作不会堵塞主线程) 

- 在web worker的基础上增加了离线缓存的能力

- 本质上充当Web应用程序(服务器)与浏览器之间的代理服务器(可以拦截全站的请求,并作出相应的动作->由开发者指定的动作)

- 创建有效的离线体验(将一些不常更新的内容缓存在浏览器,提高访问体验)

- 由事件驱动的,具有生命周期

- 可以访问cache和indexDB

- 支持推送

- 并且可以让开发者自己控制管理缓存的内容以及版本

生命周期:

1、register -- 注册

navigator.serviceWorker判断浏览器是否支持serviceWorker,

register注册sw,

scope 指定sw作用路由,

 registration.update  更新sw,

registration.unregister 卸载sw

2、install 

install 事件是 SW 触发的第一个事件,并且仅触发一次。

installEvent.waitUntil()接收一个 Promise 参数,用它来表示 SW 安装的成功与否。

SW 在安装成功并激活之前,不会响应 fetch或push等事件。

默认情况下,页面的请求(fetch)不会通过 SW,除非它本身是通过 SW 获取的,也就是说,在安装 SW 之后,需要刷新页面才能有效果。

clients.claim()可以改变这种默认行为

3、active 

如果是第一次加载sw,在安装后,会直接进入activated阶段,而如果sw进行更新,情况就会显得复杂一些。流程如下:

首先老的sw为A,新的sw版本为B。

B进入install阶段,而A还处于工作状态,所以B进入waiting阶段。只有等到A被terminated后,B才能正常替换A的工作。


更新sw

这个terminated的时机有如下几种方式:

1   关闭浏览器一段时间;2   手动清除Service Worker;3   在sw安装时直接跳过waiting阶段.

4、idle

这个空闲状态一般是不可见的,这种一般说明sw的事情都处理完毕了,然后处于闲置状态了。浏览器会周期性的轮询,去释放处于idle的sw占用的资源。

5、fetch

该阶段是sw最为关键的一个阶段,用于拦截代理所有指定的请求,并进行对应的操作。

Workbox

简述

在 Workbox 之前,GoogleChrome 团队较早时间推出过 sw-precache 和 sw-toolbox 库,但是在 GoogleChrome 工程师们看来,Workbox 才是真正能方便统一的处理离线能力的更完美的方案,所以停止了对 sw-precache 和 sw-toolbox 的维护。

配置

首先,需要在项目的sw.js文件中,引入Workbox的官方js,其中importScripts是webworker中加载js的方式。

引入Workbox后,全局会挂载一个Workbox对象,也可以统一指定存储时Cache的名称,如下:

importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.0.0-alpha.3/workbox-sw.js');

if (workbox) {

    console.log('workbox加载成功');

} else {

console.log('workbox加载失败');

}

//设置缓存cachestorage的名称

workbox.core.setCacheNameDetails({

prefix:'workbox-test',

suffix:'v2

'});

workbox.precaching.precacheAndRoute([

{ url: './styles/workbox.css', revision: '2' }, { url: './workbox', revision: '2' }

]);

precache (预缓存) 静态文件

Workbox的缓存分为两种,一种的precache,一种的runtimecache。

工作原理

首次加载Web应用程序时,Workbox会下载指定的资源,并存储具体内容和相关修订的信息在indexedDB中。

当资源内容和sw.js更新后,Workbox会去比对资源,然后将新的资源存入Cache,并修改indexedDB中的版本信息。

这个时候我们把main.css的内容改变后,再刷新页面,会发现除非强制刷新,否则Workbox还是会读取Cache中存在的老的main.css内容。

即使我们把main.css从服务器上删除,也不会对页面造成影响。

所以这种方式的缓存都需要配置一个版本号

workbox.precaching.precacheAndRoute([   

  {

        url: './styles/workbox.css', 

       revision: '4'

    },

]);

runtimecache路由请求缓存

路由请求缓存是通过文件路由匹配的模式分别对制定的路由文件做不同策略缓存的方式,这部分工作可以在 app/sw.js 中直接使用 workbox 提供的 workbox.routing.registerRoute API 完成,这个 API 可以理解为干了两件事情,一、通过请求路由配置匹配到指定待缓存文件或请求内容二、通过第二个参数的处理回调函数决定用何种策略来缓存匹配上的文件

有 三种 方法可以通过 workbox-route 来匹配一个请求 URL

1字符串方式,

workbox.routing.registerRoute( './imgs/logo.jpeg', handler);

workbox.routing.registerRoute( 'http://localhost:3000/imgs/logo.jpeg', handler);

2正则表达式方式,

workbox.routing.registerRoute(new RegExp('.*\.logo.jpeg'), handler);

3回调函数方式

const matchFunction = ({url, event}) => /imgs/.test(url));

workbox.routing.registerRoute(matchFunction, handler);

三种方式匹配的资源怎么处理呢?配置handler,通常两种做法

1使用一种 workbox 通过workbox.strategiesAPI 提供的缓存策略

2提供一个自定义返回带有返回结果的 Promise 的回调方法。

Stale While Revalidate

这种策略的意思是当请求的路由有对应的 Cache 缓存结果就直接返回,在返回 Cache 缓存结果的同时会在后台发起网络请求拿到请求结果并更新 Cache 缓存,如果本来就没有 Cache 缓存的话,直接就发起网络请求并返回结果,这对用户来说是一种非常安全的策略,能保证用户最快速的拿到请求的结果,但是也有一定的缺点,就是还是会有网络请求占用了用户的网络带宽。可以像如下的方式使用State While Revalidate策略:

workbox.routing.registerRoute(

    '/imgs/logo.jpeg',

    workbox.strategies.staleWhileRevalidate()

);

Network First

这种策略就是当请求路由是被匹配的,就采用网络优先的策略,也就是优先尝试拿到网络请求的返回结果,如果拿到网络请求的结果,就将结果返回给客户端并且写入 Cache 缓存,如果网络请求失败,那最后被缓存的 Cache 缓存结果就会被返回到客户端,这种策略一般适用于返回结果不太固定或对实时性有要求的请求,为网络请求失败进行兜底。可以像如下方式使用Network First策略:

workbox.routing.registerRoute(

    '/imgs/logo.jpeg',

    workbox.strategies.networkFirst()

);

Cache First

这个策略的意思就是当匹配到请求之后直接从 Cache 缓存中取得结果,如果 Cache 缓存中没有结果,那就会发起网络请求,拿到网络请求结果并将结果更新至 Cache 缓存,并将结果返回给客户端。这种策略比较适合结果不怎么变动且对实时性要求不高的请求。可以像如下方式使用 Cache First 策略:

workbox.routing.registerRoute(

    '/imgs/logo.jpeg',

    workbox.strategies.cacheFirst()

);

Network Only

比较直接的策略,直接强制使用正常的网络请求,并将结果返回给客户端,这种策略比较适合对实时性要求非常高的请求。可以像如下方式使用Network Only策略

workbox.routing.registerRoute(

    '/imgs/logo.jpeg',

    workbox.strategies.networkOnly()

);

Cache Only

这个策略也比较直接,直接使用 Cache 缓存的结果,并将结果返回给客户端,这种策略比较适合一上线就不会变的静态资源请求。可以像如下方式使用Cache Only策略:

workbox.routing.registerRoute(

    '/imgs/logo.jpeg',

    workbox.strategies.cacheOnly()

);

自定义策略

如果以上的那些策略都不太能满足你的请求的缓存需求,那就得想想办法自己定制一个合适的策略,甚至是不同情况下返回不同的请求结果,workbox 也考虑到了这种场景

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容

  • 前端缓存是我们前端开发中, 缓存是不可避免的知识点, 最近在复习缓存的知识, 整理了一下浏览器所有缓存类型, 希望...
    种草林阅读 1,267评论 0 0
  • 浏览器端的缓存规则 对于浏览器端的缓存来讲,这些规则是HTTP协议头和HTML页面的Meta标签中定义的。他们分别...
    niklause_sun阅读 4,897评论 0 7
  • 一图看懂前端缓存 好了,话不多说,今天主要说说HTTP缓存 (一)使用缓存的优点: 减少冗余数据的传输 节省网络费...
    yun_154192阅读 977评论 0 0
  • 大家都知道缓存的英文叫做 cache。但我发现一个有趣的现象:这个单词在不同人的口中有不同的读音。为了全面了解缓存...
    秋风_bdfd阅读 2,099评论 0 3
  • 缓存分类查看浅谈前端缓存类型之http缓存[https://www.jianshu.com/p/54f329f7e...
    曲昶光阅读 1,163评论 0 3