前言
这篇文章所采用的chrome浏览器版本为72,如有疑虑,请留言讨论,谢谢。
您将在这篇文章中学习到:
- 什么是PWA
- PWA的工作原理
- 如何给自己的hexo静态博客实现PWA
- Service worker生命周期
- Service worker自动更新
什么是PWA
PWA,即Progressive-Web-App
,渐进式网络应用,概念有点类似于微信小程序,和MIUI的快应用,但是比他们更简单,没有平台依赖性,你只需在浏览器中访问支持PWA的网页,就能收到安装提示。
PWA可以
- 让你离线浏览内容,摆脱对于网络的束缚
- 提示安装到桌面,提升用户粘性/依赖度
- 即使没有打开网页,也能主动推送通知
- 即刻安装,免除对于存储空间的考虑
最终效果一览
手机
PC
PWA工作原理
W3C 组织早在 2014 年 5 月就提出过 Service Worker 这样的一个 HTML5 API ,主要用来做持久的离线缓存。
浏览器中的 javaScript 都是运行在一个单一主线程上的,在同一时间内只能做一件事情。随着 Web 业务不断复杂,我们逐渐在 js 中加了很多耗资源、耗时间的复杂运算过程,这些过程导致的性能问题在 WebApp 的复杂化过程中更加凸显出来。
Service Worker 有以下功能和特性:
- 一个独立的 worker 线程,独立于当前网页进程,有自己独立的 worker context。
- 一旦被 install,就永远存在,除非被手动 unregister
- 用到的时候可以直接唤醒,不用的时候自动睡眠
- 可编程拦截代理请求和返回缓存文件,缓存的文件可以被网页进程
fetch
到 - 离线内容开发者可控
- 能向客户端推送消息
- 不能直接操作 DOM
- 必须在 HTTPS 环境下才能工作
- 异步实现,内部大都是通过
Promise
实现
所以我们基本上知道了 Service Worker 的伟大使命,就是让缓存做到优雅和极致,让 Web App 相对于 Native App 的缺点更加弱化,也为开发者提供了对性能和体验的无限遐想。[1]
实现过程
Chrome 将在您的应用符合以下条件时自动显示横幅(添加到桌面的提示):
- 拥有一个网络应用清单文件(manifest.json),该文件至少具有:
- 一个
short_name
(用于主屏幕) - 一个
name
(用于横幅中) - 一个 192x192 png 图标(图标声明必须包含一个 mime 类型的
image/png
) - 一个加载的
start_url
- 一个
- 拥有一个在您的网站上注册的服务工作线程(service worker)
- 通过HTTPS提供(这是使用服务工作线程的一项要求)。
- 被访问至少两次(第一次访问执行安装和激活,第二次访问生效,提示安装到桌面),这两次访问至少间隔五分钟。
创建manifest.json文件
在您博客的根目录下面的source
文件夹创建一个manifest.json
- 在用户主屏幕上用作文本的
short_name
。 - 在网络应用安装横幅中使用的
name
。 - 利用适当命名的
background_color
属性指定背景颜色。 Chrome 在网络应用启动后会使用此颜色和name
和512x512的icon展示第一屏。 - 使用
theme_color
在您hexo博客的主题的layout.ejs
等文件,属性指定主题颜色。
|
|
在
source
文件夹下面的文件会被hexo解析,如果您有插件会处理这些文件(如:hexo-translate-title
,建议您在博客项目的_config.yml
文件skip_render
项添加一个子项:
skip_render: ['manifest.json']
或
skip_render:
- manifest.json这两种写法都是正确的,可以确保
manifest.json
不被hexo和其他插件解析,更改内容;而且放在source
目录下面的文件,在执行hexo g
或hexo s
后,最终都会复制到网站根目录。🙃
将manifest的相关信息告知浏览器
在您创建清单文件之后,将 link
标记添加到layout.ejs
页面上,如下所示:
|
在您主题的layout.ejs
中添加一些meta标签
|
其中的
apple-mobile-web-app-status-bar-style
值,可以设为:default
,black
orblack-translucent
If set to black-translucent, the status bar is black and translucent. If set to default or black, the web content is displayed below the status bar. If set to black-translucent, the web content is displayed on the entire screen
创建service worker
在您博客的根目录下面创建一个文件夹,暂时叫他static_files
,在里面创建一个js文件:sw.js
目的是使用hexo事件,动态生成带有时间戳的
sw.js
到最终的输出的public
目录去。PS:
sw.js
只能放在网站根目录下,它的作用域就是您sw.js
文件放置的目录。
|
- install 事件会绑定在 Service Worker 文件中,在 Service Worker 安装成功后,
install
事件被触发。install
事件一般是被用来填充浏览器的离线缓存能力。为了达成这个目的,使用了 cache API ,它使我们可以存储网络响应发来的资源,并且根据它们的请求来生成key。它会一直持久存在,直到你告诉它不再存储,你拥有全部的控制权。 - 当 service worker 安装完成后,会接收到一个激活事件(activate event)。
activate
主要用途是清理先前版本的service worker 脚本中使用的资源。 fetch
事件在您刷新网页的时候,会在您的缓存里面找,如果没有缓存才去做http请求。
更新你的service worker
如果您的 service worker 已经被安装,但是刷新页面时有一个新版本的可用,新版的 service worker 会在后台安装,但是还没激活。当不再有任何已加载的页面在使用旧版的 service worker 的时候,新版本才会激活(也就是说,关闭浏览器窗口之后,再重新打开)。一旦再也没有更多的这样已加载的页面,新的 service worker 就会被激活。
这也就是为什么我们要动态生成cacheName
,让他以时间为后缀。
在service worker 里的 install
事件监听器里面,删除旧的缓存。
启用service worker
在您博客的js文件中,加入以下代码:
|
这样就能成功注册了。
主动提示用户添加到桌面
在chrome68之前,会自动提示,但是在68之后,必须开发人员监听beforeinstallprompt
事件,来提示用户安装到桌面:
请使用
deferredPrompt
延迟的提示,保存提示事件。PS:如果在beforeinstallprompt
里面直接调用e.prompt()
函数,会报错(prompt is not a function)没有此函数。
|
下面代码使用Materialize
框架的toast
功能,展示一个弹窗提醒用户安装:
|
或自定义一个按钮来让用户主动触发安装(您需要在页面上写一个和自己代码相匹配的,如class="ad2hs-prompt"
的标签)[2]:
|
真正的Chrome级提示用户安装[2:1]:
|
使用hexo的generateAfter事件生成sw.js
在您博客的根目录下创建scripts
文件夹,在里面创建events.js
:
PS:这个是hexo的固定写法,hexo会在生成网站之前执行项目根目录下
scripts
文件夹下的所有js脚本。[3]
|
这时候再执行hexo g
,就能看到public
文件夹下面生成了sw.js
,打开即可看见第一行类似于这样:
|
这样浏览器在获取到这个sw.js
的时候,就能知道网站被更新了,而且缓存也会被更新。
测试
lighthouse
运行 Lighthouse 的方式有两种:作为 Chrome 扩展程序运行,或作为命令行工具运行。 Chrome 扩展程序提供了一个对用户更友好的界面,方便读取报告。 命令行工具允许您将 Lighthouse 集成到持续集成系统。[4]
Chrome 扩展程序
转到您要进行审查的页面。
点击位于 Chrome 工具栏上的 Lighthouse 图标。
接下来就会进行自动化的web测试
如果您是第一次做PWA应用,十有六七会失败在这一步,请您按照lighthouse的指示优化您的网页,这样才能正常使用,向用户主动提示安装到桌面。
使用F12审查
在浏览器中按下F12,进入Audits选项卡,点击开始审查
命令行工具
安装 Lighthouse 作为一个全局节点模块。
|
针对一个页面运行 Lighthouse 审查。
|
审查结束后自动打开审查报告
|
其他工具
-
PWA检查列表,包含对于PWA应用详细且近乎严苛的要求:
https://developers.google.com/web/progressive-web-apps/checklist
-
网速测试工具,使您的网页在所有设备上都能快速加载:
-
测试网页性能,Test a website’s performance:
结语
- PWA目前在苹果设备上支持非常差,只能由用户主动点击分享按钮,添加到桌面,而且在这个图标里面点击任意
a
标签,都会打开safari浏览器,用户体验极差。(iOS12.2以前版本,iOS12.2修复了都会打开safari浏览器的这个用户体验问题) - PWA目前在安卓手机上安装后,可以把apk提取出来,发送给朋友,如果朋友没有安装Chrome浏览器,则会被提示需要安装Chrome浏览器才能继续。
我们将在下一篇文章中介绍如何摆脱需要Chrome浏览器的限制。
其他文章
参考资料
Service Worker 简介 https://lavas.baidu.com/pwa/offline-and-cache-loading/service-worker/service-worker-introduction ↩︎
How to Use the ‘beforeinstallprompt’ 🔔 Event to Create a Custom PWA Add to Homescreen Experience 👍 https://love2dev.com/blog/beforeinstallprompt/ ↩︎ ↩︎
使用 Lighthouse 审查网络应用 https://developers.google.com/web/tools/lighthouse/ ↩︎ ↩︎