在我们开首写码在此以前
从这个类型地址拿到chaches
polyfill。
这个polyfill支持CacheStorate.match,Cache.add和Cache.addAll,而现在Chrome
M40实现的Cache
API还尚无帮衬那么些办法。
将dist/serviceworker-cache-polyfill.js放到你的网址中,在service
worker中经过importScripts加载进来。被service
worker加载的脚本文件会被机关缓存。
JavaScript
importScripts(‘serviceworker-cache-polyfill.js’);
1
|
importScripts(‘serviceworker-cache-polyfill.js’);
|
需要HTTPS
在开发阶段,你能够透过localhost使用service
worker,不过倘诺上线,就供给您的server扶助HTTPS。
你可以通过service
worker威逼连接,伪造和过滤响应,13分逆天。即便你能够约束本身不干坏事,也会有人想干坏事。所以为了预防外人使坏,你不得不在HTTPS的网页上登记service
workers,那样我们才得以预防加载service
worker的时候不被歹徒篡改。(因为service
worker权限非常大,所以要防备它本人被人渣篡改利用——译者注)
Github
Pages恰恰是HTTPS的,所以它是3个精美的天然实验田。
万1您想要让您的server协理HTTPS,你须求为你的server获得三个TLS证书。不一致的server安装方法不一致,阅读帮忙文档并透过Mozilla’s
SSL config
generator打听最棒实践。
生命周期
image
Service Worker
在 main.js
实行登记,第二遍注册前会举行分析,判断加载的文书是还是不是在域名下,协议是或不是为
HTTPS
的,通过那两点则成功注册。
service Worker
起始进入下3个生命周期状态 install
, install
实现后会触发 service Worker
的 install
事件。 如果 install
成功则接下去是 activate
情形, 然后那些 service worker
才能接管页面。当事件 active
事件执行到位现在,此时 service Worker
有三种情景,一种是 active
,一种是 terminated
。active
是为着工作,terminated
则为了节约内部存款和储蓄器。当新的 service Worker
处于
install/waitting
阶段,当前 service Worker
处于
terminated
,就会发生交接替换。也许能够经过调用 self.skipWaiting()
方法跳过等待。
被替换掉的原始的 service Worker
到 Redundant
阶段,在 install
或者
activating
中断的也会跻身 Redundant
阶段。所以多少个 Service Worker
脚本的生命周期有这么一些阶段(从左往右):
[图片上传战败…(image-af三cfa-1511157771六一7)]
Service Worker的装置步骤
在页面上完结注册手续之后,让我们把集中力转到service
worker的剧本里来,在那其间,大家要到位它的安装步骤。
在最宗旨的事例中,你要求为install事件定义2个callback,并控制怎么样文件你想要缓存。
JavaScript
// The files we want to cache var urlsToCache = [ ‘/’,
‘/styles/main.css’, ‘/script/main.js’ ]; // Set the callback for the
install step self.addEventListener(‘install’, function(event) { //
Perform install steps });
1
2
3
4
5
6
7
8
9
10
11
|
// The files we want to cache
var urlsToCache = [
‘/’,
‘/styles/main.css’,
‘/script/main.js’
];
// Set the callback for the install step
self.addEventListener(‘install’, function(event) {
// Perform install steps
});
|
在大家的install callback中,大家必要实践以下步骤:
- 敞开叁个缓存
- 缓存我们的文书
- 控制是或不是拥有的财富是还是不是要被缓存
JavaScript
var CACHE_NAME = ‘my-site-cache-v1’; var urlsToCache = [ ‘/’,
‘/styles/main.css’, ‘/script/main.js’ ];
self.addEventListener(‘install’, function(event) { // Perform install
steps event.waitUntil( caches.open(CACHE_NAME) .then(function(cache) {
console.log(‘Opened cache’); return cache.addAll(urlsToCache); }) ); });
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
var CACHE_NAME = ‘my-site-cache-v1’;
var urlsToCache = [
‘/’,
‘/styles/main.css’,
‘/script/main.js’
];
self.addEventListener(‘install’, function(event) {
// Perform install steps
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
console.log(‘Opened cache’);
return cache.addAll(urlsToCache);
})
);
});
|
地点的代码中,大家由此caches.open打开我们钦点的cache文件名,然后大家调用cache.addAll并传到大家的文书数组。那是经过种类promise(caches.open
和
cache.addAll)实现的。event.waitUntil得到三个promise并采用它来获得安装成本的小时以及是或不是安装成功。
倘诺持有的公文都被缓存成功了,那么service
worker就安装成功了。假诺别的一个文书下载退步,那么安装步骤就会破产。那些办法允许你依靠于你协调内定的持有能源,不过那意味你要求尤其严酷地操纵如何文件须要在安装步骤中被缓存。钦赐了太多的文本的话,就会追加设置失利率。
下边只是一个简短的例证,你能够在install事件中进行别的操作照旧甚至忽视install事件。
谷歌(Google) 开发工具助力 service worker 开发
Google 提供了 sw-toolbox
和 sw-precache
三个工具方便高效生成
service-worker.js
文件:
- sw-precache用来转移页面所需静态财富列表,近年来有
webpack
插件sw-precache-webpack-plugin
能够同盟 - sw-toolbox
提供了动态缓存使用的通用策略, 那么些动态的能源不合适用 sw-precache
预先缓存。同时它提供了一套类似 Express.js 路由的语法,
用于编写策略。它还提供了 LRU 替换策略与 TTL
失效机制,能够保障我们的运用不会超越浏览器的缓存分配的定额。
更多[参照小说]([PWA 入门: 驾驭和创办 Service Worker 脚本])
更加多内容
此处有1些连锁的文书档案能够参见:https://jakearchibald.github.io/isserviceworkerready/resources.html
Install
install
存在中等态 installing
那几个状态在 main.js
的
registration
挂号对象中得以访问到。
/* In main.js */
// 重写 service worker 作用域到 ./
navigator.serviceWorker.register('./sw.js', {scope: './'}).then(function(registration) {
if (registration.installing) {
// Service Worker is Installing
}
})
安装时 service Worker
的 install
事件被触发,那一般用于拍卖静态能源的缓存
service worker 缓存的静态能源
chrome PWA 演示实例
/* In sw.js */
self.addEventListener('install', function(event) {
event.waitUntil(
// currentCacheName 对应调试工具中高亮位置,缓存的名称
// 调用 `cache.open` 方法后才可以缓存文件
caches.open(currentCacheName).then(function(cache) {
// arrayOfFilesToCache 为存放缓存文件的数组
return cache.addAll(arrayOfFilesToCache);
})
);
});
event.waitUntil()
方法接收多个 promise
对象, 要是这些 promise
对象 rejected
则 service Worker
安装失利,状态变更为
Redundant
。关于 cache
相关表明看下文。
fetch()的暗中认可参数
当您选拔fetch,缺省级地区级,请求不会带上cookies等证据,要想带上的话,供给:
JavaScript
fetch(url, { credentials: ‘include’ })
1
2
3
|
fetch(url, {
credentials: ‘include’
})
|
如此这般设计是有理由的,它比XH悍马H2的在同源下暗中同意发送凭据,但跨域时屏弃凭据的条条框框要来得好。fetch的行为更像其余的COLANDS请求,例如<img crossorigin>,它默认不发送cookies,除非你指定了<img crossorigin="use-credentials">.。
示例
fetch
基于stream
的 ,因此 response
& request
壹旦被消费则不可能复苏,所以那里在缓存的时候需求选择 clone
方法在消费前复制1份。
self.addEventListener('fetch', function(event) {
// 只对 get 类型的请求进行拦截处理
if (event.request.method !== 'GET') {
console.log('WORKER: fetch event ignored.', event.request.method, event.request.url);
return;
}
event.respondWith(
// 缓存中匹配请求
caches.match(event.request)
.then(function(response) {
if (response) {
return response;
}
// 因为 event.request 流已经在 caches.match 中使用过一次,
// 那么该流是不能再次使用的。我们只能得到它的副本,拿去使用。
var fetchRequest = event.request.clone();
// fetch 的通过信方式,得到 Request 对象,然后发送请求
return fetch(fetchRequest).then(
function(response) {
// 检查是否成功
if(!response || response.status !== 200 || response.type !== 'basic') {
return response;
}
// 如果成功,该 response 一是要拿给浏览器渲染,而是要进行缓存。
// 不过需要记住,由于 caches.put 使用的是文件的响应流,一旦使用,
// 那么返回的 response 就无法访问造成失败,所以,这里需要复制一份。
var responseToCache = response.clone();
caches.open(CACHE_NAME)
.then(function(cache) {
cache.put(event.request, responseToCache);
});
return response;
}
);
})
);
});
何以立异多个Service Worker
你的service
worker总有亟待立异的那一天。当那1天来到的时候,你供给听从如下步骤来更新:
- 履新您的service worker的JavaScript文件
- 当用户浏览你的网址,浏览器尝试在后台下载service
worker的台本文件。只要服务器上的文本和当麻芋果件有三个字节分歧,它们就被判定为急需更新。
- 当用户浏览你的网址,浏览器尝试在后台下载service
- 履新后的service worker将起来运营,install event被重新触发。
- 在那个日子节点上,当前页面生效的依旧是老版本的service
worker,新的servicer worker将进入”waiting”状态。 - 此时此刻页面被关门之后,老的service worker进度被杀掉,新的servicer
worker正式生效。 - 只要新的service worker生效,它的activate事件被触发。
代码更新后,平常须求在activate的callback中履行七个管理cache的操作。因为你会供给破除掉在此以前旧的多少。大家在activate而不是install的时候实施那么些操作是因为只要大家在install的时候霎时执行它,那么如故在运行的旧版本的数量就坏了。
前边大家只使用了贰个缓存,叫做my-site-cache-v1,其实我们也可以使用多个缓存的,例如一个给页面使用,一个给blog的内容提交使用。这意味着,在install步骤里,我们可以创建两个缓存,pages-cache-v1和blog-posts-cache-v1,在activite步骤里,我们可以删除旧的my-site-cache-v1。
上边包车型地铁代码可以循环全数的缓存,删除掉全体不在白名单中的缓存。
JavaScript
self.addEventListener(‘activate’, function(event) { var cacheWhitelist =
[‘pages-cache-v1’, ‘blog-posts-cache-v1’]; event.waitUntil(
caches.keys().then(function(cacheNames) { return Promise.all(
cacheNames.map(function(cacheName) { if
(cacheWhitelist.indexOf(cacheName) === -1) { return
caches.delete(cacheName); } }) ); }) ); });
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
self.addEventListener(‘activate’, function(event) {
var cacheWhitelist = [‘pages-cache-v1’, ‘blog-posts-cache-v1’];
event.waitUntil(
caches.keys().then(function(cacheNames) {
return Promise.all(
cacheNames.map(function(cacheName) {
if (cacheWhitelist.indexOf(cacheName) === -1) {
return caches.delete(cacheName);
}
})
);
})
);
});
|
Redundant
service Worker
在 install
active
进度中处错误或然,被新的
service Worker
替换状态会成为 Redundant
。
即使是后一种情状,则该 worker
如故控制那几个页面。
值得注意的是已经
install
的service worker
页面关闭后再打开不会触发install
事件,可是会再也注册。越来越多参考小说
钻探 Service Worker
「生命周期」
使用Service Worker
于今我们有了polyfill,并且消除了HTTPS,让大家看看毕竟怎么用service
worker。
Register 时机
service Worker
将深化对 CPU
时间和内存的争用,从而影响浏览器渲染以及网页的竞相。Chrome 团队的开发者
杰夫 Posnick 实践申明在突显动画时期注册 service Worker
会导致低端移动装备出现卡顿,因而在这种气象下延后登记或等越来越好的用户体验。
//Bad
window.addEventListener('DOMContentLoaded', function() {
navigator.serviceWorker.register('/sw.js').then(function(registration) {
}).catch(function(err) {
});
});
// Good
if ('serviceWorker' in navigator) {
// 判断浏览器支持情况
window.addEventListener('load', function() {
// 页面所有资源加载完成后注册
navigator.serviceWorker.register('/service-worker.js');
});
}
唯独当你利用 clients.claim()
将 service Worker
控制全体
Service Worker 是什么?
1个 service worker
是壹段运维在浏览器后台进度里的剧本,它独自于当下页面,提供了那么些不须要与web页面交互的功用在网页背后悄悄执行的力量。在以往,基于它能够兑现新闻推送,静默更新以及地理围栏等服务,然而当前它首先要全体的效果是挡住和拍卖网络请求,包括可编制程序的响应缓存管理。
缘何说这些API是一个尤其棒的API呢?因为它使得开发者可以扶助特别好的离线体验,它赋予开发者完全控制离线数据的能力。
在service worker提出从前,其余二个提供开发者离线体验的API叫做App
Cache。可是App
Cache有些局限性,例如它能够很不难地化解单页应用的标题,可是在多页应用上会很忙碌,而Serviceworkers的面世便是为了缓解App Cache的痛点。
下边详细说一下service worker有哪些须求专注的地点:
- 它是JavaScript
Worker,所以它不能够直接操作DOM。然则service
worker能够透过postMessage与页面之间通讯,把信息布告给页面,要是要求的话,让页面本身去操作DOM。 - Serviceworker是三个可编制程序的网络代理,允许开发者控制页面上拍卖的网络请求。
- 在不被使用的时候,它会本人终止,而当它再一次被用到的时候,会被再次激活,所以您不可能注重于service
worker的onfecth和onmessage的处理函数中的全局状态。假设你想要保存一些持久化的音讯,你能够在service
worker里使用IndexedDB API。 - Serviceworker大批量使用promise,所以只要您不精晓怎么是promise,那你供给先读书这篇文章。
Installed / Waiting
安装到位待正在周转的 service Worker
交接的情形。
在 Service Worker
registration
对象, 我们得以拿走那几个场馆
/* In main.js */
navigator.serviceWorker.register('./sw.js').then(function(registration) {
if (registration.waiting) {
// Service Worker is Waiting
}
})
那是三个提醒用户更新的好机会,大概能够静默更新。
改变URL Hash的Bug
在M40版本中设有一个bug,它会让页面在改动hash的时候造成service
worker结束工作。
你能够在那里找到越多相关的音信: https://code.google.com/p/chromium/issues/detail?id=433708
注意事项
- 成效域:出于安全原因, Service Worker
脚本的法力范围不可能超出脚本文件所在的不二等秘书诀。比如地址是
“/sw-test/sw.js” 的剧本只可以控制 “/sw-test/” 下的页面。 - 本地开发条件足以运用
http
协议, 上线必须运用https
协议。 Service Worker
中的Javascript
代码必须是非阻塞的,所以您不应该在Service Worker
代码中是用
localStorage
以及XMLHttpRequest
。- 在页面关闭后,浏览器可以连续保持service
worker运转,也得以关闭service
worker,那有赖于与浏览器本身的行事,所以不要在serviceWorker.js
中定义全局变量,借使想要保存一些持久化的音讯,你可以在service
worker里使用IndexedDB API。
参考
MDN
Service Worker
lifecycle
service worker
note
update service
worker
chrom service worker
sample
PWA 入门: 掌握和成立 Service Worker
脚本
PWA
在饿了么的实践经验
Service Worker的生命周期
Service worker拥有叁个完全独立于Web页面包车型客车生命周期。
要让八个service
worker在你的网址上生效,你须求先在您的网页中注册它。注册1个service
worker之后,浏览器会在后台默默运营3个service worker的安装进程。
在设置进程中,浏览器会加载并缓存1些静态能源。要是全体的文书被缓存成功,service
worker就安装成功了。假诺有任何公文加载或缓存失利,那么安装进度就会失利,service
worker就不可能被激活(也即没能安装成功)。假如发生这么的标题,别担心,它会在下次再品尝安装。
当安装完成后,service
worker的下一步是激活,在那壹阶段,你还是能提高四个service
worker的本子,具体内容大家会在前边讲到。
在激活之后,service
worker将接管全数在和谐管辖域范围内的页面,不过假如四个页面是刚刚注册了service
worker,那么它那二次不会被接管,到下叁次加载页面包车型客车时候,service
worker才会生效。
当service
worker接管了页面之后,它大概有二种状态:要么被停止以节外省部存款和储蓄器,要么会处理fetch和message事件,那多个事件分别发生于3个网络请求出现还是页面上发送了三个音讯。
下图是3个简化了的service worker初次安装的生命周期:
极品实践
fetch()不遵从30x重定向规范
不幸,重定向在fetch()中不会被触发,那是近来版本的bug;
打探前的刺探
万壹设置失利了,未有很优雅的法子获得通报
若果二个worker被登记了,不过并未有出现在chrome://inspect/#service-workers或chrome://serviceworker-internals,那么很可能因为异常而安装失败了,或者是产生了一个被拒绝的的promise给event.waitUtil。
要消除这类难题,首先到 chrome://serviceworker-internals检查。打开开发者工具窗口准备调试,然后在你的install event代码中添加debugger;语句。这样,通过断点调试你更容易找到问题。
Activating
- 当页面未有正在运行的
service Worker
时; service Worker
本子中调用了self.skipWaiting
方法;- 用户切换页面使本来的
service Worker
释放; - 一定失效已过,释放由此原有的
service Worker
被释放
则状态变为 activating
,触发 service worker
的 active
事件。
/* In sw.js */
self.addEventListener('activate', function(event) {
event.waitUntil(
// Get all the cache names
caches.keys().then(function(cacheNames) {
return Promise.all(
// Get all the items that are stored under a different cache name than the current one
cacheNames.filter(function(cacheName) {
return cacheName != currentCacheName;
}).map(function(cacheName) {
// Delete the items
return caches.delete(cacheName);
})
); // end Promise.all()
}) // end caches.keys()
); // end event.waitUntil()
});
同 install
事件中的 event.waitUntil
方法。当所吸收接纳的 promise
被
reject
那么 serviceWorker
进入 Redundant
状态。
fetch()最近仅支持Service Workers
fetch立即帮衬在页面上利用了,可是当前的Chrome达成,它还只援救service
worker。cache
API也就要在页面上被支持,可是近日截至,cache也还不得不在service
worker中用。
引进开关机制
开关是在饿了么实践经验里提议降级方案,通过向后端请求四个是不是降级的接口,要是降级则打消掉已经登记的service Worker
。那里要留心不要缓存这几个开关请求。为了便于难点排查,可以设置三个debug 格局(在 url 添加有些字符)。
Non-CO奥德赛S暗许不援助
暗中认可景况下,从第三方U奥迪Q7L跨域获得1个能源将会破产,除非对方协理了CO翼虎S。你能够加上三个non-COCR-VS选项到Request去制止退步。代价是这么做会回来一个“不透明”的response,意味着你无法得知这几个请求毕竟是水到渠成了照旧退步了。
JavaScript
cache.addAll(urlsToPrefetch.map(function(urlToPrefetch) { return new
Request(urlToPrefetch, { mode: ‘no-cors’ }); })).then(function() {
console.log(‘All resources have been fetched and cached.’); });
1
2
3
4
5
|
cache.addAll(urlsToPrefetch.map(function(urlToPrefetch) {
return new Request(urlToPrefetch, { mode: ‘no-cors’ });
})).then(function() {
console.log(‘All resources have been fetched and cached.’);
});
|
Actived
activting
成功后,这时 service Worker
接管了任何页面状态成为
acticed
。
其一意况我们能够阻碍请求和新闻。
/* In sw.js */
self.addEventListener('fetch', function(event) {
// Do stuff with fetch events
});
self.addEventListener('message', function(event) {
// Do stuff with postMessages received from document
});
怎么样注册和装置service worker
要设置service
worker,你须要在您的页面上登记它。那几个手续告诉浏览器你的service
worker脚本在何地。
JavaScript
if (‘serviceWorker’ in navigator) {
navigator.serviceWorker.register(‘/sw.js’).then(function(registration) {
// Registration was successful console.log(‘ServiceWorker registration
successful with scope: ‘, registration.scope); }).catch(function(err) {
// registration failed 🙁 console.log(‘ServiceWorker registration
failed: ‘, err); }); }
1
2
3
4
5
6
7
8
9
|
if (‘serviceWorker’ in navigator) {
navigator.serviceWorker.register(‘/sw.js’).then(function(registration) {
// Registration was successful
console.log(‘ServiceWorker registration successful with scope: ‘, registration.scope);
}).catch(function(err) {
// registration failed 🙁
console.log(‘ServiceWorker registration failed: ‘, err);
});
}
|
地点的代码检查service worker API是或不是可用,假使可用,service
worker /sw.js 被注册。
若果这么些service worker已经被注册过,浏览器会自动忽略上面包车型大巴代码。
有二个亟需专门说明的是service
worker文件的途径,你肯定留神到了在那么些例子中,service
worker文件被放在那一个域的根目录下,那意味着service
worker和网址同源。换句话说,那个service
work将会吸收接纳那一个域下的拥有fetch事件。借使自身将service
worker文件注册为/example/sw.js,那么,service worker只能收到/example/路径下的fetch事件(例如: /example/page1/, /example/page2/)。
今日您能够到 chrome://inspect/#service-workers 检查service worker是否对你的网站启用了。
当service
worker第叁版被完毕的时候,你也能够在chrome://serviceworker-internals中查看,它很有用,通过它可以最直观地熟悉service worker的生命周期,不过这个功能很快就会被移到chrome://inspect/#service-workers中。
你会发现那几个效果能够很有益于地在3个仿照窗口中测试你的service
worker,那样你能够关闭和重新打开它,而不会影响到你的新窗口。任何创制在模拟窗口中的注册服务和缓存在窗口被关闭时都将消灭。
伸手处理
处于 actived
阶段的 service Worker
可以阻碍页面发出的
fetch
,也得以爆发fetch
请求,能够将呼吁和响应缓存在
cache
里,也能够将 response
从 cache
中取出。
拍卖响应式图片
img的srcset属性或许<picture>标签会根据情况从浏览器或者网络上选择最合适尺寸的图片。
在service worker中,你想要在install步骤缓存三个图形,你有以下两种选用:
- 设置具有的
<picture>元素或者将被请求的srcset属性。
- 设置单一的low-res版本图片
- 设置单一的high-res版本图片
比较好的方案是二或三,因为壹旦把具有的图纸都给下载下来存着有点浪费内部存款和储蓄器。
如若你将low-res版本在install的时候缓存了,然后在页面加载的时候你想要尝试从互连网上下载high-res的本子,可是倘诺high-res版本下载退步以来,就如故用low-res版本。这些想法很好也值得去做,可是有一个标题:
比方我们有上边二种图片:
Screen Density | Width | Height |
---|---|---|
1x | 400 | 400 |
2x | 800 | 800 |
HTML代码如下:
JavaScript
<img src=”image-src.png” srcset=”image-src.png 1x, image-2x.png 2x”
/>
1
|
<img src="image-src.png" srcset="image-src.png 1x, image-2x.png 2x" />
|
假如大家在三个二x的来得格局下,浏览器会下载image-二x.png,若是大家离线,你能够读取此前缓存并赶回image-src.png替代,假使此前它曾经被缓存过。固然如此,由于现行的格局是贰x,浏览器会把400X400的图片显示成200X200,要幸免这些标题就要在图纸的体制上安装宽高。
JavaScript
<img src=”image-src.png” srcset=”image-src.png 1x, image-2x.png 2x”
style=”width:400px; height: 400px;” />
1
2
|
<img src="image-src.png" srcset="image-src.png 1x, image-2x.png 2x"
style="width:400px; height: 400px;" />
|
<picture>标签情况更复杂一些,难度取决于你是如何创建和使用的,但是可以通过与srcset类似的思路去解决。
越发简的介
二零一八年开班火遍南北的 PWA
技术诞生情状有负重望,首要来自 safrai
对于这一技术协助不甚理想,不帮衬 mainfest
文件也不帮忙
service Worker
。
service worker
是贰个出奇的 web Worker
,由此她与页面通讯和 worker
是同一的,同样无法访问 DOM
。特殊在于她是由事件驱动的富有生命周期的
worker
,并且能够阻止处理页面包车型地铁网络请求(fetch),能够访问 cache
和
IndexDB
。
换言之 service Worker
能够让开发者自个儿主宰管理缓存的内容以及版本,为离线弱网环境下的 web
的运作提供了恐怕,让 web 在经验上越来越亲临其境 native。
处理边界和填坑
那1节内容相比较新,有过多待定细节。希望那1节非常的慢就不供给讲了(因为标准会处理这几个难题——译者注),不过今后,那个内容照旧应该被提一下。
install 事件中静态能源缓存
service Worker
在 install
事件中缓存文件进度中,当在那之中3个文件加载退步,则 install
失利。因而能够对要缓存的文本进行独家,一定要加载的,和同意加载失利的,对于同意加载退步的文件。
self.addEventListener('install', function(event) {
event.waitUntil(
caches.open('mygame-core-v1').then(function(cache) {
// 不稳定文件或大文件加载
cache.addAll(
//...
);
// 稳定文件或小文件加载
return cache.addAll(
// core assets & levels 1-10
);
})
);
});
哪些缓存和重返Request
你已经安装了service worker,你将来得以回来您缓存的乞请了。
当service
worker被安装成功还要用户浏览了另贰个页面大概刷新了脚下的页面,service
worker将起来接到到fetch事件。上面是一个例证:
JavaScript
self.addEventListener(‘fetch’, function(event) { event.respondWith(
caches.match(event.request) .then(function(response) { // Cache hit –
return response if (response) { return response; } return
fetch(event.request); } ) ); });
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
self.addEventListener(‘fetch’, function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
// Cache hit – return response
if (response) {
return response;
}
return fetch(event.request);
}
)
);
});
|
上边的代码里我们定义了fetch事件,在event.respondWith里,我们传入了三个由caches.match发生的promise.caches.match
查找request中被service worker缓存命中的response。
壹旦大家有多个命中的response,我们回去被缓存的值,不然大家回去3个实时从网络请求fetch的结果。那是贰个卓殊简单的事例,使用全部在install步骤下被缓存的财富。
设若大家想要增量地缓存新的请求,大家得以经过处理fetch请求的response并且拉长它们到缓存中来兑现,例如:
JavaScript
self.addEventListener(‘fetch’, function(event) { event.respondWith(
caches.match(event.request) .then(function(response) { // Cache hit –
return response if (response) { return response; } // IMPORTANT: Clone
the request. A request is a stream and // can only be consumed once.
Since we are consuming this // once by cache and once by the browser for
fetch, we need // to clone the response var fetchRequest =
event.request.clone(); return fetch(fetchRequest).then(
function(response) { // Check if we received a valid response
if(!response || response.status !== 200 || response.type !== ‘basic’) {
return response; } // IMPORTANT: Clone the response. A response is a
stream // and because we want the browser to consume the response // as
well as the cache consuming the response, we need // to clone it so we
have 2 stream. var responseToCache = response.clone();
caches.open(CACHE_NAME) .then(function(cache) {
cache.put(event.request, responseToCache); }); return response; } ); })
); });
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
|
self.addEventListener(‘fetch’, function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
// Cache hit – return response
if (response) {
return response;
}
// IMPORTANT: Clone the request. A request is a stream and
// can only be consumed once. Since we are consuming this
// once by cache and once by the browser for fetch, we need
// to clone the response
var fetchRequest = event.request.clone();
return fetch(fetchRequest).then(
function(response) {
// Check if we received a valid response
if(!response || response.status !== 200 || response.type !== ‘basic’) {
return response;
}
// IMPORTANT: Clone the response. A response is a stream
// and because we want the browser to consume the response
// as well as the cache consuming the response, we need
// to clone it so we have 2 stream.
var responseToCache = response.clone();
caches.open(CACHE_NAME)
.then(function(cache) {
cache.put(event.request, responseToCache);
});
return response;
}
);
})
);
});
|
代码里大家所做政工包涵:
- 丰裕三个callback到fetch请求的 .then 方法中
- 1旦大家得到了一个response,大家开始展览如下的自笔者批评:
- 保险response是可行的
- 检查response的情事是或不是是200
- 保证response的花色是basic,那象征请求作者是同源的,非同源(即跨域)的呼吁也无法被缓存。
- 假定我们经过了反省,clone本条请求。这么做的原因是假使response是3个Stream,那么它的body只好被读取2回,所以大家得将它克隆出来,1份发给浏览器,一份发给缓存。
缓存使用政策
为此得以依照使用的光景,使用缓存的 response
给到页面收缩请求及时响应,亦大概将呼吁再次来到的结果更新到缓存,在使用离线时返回给页面。那正是以下的三种策略。
- 网络优先: 从网络得到, 失利也许逾期再品尝从缓存读取
- 缓存优先: 从缓存获取,
缓存插叙不到再品尝从互连网抓取,在上文中的代码块就是该种策略的兑现。 - 最快: 同时询问缓存和网络, 重返起始得到的
- 仅限网络: 仅从互联网获取
- 仅限缓存: 仅从缓存获取
Service Worker入门
2015/03/26 · JavaScript
· Service Worker
原版的书文出处: Matt
Gaunt 译文出处:[w3ctech
- 10年踪迹](http://www.w3ctech.com/topic/866)
原生App拥有Web应用普通所不具有的富离线体验,定时的沉默不语更新,新闻文告推送等功用。而新的Serviceworkers标准让在Web App上存有那个意义成为或许。
荒唐监察和控制
self.addEventListener('error', event => {
// 上报错误信息
// 常用的属性:
// event.message
// event.filename
// event.lineno
// event.colno
// event.error.stack
})
// 捕获 promise 错误
self.addEventListener('unhandledrejection', event => {
// 上报错误信息
// 常用的属性:
// event.reason
})
那多个事件都不得不在 worker 线程的 initial
生命周期里登记。(不然会破产,控制台可看出警告)
获得帮忙
一旦你遇上麻烦,请在Stackoverflow上发帖询问,使用‘service-worker’标签,以便于我们马上跟进和不择手段帮忙您化解难题。
赞 2 收藏
评论
同盟景况
safrai
已经于 2017年8月 开始了 service Worker
的开发。
image
近来浏览器PC援助情状如图
国内首要浏览器协助情况
android
设备在 4.4
版本采纳 Chromium
作为根本,Chromium
在 40
对于 service worker
帮助。国内浏览器包含微信浏览器在内基本已经支撑
service Worker
那为升级体验提供了恐怕。service worker
与 HTTP2
尤其配哦,在后日基于它能够完成信息推送,静默更新以及地理围栏等劳动。
处理请求中离线意况
在 service Worker
发送请求时,捕获非常,并回到页面三个 response
通告页面恐怕离线。
function unableToResolve () {
/*
当代码执行到这里,说明请求无论是从缓存还是走网络,都无法得到答复,这个时机,我们可以返回一个相对友好的页面,告诉用户,你可能离线了。
*/
console.log('WORKER: fetch request failed in both cache and network.');
return new Response('<h1>Service Unavailable</h1>', {
status: 503,
statusText: 'Service Unavailable',
headers: new Headers({
'Content-Type': 'text/html'
})
});
}
fetch(event.request).then(fetchedFromNetwork, unableToResolve).catch(unableToResolve);
image