PWA 具备的特性
- 响应式
- 独立于网络连接
- 类似原生应用的交互体验
- 始终保持更新
- 安全
- 可发现
- 可重连
- 可安装
- 可链接
因此可以构建能应对不断变化的网络状况或无网络连接的网站(没有 PWA 的网站断网情况直接展示无法访问此网站,且没有友好提示),提供更好的浏览体验
PWA 是增强浏览器体验的,如果当前浏览器不支持 PWA,也可以作为普通的网站运行。
Service Worker:PWA 的关键
可以深入网络请求并构建更好的 Web 体验,允许将网站“添加”到设备主屏幕上,看起来更像原生应用,可以选择性缓存部分网络资源以提供离线体验
Service Worker的特点:
-
运行在它自己的全局脚本上下文中
-
不绑定到具体的网页
-
无法修改网页中的元素,因为它无法访问DOM
-
只能使用HTTPS
Service Worker能够拦截进出的HTTP请求,从而完全控制你的网站
“将你的网络请求想象成飞机起飞。Service Worker是路由请求的空中交通管制员。它可以通过网络加载,甚至通过缓存加载。”它可以让你全权控制网站中所有进出的网络请求。这种能力使它们极其强大,并允许你决定如何响应请求。 -
由于Service Worker运行在worker上下文中,意味着无法访问DOM
-
它与应用的主要JavaScript运行在不同的线程中,因此不会被阻塞
-
因为完全异步,一次无法使用诸如同步XHR和localStorage之类的功能
Service Worker的生命周期
当第一次加载页面时,Service Worker还没有激活,所以它不会处理任何请求。只有当它安装和激活后,才能控制在其范围内的一切。这意味着,只有刷新页面或者导航到另一个页面,Service Worker内的逻辑才会启动
在Service Worker安装过程中,可以获取资源并为下次访问准备好缓存
发起的任意HTTP请求,可以检查资源是否存在于缓存中,如果不存在,再通过网络检索它们
当进入动态内容请求的fetch事件时,可以决定是否缓存它们
简单的缓存示例
- 注册了Service Worker文件的简单HTML页面
- service-worker.js中的代码
在Service Worker的install事件里,一旦缓存开启,就开始把资源(在sw安装期间缓存重要资源,称为预缓存)添加进去。接下来调用cache.addAll()并传入文件数组。event.waitUntil()方法使用JavaScript的Promise来知晓安装所需时间及是否安装成功。
值得注意的是,如果所有的文件都成功缓存了,Service Worker便会安装完成,如果有任何文件下载失败,安装过程也随之失败。 意味着决定在安装步骤中缓存的文件列表要格外注意,多缓存一个文件就多一分Service Worker安装失败的风险。
- 添加到Service Worker中以开始监听fetch事件的代码
- 效果
拦截并缓存实例
- 显示谷歌字体的基础网页
- 在sw文件中添加代码
- 先通过添加事件监听器进入fetch事件
- 检查请求资源是否存在于缓存,存在则返回缓存并不继续执行代码,否则继续
- 如果缓存中没有请求资源,则按原计划发起网络请求,在代码进一步执行之前,需要复制请求(请求是一个流,之前判断是否在缓存中已使用过一次,接下来发起HTTP请求还要再使用一次,所以要复制一份)
- 检查HTTP响应,如果是成功响应,则复制响应写入到缓存以便下次使用它,然后最终返回原响应
- 效果
整合代码
- 在运行期间预缓存和缓存资源的Service Worker代码