随着互联网越来越普及,Web 应用的需求也变得越来越高。然而,Web 应用还存在一些局限,如离线缓存、快速加载等。PWA(Progressive Web App)的出现就是为了解决这些问题。而 PWA 的核心技术之一就是 Service Worker。
Service Worker 是什么?
Service Worker 是一个 JS 脚本,它在用户退出网站后仍然可以在后台运行。它可以和浏览器之外的其他资源打交道,比如发送网络请求和查找缓存。Service Worker 是 PWA 实现离线缓存和快速加载等功能的重要手段。
Service Worker 的运行原理
Service Worker 使用事件驱动模型,通过监听浏览器事件来实现相关功能。
安装
Service Worker 安装过程可以分为注册、下载及安装三个阶段。这三个阶段的代码如下:
// javascriptcn.com 代码示例 // 注册 Service Worker navigator.serviceWorker.register('/sw.js') .then(reg => { console.log("Service Worker 注册成功"); reg.addEventListener('updatefound', () => { // 监听到 Service Worker 脚本变化,触发更新逻辑 const newWorker = reg.installing; newWorker.addEventListener('statechange', () => { if (newWorker.state === 'installed') { console.log('Service Worker 更新完成'); } }); }); }) .catch(error => { console.log("Service Worker 注册失败") });
在这个代码块中,我们首先使用 navigator.serviceWorker.register
方法注册 Service Worker。一旦注册成功,我们就可以监听 Service Worker 的状态变化了。在 updatefound
事件触发时,我们获取新的 Service Worker 脚本,并在 statechange
事件中监听其更新状态,如果更新完成(state 为 installed),就输出更新完成的信息。
缓存
Service Worker 的其中一个核心功能是缓存请求和响应。它通过监听 fetch 事件来实现请求和响应的缓存。
当客户端请求资源时,Service Worker 将首先检查该资源是否已经被缓存。如果缓存中有该资源,则将缓存的响应返回给客户端。如果缓存中没有该资源,则 Service Worker 将为该请求发送一个网络请求,并在网络请求返回后将响应缓存起来以供后续使用。
以下是代码展示:
// javascriptcn.com 代码示例 // 缓存静态资源 const cacheName = 'MY_CACHE'; self.addEventListener('install', event => { event.waitUntil( caches.open(cacheName).then(cache => { console.log('Service Worker 安装成功'); return cache.addAll([ '/', '/style.css', '/script.js', '/assets/img/logo.png' ]); }) ); }); // 从缓存中获取响应 self.addEventListener('fetch', event => { event.respondWith( caches.match(event.request).then(response => { // 如果缓存中有,则返回缓存 if (response) { return response; } // 如果缓存中没有,则发送 HTTP 请求,并将其放入到缓存中 return fetch(event.request).then(response => { if (!response || response.status !== 200 || response.type !== 'basic') { return response; } const responseToCache = response.clone(); caches.open(cacheName).then(cache => { cache.put(event.request, responseToCache); }); return response; }); }) ); });
在这个代码块中,我们定义了一个缓存名称,并使用 caches.open
方法打开我们在其中缓存静态资源。Service Worker 中的 install
事件在安装 Service Worker 时触发,允许我们进行一些资源预缓存。如上代码,在 install 事件中,我们使用 cache.addAll
方法将需要缓存的资源添加到缓存中。
fetch
事件会监听所有的网络请求,并允许我们实现自定义的响应逻辑。在上述代码块中,我们首先将请求与缓存进行匹配,如果缓存中有该资源,则从缓存获取。如果缓存中没有该资源,则 Service Worker 发送网络请求,并缓存响应。
通信
Service Worker 通过发送/监听 message
事件与网页通信,使网页能够调用 Service Worker 中的功能。
网页向 Service Worker 发送消息:
navigator.serviceWorker.addEventListener('message', ({data}) => { console.log('Service Worker 返回数据:' + data); }); navigator.serviceWorker.controller.postMessage('Hello');
Service Worker 中的 message 事件响应:
self.addEventListener('message', event => { console.log('网页发来消息:' + event.data); event.ports[0].postMessage('World!'); });
在这个代码块中,我们使用 navigator.serviceWorker.controller
发送数据到 Service Worker。同时,在 Service Worker 中监听 message
事件,当事件触发时,将返回数据。
总结
本文介绍了 PWA 技术中的 Service Worker,并详细讲解了其运行原理,包括安装、缓存和通信这三个方面。Service Worker 的事件驱动模型,使得它可以实现离线缓存、快速加载及其它功能。而对于 Web 开发者而言,Service Worker 将成为实现 PWA 的利器。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6542ea607d4982a6ebc93710