Open evantianx opened 7 years ago
For example, the Google I/O 2016 web app features a short animation before transitioning to the main screen. Our team found that kicking off the service worker registration during the animation could lead to jankiness on low-end mobile devices. Rather than giving users a poor experience, we delayed service worker registration until after the animation, when the browser was most likely to have a few idle seconds.
Similarly, if your web app uses a framework that performs additional setup after the page has loaded, look for a framework-specific event that signals when that work is done.
这意味着若页面载入存在动画,则应在动画结束之后再进行注册:
if('serviceWorker' in navigator) {
document.querySelector('.hero').addEventListener('animationend', function () {
// service worker is registered only when the animation ends
navigator.serviceWorker.register('/serviceworker.js');
});
}
// ---
App.init({
// config
complete: function() {
// service worker is registered only when the app is initiated
if('serviceWorker' in navigator) {
navigator.serviceWorker.register('/serviceworker.js');
}
}
});
当然,如果你的网站足够简单,那么只需考虑在页面加载完毕之后再注册 Service Worker:
if('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/serviceworker.js');
});
}
考虑到安全因素,使用 Service Worker 必须通过 HTTPS 协议或者本地 localhost。
开发环境中,Service Worker 只可以在 localhost 上生效,其他如内网 IP 之类的无效。
只能作用于当前路径和子路径。
不能同时作用于主域名和子域名,如
kollegorna.se/serviceworker.js
不能作用于labs.kollegorna.se
最佳实践是: 在注册 Service Worker 时,使用 ES5 语法;在内部使用 ES6 语法。
提高用户体验,可以添加一个离线页面。
每次用户访问你的网站的时候,浏览器就会下载 worker 文件。如果之前访问过且该文件已经有缓存,那么浏览器就会进行比对。如果发现有差异,则会认为 worker 文件过期, 所以会重新注册 service worker,然后删除旧的 worker 文件。此即为 work 文件的生命周期。
在一个生命周期内只会触发一次。负责注册 service worker 以及初始化页面和样式
self.addEventListener('install', event => {
// ...
})
紧接着 install 事件,activate 事件触发了。同样一个生命周期内只会触发一次。它的作用在于删除过期的缓存。
self.addEventListener('activate', event => {
// ...
})
拦截 HTTP 请求。每个 HTTP 请求都会有单独的 fetch 事件触发。可以用来做回调,决定页面重新加载还是从缓存加载。
self.addEventListener('fetch', event => {
// ...
})
首次加载时一定要精简要下载的资源。原因在于用户可能不会在页面停留很久或者网络情况不佳。
const criticalResources = [
'/',
'/offline/',
'/assets/css/main.css',
'/assets/js/main.js'
],
// 异步缓存文件
cacheCriticals = () => {
return caches.open(version).then( cache => {
return cache.addAll(criticalResources);
});
};
self.addEventListener('install', event => {
event.waitUntil(cacheCriticals().then( () => self.skipWaiting() ));
});
分清主次之后,我们进一步改进:
const otherResources = [
'/about/',
'/contact/',
'/services/'
],
cacheCriticals = () => {
return caches.open(version).then( cache => {
cache.addAll(otherResources); // important, but not critical resources
return cache.addAll(criticalResources); // critical resources
});
};