zoukankan      html  css  js  c++  java
  • service worker 实战

    service worker 实战

    service worker 是现代浏览器的一个新特性,伴随着谷歌的 PWA 概念一起,在近期广泛的出现在大家的视野里。

    关于 service worker 的概念和相关的机制,本文不再介绍,大家可以参考 mdn 或自行 google。
    本文主要说说我是怎么使用 service worker 的。

    做什么?

    service worker 故名意思,就是一个提供 service 的 worker。
    通常 service worker 扮演着一个 proxy server,而目前因种种原因,我们主要是用它来做一个缓存代理。
    最终,通过这个代理来加速我们 web 的加载,甚至是实现我们 web 的离线加载。

    怎么做?

    要通过 service worker 实现一个缓存代理其实很简单,借助谷歌的 sw-toolbox
    这个库,简直可以说是分分钟搞定。以我的一个 h5 应用 为例:

    1. 首先创建一个 service worker 的脚本文件 sw.js
    2. 在脚本里引入 sw-toolbox importScripts('/static/js/lib/sw-toolbox.js');
    3. 为了 service worker 能尽快应用,分别在 install 事件中调用 self.skipWaiting,在 activate 事件中调用 self.clients.claim
    4. 针对应用的资源制定合适的缓存策略。
    5. 最后在页面中注册 service worker,即可。

    完整 sw.js 代码如下:

    var version = '1.2.0';
    
    self.__uri = function(src) {
    	return src
    };
    
    importScripts(__uri('/static/js/lib/sw-toolbox.js'));
    importScripts(__uri('/static/js/lib/sw/monitor.js'));
    
    self.addEventListener('install', function(event) {
    	event.waitUntil(self.skipWaiting());
    });
    self.addEventListener('activate', function(event) {
    	event.waitUntil(self.clients.claim());
    });
    
    toolbox.router.get('/:module/sw', toolbox.networkOnly);
    toolbox.router.get('/static/(.*)', toolbox.cacheFirst);
    toolbox.router.get('/(.*)', toolbox.networkFirst);
    toolbox.router.get('/(.*)', function(request, values, options) {
    	// 跨域,针对微信添加额外的头
    	var newRequest = new Request(request, {
    		headers: {}
    	});
    	return toolbox.cacheFirst.apply(this, [newRequest, values, options]);
    }, {
    	origin: /^https?://at.alicdn.com/,
    	cache: {
    		name: 'font_1457169990_5499172',
    		maxEntries: 10,
    		maxAgeSeconds: 60 * 60 * 24 * 7
    	}
    });
    

    页面注册代码如下:

    if (navigator.serviceWorker) {
    	fetch(G.root + '/sw').then(function(res) {
    
    		if (res.ok) {
    			return res.json();
    		}
    
    		throw res.statusText;
    	}).then(function(resData) {
    		if (resData.data.on) {
    			navigator.serviceWorker.register(__uri('/andyunjing/sw.js'));
    		} else {
    			navigator.serviceWorker.getRegistrations().then(function(registrations) {
    				// console.log(registrations.scope)
    				registrations.forEach(function(registration) {
    					registration.unregister();
    				});
    			});
    		}
    	});
    }
    

    缓存策略

    sw-toolbox 提供了 networkFirst、cacheFirst、fastest、cacheOnly、networkOnly 5种缓存应用策略,相信大家看名字也基本能猜到相应的逻辑了,具体的可查看官方文档了解。

    在我的代码里面主要用到了 networkFirst、cacheFirst、networkOnly 这3种。

    • 针对 /:module/sw 这个开关接口请求,始终进行网络请求,即 networkOnly
    • 针对网页的静态资源,如果有缓存,则用缓存的,否则进行请求,即 cacheFirst
    • 针对网页的页面,为了获取最新的数据,首先从网络请求,但如果没网的话,也可以用缓存里面的页面,即 networkFirst

    其他

    在完整的代码里面,除了引入 sw-toolbox 库和配置缓存策略外,还有一些其他的东西,是我参考 https://zhuanlan.zhihu.com/p/25800461
    这篇文章的经验,实现的服务器端的开关控制和相关的统计打点

    还有一个就是跨域资源的加载,针对微信去掉 x-qid 的头,避免触发 options 请求。

    效果

    最终的页面,在首次加载的时候完成 service worker 的注册和启用,在第二次加载完成页面资源的缓存,然后第三次打开小伙伴们就能享受到网页秒开的爽快了!

    service worker 作为一个渐进增强的选项,在不改动原有代码的情况下,通过简单的开发就是带来更好的体验,大家值得一试!

  • 相关阅读:
    hdu1410 数学题组合概率 log优化
    Triangle
    Unique Paths II
    Unique Paths
    Pascal's Triangle II
    Pascal's Triangle
    Plus One
    Remove Duplicates from Sorted Array II
    Remove Duplicates from Sorted Array
    Remove Element
  • 原文地址:https://www.cnblogs.com/snadn/p/6668824.html
Copyright © 2011-2022 走看看