第一章 理解PWA

1.1 PWA有什么优势

  • 响应式
  • 独立于网络连接
  • 类似原生应用的交互体验
  • 始终保持更新
  • 安全
  • 可发现
  • 可重连
  • 可安装
  • 可链接

1.2 PWA基础

这些应用不通过应用商店进行打包和部署,它们只是汲取了所需要的原生应用功能的网站而已。

1.3 Service Worker:PWA的关键

PWA 功能的关键在于 Service Worker。如果浏览器不支持 Service Worker,也能简单降级为普通的网站。

1.3.1 理解 Service Worker

Service Worker 有以下几个特点:

  • 运行在它自己的全局脚本上下文中;
  • 不绑定到具体的网页;
  • 无法修改网页中的元素,因为它无法访问 DOM;
  • 只能使用 HTTPS。

Service Worker 运行在 worker 上下文中,意味着它无法访问 DOM,与应用的主要 JavaScript 运行在不同的线程中,不会被阻塞。

1.3.2 Service Worker 生命周期

  1. 用户导航到一个 URL;
  2. 在注册(调用 register 函数)过程中,浏览器下载、解析和执行 Service Worker;
  3. 一旦 Service Worker 执行,就激活安装事件;
  4. 如果成功,Service Worker 现在就可以控制客户端并处理功能事件。
  5. 如果失败,register() 返回的 Promise 会执行 reject 操作,并且 Service Worker 会被废弃。

当第一次加载页面时,Service Worker 还没有激活,所以不会处理任何请求。只有刷新页面或者导航到另一个页面,Service Worker 内的逻辑才会启动。

1.3.3 Service Worker 基础示例

假设创建了一个 Service Worker 文件,命名为 sw.js。需要在页面 HTML 中做如下操作:

1
2
3
4
5
6
7
8
9
10
11
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./sw.js')
.then(function(registration) {
// 注册成功
console.log('Service Worker registration successful with scope: ', registration.scope);
})
.catch(function(err) {
// 注册失败
console.log('ServiceWorker registration failed: ', 'err');
});
}

Service Worker 是事件驱动的,最强大的功能之一就是允许通过进入不同的事件来监听任何网络请求。

1
2
3
4
5
self.addEventListener('fetch', function(event) {
if (/\.jpg$/.test(event.request.url)) {
event.respondWith(fetch('/images/unicon.jpg'));
}
})

上例监听了 fetch 事件,如果 HTTP 请求的是 JPG 文件,就拦截请求并强制返回一张指定图片。

1.3.4 安全考虑

为了让 Service Worker 能在网站上运行,需要通过 HTTPS 来提供服务。