Service worker性能优化 &workbox
定义:
Service worke 是一个浏览器提供的独立线程,独立于当前网页的进程,在js主线程注册完之后,,开发者可以用编程的方式自己控制关联的页面,拦截并修改访问和资源请求,不局限于图片,甚至是ajax请求等,细粒度地缓存资源
特点
- 独立的一个线程(不影响页面UI渲染)
- 独立 生命周期
- 独立的作用域
- 通过postMessage进行通信
- API全异步
- 只能运行在HTTPS或者localhost环境
作用
- 拦截页面的请求,实现缓存预加载。
- 缓存一些静态资源,实现图片前端资源预加载。
- 可以做统一url的多个页面之间的通信的桥梁
调试 Service Worker
地址栏输入:chrome://inspect/#service-workers
Service Worker 日志查看
地址栏输入:chrome://serviceworker-internals
作用域
sw会监听和代理所有的请求,只想对特定页面监控,可以在注册时指定路径:
navigator.serviceWorker.register('/mytest/sw.js');
实践
页面通信
// app.js // 加载sw.js这个service worker navigator.serviceWorker.register('./sw.js') .then(reg => { console.log('SW registered!', reg) }) .catch(err => console.log('Boo!', err)); // 监听service worker发送过来的消息 navigator.serviceWorker.addEventListener('message', function (event) { console.log('Client ' + clientId + ' says: ' + event.data.message) }); // 页面上有一个按钮,点击之后向service worker发送hello的消息 button.addEventListener('click', function() { navigator.serviceWorker.controller.postMessage('hello'); });
// sw.js // 监听页面上发送过来的消息,然后发送给其他页面消息 self.addEventListener('message', function(event){ var promise = self.clients.matchAll() .then(function(clientList) { // event.source.id contains the ID of the sender of the message. var senderID = event.source.id; clientList.forEach(function(client) { // Skip sending the message to the client that sent it. if (client.id === senderID) { return; } client.postMessage({ client: senderID, message: event.data }); }); }); // If event.waitUntil is defined, use it to extend the // lifetime of the Service Worker. if (event.waitUntil) { event.waitUntil(promise); } });
Workbox 文档
- Workbox Webpack插件文档:https://developers.google.com/web/tools/workbox/guides/generate-service-worker/webpack
- Workbox Webpack插件详细配置文档:https://developers.google.com/web/tools/workbox/modules/workbox-webpack-plugin