本文原创,转载请以链接形式注明地址:
想要开发一个 PWA(Progressive web App) 应用,你必须知道首先知道,Service Worker 是什么,他是怎么工作的。
首先,写给所有移动端开发的同学:PWA(Progressive Web Apps) 一定是将来的移动开发趋势,且学且珍惜。
Progressive Web Apps 比小程序还要方便,对于首次访问的用户可以直接在浏览器中进行访问,不需要安装应用。即使在比较糟糕的网络环境下,也能够快速地加载,且能够推送相关消息, 也可以像原生应用那样添加至桌面或浏览器主屏,能够有全屏浏览的体验。
PWA 和 Service Worker 是什么关系?Service Worker 是一个运行在浏览器后台进程里的
,基于它可以实现消息推送,静默更新以及拦截和处理网络请求,包括可编程的响应缓存管理,是 PWA 的核心。 开源实验室 () 已启用 Service Worker,现在只要你访问过的文章,在主流浏览器 (包括 PC、手机) 二次访问均可离线访问啦。
- js
Service worker 是一个完全独立于 Web 页面的 js 脚本,有他自己的生命周期。
每个 service worker 会对应一个缓存池,每个缓存池有多个缓存仓库。
首先讲讲它的声明周期,借用 Google 的一张图片:
若网站对应的 cacheName 没有
,则首先触发
- install
事件。 若
- install
失败,则退出等待下次访问再启动;否则触发
- install
事件。 在
- activate
中,判断当前页面是否在上文声明的 filesToCache 列表中,如果是则接管网页的显示。 接管网页以后,如果当前内存不足,会被杀死;否则等待处理
- activate
和
- fetch
事件。这两个事件一个是当网络请求时,或者其他网页发出了消息时。 本文只讲如何让你的网页无网络也能访问,没有讲这两个事件,下一篇文章再给大家讲讲 service worker 深度使用。
- message
首先你的站点必须支持
(这也是为什么这两天你访问开源实验室出错的原因,在转全站 https)。 其次,你至少得懂一点
- https
开发。 最后,你得有一个 52 或以上的版本的 Chrome 用作调试。
- js
首先,在你的网站根目录下创建一个
文件 (文件名自定)。 这个 service-worker.js 文件必须放在跟目录,因为 service workers 的作用范围是根据其在目录结构中的位置决定的。
- service-worker.js
然后需要检查浏览器是否支持 service workers,如果支持,就注册 service worker,将下面代码添加至网页要加载的
中。
- js
- if('serviceWorker' in navigator) {
- //注册上一步创建的js文件
- navigator.serviceWorker
- .register('/service-worker.js')
- .then(function() { console.log('Service Worker Registered'); });
- }
当用户访问一个注册了 service worker 的页面时,会触发一个叫
事件,所以我们首先对这个事件监听。
- install
- var cacheName = 'oslab-kymjs-blog';
- var filesToCache = [];
- self.addEventListener('install', function(e) {
- console.log('[ServiceWorker] Install');
- e.waitUntil(
- caches.open(cacheName).then(function(cache) {
- console.log('[ServiceWorker] Caching app shell');
- return cache.addAll(filesToCache);
- })
- );
- });
当监听到
事件以后,去缓存池打开名为 oslab-kymjs-blog 的缓存仓库。
- install
事件也将会失败。而如果
- install
失败了,那么接下来 service worker 就完全不会工作了。 所以一定要注意,文件列表一定不要太长了,越长造成失败的可能性就越高,每个要缓存的页面越大失败的可能性也越高。
- install
用 Chrome Developer Tools 调试 Service Worker 非常方便。
首先 run 起你本地的 server(我博客是 jekyll 生成的,所以直接用了 jekyll 服务),然后 Chrome 右上角三个点,More Tools,Developer Tools。(mac 快捷键 cmd+opt+i)
切换到 Application 视图
你应该能看到这样的一个页面
首次运行应该显示空的,看不到东西,刷新一下就可以了。但如果刷新后还是看不到,这意味着当前打开的页面没有已经被注册的 Service Worker,检查一下 注册 步骤的
是否被加载了吧。
- js
刷新前 注意勾选【update on reload】不然每次刷新都会起一个新的 service worker,然后由于是串行执行,会等待前一个执行完,不然得手动点【skipWaiting】。
然后如果勾选了【update on reload】,可能会看到这个警告,无所谓,忽略它就好了。
当 service worker 开始启动时,就会触发
事件。 所以我们监听 activate 在这里更新缓存。
- activate
- self.addEventListener('activate', function(e) {
- console.log('[ServiceWorker] Activate');
- e.waitUntil(
- caches.keys().then(function(keyList) {
- return Promise.all(keyList.map(function(key) {
- console.log('[ServiceWorker] Removing old cache', key);
- if (key !== cacheName) {
- return caches.delete(key);
- }
- }));
- })
- );
- });
以上代码表示,如果执行到了 activate,首先判断现在缓存池中的缓存仓库 cacheName 是否和我们声明的 cacheName 同一个,如果不是,就清空缓存池中的无用缓存 (install 中下载新的缓存,activate 中删除旧缓存)。所以建议大家在 cacheName 的末尾加一个版本号,这样可以始终让 service worker 加载最新的缓存。
至此,就为我们的博客完整接入了 service worker。
如果还不会,你可以以我博客的 service worker 做参考,看看我的写法 。
来源: http://www.bubuko.com/infodetail-1947783.html