PWA 技术解析:Service Worker 原理和应用
PWA(Progressive Web App) 技术是一种新型的 Web 应用技术,通过应用像原生应用一样的体验、优秀的性能、脱机访问等特点,让 Web 应用能够像原生应用一样受到用户的喜爱。Service Worker 是 PWA 实现的重要组成部分之一;本文将从 Service Worker 的原理和应用方面来解析 PWA 技术。
一、Service Worker 的原理
1.1、什么是 Service Worker
Service Worker 是一段在后台运行的 JavaScript 代码,它能让 Web 应用实现一些特殊的功能和逻辑,比如网络代理和缓存。众所周知,Web 应用是不能运行在用户计算机的后台的,也就无法持续地运行和缓存数据;但是,通过 Service Worker 机制,Web 应用就可以在用户关闭页面之后,异步地在后台接收事件和 HTTP 请求,然后离线地处理它们。
另外,Service Worker 有生命周期,它可以在离线、在线、停止等状态下改变自己的状态,这种能力可以让 Service Worker 实现非常有用的功能,比如网络代理和脱机缓存等。
1.2、注册 Service Worker
Service Worker 要想生效,需要通过 navigator.serviceWorker.register() 方法注册,代码如下:
if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js', { scope: '/' }).then(function(registration) { // 注册成功 console.log('ServiceWorker registration successful with scope: ', registration.scope); }).catch(function(err) { // 注册失败 console.log('ServiceWorker registration failed: ', err); }); }
在上面的代码中,'/sw.js' 是 Service Worker 需要加载的文件路径,而 scope 参数则指定了 Service Worker 控制的范围,如果不指定 scope,则默认控制整个站点;如果指定了 scope,则只控制 scope 指定的路径下的文件。register() 方法返回一个 Promise 对象,在注册成功后会返回一个 ServiceWorkerRegistration 对象。
1.3、Service Worker 生命周期
Service Worker 的生命周期分为三个阶段:registration、installation 和 activation。分别对应着 Service Worker 注册成功、准备安装和已安装准备激活。
registration 阶段:
在这个阶段,Service Worker 已经被浏览器成功注册,但没有开始安装。在此阶段,Service Worker 会触发 install 和 activate 事件。
installation 阶段:
在此阶段,Service Worker 正在后台安装和缓存资源。在这个阶段,Service Worker 只是在客户端下载资源,并没有激活,所以此时不能通过 Service Worker 处理 HTTP 请求。
activation 阶段:
在此阶段,Service Worker 已经安装成功,且可以接收 fetch 事件,开始缓存资源并拦截网络请求。
1.4、Service Worker 缓存机制
Service Worker 机制最主要的应用之一就是缓存文件,以便在离线状态下能够快速响应。Service Worker 缓存提供了两种缓存策略:默认策略和自定义策略。
默认策略:
默认情况下,Service Worker 会优先从网络中加载资源,当网络资源无法访问时,Service Worker 才会从缓存中加载资源。当页面发生变化时,Service Worker 也会相应地更新缓存。
自定义策略:
开发者也可以自定义缓存策略,实现更灵活的缓存方案。可以使用 Cache API 将需要缓存的资源存储到缓存中,并在需要时调用缓存进行存取操作。
二、 Service Worker 应用实例
下面使用一个缓存 fetch 请求的 Service Worker 应用来解析 Service Worker 在实际应用中的应用。这个应用的实现过程包含如下几个步骤:
首先,建立一个简单的 Web 应用,使用 fetch 方法获取 API 数据并展示到页面上。
在新建一个 sw.js 文件,服务于 Service Worker,并在其中缓存需要使用的页面资源,以及通过 on fetch 事件来缓存并返回 API 数据。
在页面中完成 Service Worker 的注册和安装,并通过 fetch 方法来实现 Service Worker 的缓存和使用。
完整代码如下:
1、index.html
<html> <head> <meta /> <title>PWA 技术解析:Service Worker 原理和应用</title> <link /> <script></script> </head> <body>2、app.js
var itemContainer = document.querySelector(".items");
fetch("http://jsonplaceholder.typicode.com/posts") .then(function(response) { return response.json(); }).then(function(data) { data.forEach(function(item) { var element = document.createElement('div'); element.innerHTML = item.body; itemContainer.appendChild(element); }); }).catch(function(err) { console.log("Fetch error", err); });
3、sw.js
const CACHE_NAME = 'pwa-cache-v1'; const CACHED_URLS = [ '/', '/index.html', '/app.js' ];
self.addEventListener('install', function(event) { // 开始缓存文件 caches.open(CACHE_NAME).then(function(cache) { console.log('Opened cache'); return cache.addAll(CACHED_URLS); }) })
self.addEventListener('fetch', function(event) { // 进行请求和缓存处理 event.respondWith( caches.match(event.request).then(function(response) { // 请求命中缓存时,返回缓存数据 if (response) { return response; }
// www.javascriptcn.com code example
// 请求未命中缓存时,发起新请求
var fetchRequest = event.request.clone();
return fetch(fetchRequest).then(function(response) {
// 需要缓存,先进行缓存
if (response.status === 200 && response.type === 'basic') {
var responseToCache = response.clone();
caches.open(CACHE_NAME).then(function(cache) {
cache.put(event.request, responseToCache);
});
}
// 返回请求数据
return response;
});
})
);});
4、index.html 中增加 Service Worker 的注册和安装代码
if ('serviceWorker' in navigator) { window.addEventListener('load', function() { navigator.serviceWorker.register('/sw.js').then(function(registration) { // 注册成功后 console.log('ServiceWorker registration successful with scope: ', registration.scope); }).catch(function(err) { console.log('ServiceWorker registration failed: ', err); }); }); }
通过这个 Service Worker 应用实例,我们可以看出 Service Worker 的缓存机制具有非常高的可定制性,可以为 Web 应用提供离线访问的能力,这是普通 Web 应用难以实现的功能。
结语:
Service Worker 是 PWA 实现的重要组成部分,它可以让 Web 应用具有像原生应用一样的离线、网络代理和脱机缓存的能力。Service Worker 的缓存机制具有非常高的可定制性,可以为 Web 应用提供离线访问的能力。通过深入理解 Service Worker 原理和应用,我们可以为 Web 应用的开发提供更多的思路和方案。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d01d29e46428fe9ecbc898