-
Notifications
You must be signed in to change notification settings - Fork 3
使用信息
在 README 中我们了解了一个最简单的配置文件所具备的要素,这里将做一些深入讨论。
因为支持多条规则,因此 routers
是一个由对象构成的数组。其中每个对象可以包含 method
, urlPattern
, strategy
, validate
四个属性。这里要重点讲一下 urlPattern
属性, validate
将放在最后讲述。
urlPattern
通常是一个正则表达式,用以匹配静态文件的 URL 。但它也可以是一个方法,参数为 request
,返回 true/false
来给出匹配结果。这主要是为了满足模块根据不同请求来动态确定是否需要读取缓存,也是对正则表达式的一个扩展,例如下面的配置:
{
method: 'get',
urlPattern(request) {
if (request.xxx) {
reutrn /some\/path/.test(request.url);
}
else {
return false;
}
},
strategy: 'fastest',
validate: [...]
}
在使用方法的情况下,对应的 validate
数组中的对象将不在提供 url
属性,而是提供可以通过验证的 request
对象,供检查代码使用。
通过 routers
的配置,service-worker 可以在 fetch
阶段进行资源的匹配和缓存策略的应用。而这样带来的问题是,第一次访问时缓存里并没有目标对象,所以首次访问就一定需要通过网络请求进行 (cacheOnly
除外), 使得缓存策略不够“完美”。
对于这些我们已知一定会被访问的且希望提升访问速度的静态资源,我们应当采取 precache
的方式,在 install
阶段即进行缓存,这样来到 fetch
时可以直接读取缓存。
precache
的配置方法也很简单,直接将需要的资源路径以__字符串__的形式写在数组里即可,这里__不__支持正则表达式。
export default {
name: 'xxx',
urlPattern: /xxx/,
routers: [...],
precache: [
'/news/static/cacheFirst.js',
'/news/static/main.css'
]
}
要特别注意的是,所有 precache
配置的资源路径__必须__匹配之前配置的 routers
中的某一条,否则会被忽略。
crater 内置了 5 种 请求-缓存 策略供开发者使用:
- networkFirst
网络请求优先。对于匹配该策略的请求,Service Worker 会优先从网络获取,如果成功,将请求内容返回并保存/更新 到 Cache Strorage 中。如果网络请求失败,则去 Cache Storage 中进行匹配读取,返回缓存的内容。需要注意的是,如果配置了 options.timeout
参数,网络请求会在大于这个超时时间后,直接去读取缓存,避免出现弱网环境一直等待服务器超时的情况出现。
- cacheFirst
缓存优先。优先去匹配缓存中的内容,匹配成功即返回,若失败则进行网络请求,返回请求结果并更新至缓存列表。适用于固定不变的静态资源。如果配置了 options.cache.maxAge
,将只会返回在此有效期内的缓存内容。
- fastest
快速优先。同时进行网络请求和缓存读取,返回两者中较快的。在缓存中有匹配内容的情况下,这种策略通常都是缓存读取较快。但同时网络请求也会进行,并将最新的内容更新至缓存列表,保证下一次访问时,缓存返回的内容相对较新。
- cacheOnly
只读缓存。始终匹配读取缓存,不进行网络请求,如果匹配失败则抛出错误,请求失败。如果配置了 options.cache.maxAge
,将只会返回在此有效期内的缓存内容。
- networkOnly
只进行网络请求。始终只进行网络请求,若失败也不去读取缓存。与正常请求行为表现一致。
感谢 sw-toolbox 的实践,sw 参考了缓存策略的部分实现。
crater 还支持一些额外的配置项。它们分别是:
-
timeout
:number
类型,单位毫秒(ms),默认值3000。用于对网络请求增加一个超时限制。如networkFirst
策略中一旦网络请求超过这个时长,则读取缓存并返回。 -
cache.maxEntries
:number
类型,默认值50。表示单个模块的缓存数量最大值,多于这个值会采取 LRU 策略进行淘汰。 -
cache.maxAge
:number
类型,单位毫秒(ms),默认值 24 * 60 * 60 * 1000。表示单个模块的缓存最长时间,过期的缓存将会被清除。在配合上述各种策略使用时,此参数将在读取缓存内容时起作用,不会返回此有效期外的缓存内容。
一个示例写法如下:
export default {
name: 'xxx',
urlPattern: /xxx/,
routers: [...],
options: {
timeout: 5000,
cache: {
maxEntries: 30,
maxAge: 60 * 60 * 1000
}
}
}
因为配置文件是由各模块自行编写,加之最终生成的 service-worker.js
是把各模块的配置融合到一起,因此需要最大限度的保证配置文件的合法性和互相隔离,避免互相影响产生不可预知的问题。
crater 提供了一个内置的检查工具,可以通过运行命令 npm run validate
发起检查,检查结果会在命令行直接展示。
检查主要分为两大类:内部检查和交叉检查。
-
内部检查
- 检查每条
validate
是否能被urlPattern
匹配,如不能则报错 - 检查每条
precache
是否能被urlPattern
匹配,如不能则报错
- 检查每条
-
交叉检查 (两两比对)
- 检查两个配置文件的
name
是否相同,如相同则报错 - 检查配置A的每条
validate url
是否能被配置B的urlPattern
匹配,如能则报错
- 检查两个配置文件的
'use strict';
export default {
name: 'news',
// referrer url patterns
urlPattern: /news/,
routers: [
{
method: 'get',
// static file url patterns
urlPattern: /news\/static\/cache.*\.js$/,
strategy: 'cacheFirst',
validate: [{
url: '/news/static/cache.js'
}]
},
{
method: 'get',
urlPattern(request) {
if (!request.referrer) {
return true;
}
return /news\/static\/fast.*\.js$/.test(request.url);
},
strategy: 'fastest',
validate: [{
request: {
url: '/news/static/fat.js'
}
}, {
request: {
url: '/news/static/faster.js',
referrer: 'http://somewhere'
}
}, {
request: {
url: '/news/static/fastest.js',
referrer: 'http://somewhere/else'
}
}]
},
{
method: 'get',
urlPattern: /news\/static\/main\.css$/,
strategy: 'networkFirst',
validate: [{
url: '/news/static/main.css'
}]
},
{
method: 'get',
urlPattern: /news\/static\/jquery.js$/,
strategy: 'networkOnly',
validate: [{
url: '/news/static/jquery.js'
}]
}
],
precache: [
'/news/static/cache.js',
'/news/static/main.css'
],
options: {
timeout: 5000,
cache: {
maxEntries: 30,
maxAge: 1000 * 60 * 60 * 24
}
}
};
crater 中还集成了一些其他命令,如下:
- npm run lint
使用依赖的 fecs
进行代码检查。
- npm run test
这是对 crater 的缓存策略,路由匹配和预缓存等内部代码进行单测的命令,一般开发者不必关注。此外它只支持 Linux 和 Mac OS 系统,因此在 Windows 运行失败是正常情况。