PWA概念
PWA,全名 Progressive Web App,是提升Web App体验的一种新方法,它通过对应用的一系列改进,对应用在安全、性能和体验三个方面都有很大提升,使其兼具 Web App 和 Native App 的优点。
如下特点,可以解释为什么要选择PWA:
- 不限浏览器、不限设备:能访问Web应用的浏览器和设备均可使用;
- 原生应用的体验:Manifest的设置
- 持续更新:得益于Service worker,应用可以时刻保持最新;
- 可离线访问:这也是Service worker的功劳;
- 安全:通过HTTPS访问,保证了安全性;
- 安装方便:可以随时删除、随时安装,无需下载,节省流量;
- 部署便捷:这个优点开发人员应该深有体会,没有了繁琐的打包、加密、签名、审核过程。
简而言之,就是你的Web站点可以添加到移动设备的主屏幕,像原生应用一样安全的访问,且Android、iOS都支持,这就是PWA。
基本条件
一个合格的PWA应用必须具备如下条件:
- Web应用支持HTTPS
- 拥有 Web App Manifest 文件
- 成功注册了 Service worker
- 用户对站点的粘度符合一定条件
实现过程
明白PWA是咋回事了,就要动手开发了。既然是PWA是基于Web App的,那么Web App其实用可用任何前端框架实现。这里选用的是Angular + Ionic,为什么选用Ionic,原因是让应用的UI更接近原生应用,增强用户体验。
创建Ionic应用
使用如下命令创建应用:
ionic start pwa-app sidemenu --type=angular
这个命令会创建一个带有左侧菜单的Ionic应用,执行 ionic serve,便可看到效果。
改进应用
从PWA的概念可以看到,PWA应用需要Manifest文件、注册Service woker,这些开发者都可以自行手动添加,但是Angular已经提供了PWA的组件,方便进行这些改进。
执行如下命令,安装PWA组件:
ng add @angular/pwa
这个组件对应用进行了如下改进:
- 安装了如下组件:
"@angular/pwa": "^0.12.4",
"@angular/service-worker": "^7.2.2",
- 新增了如下文件:
src/ngsw-config.json
src//www.greatytc.com/manifest.json
src/assets/icons/icon-128x128.png
src/assets/icons/icon-144x144.png
src/assets/icons/icon-152x152.png
src/assets/icons/icon-192x192.png
src/assets/icons/icon-384x384.png
src/assets/icons/icon-512x512.png
src/assets/icons/icon-72x72.png
src/assets/icons/icon-96x96.png
- 修改了如下文件:
//app.module.ts:
import { ServiceWorkerModule } from "@angular/service-worker";
imports: [
...
ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production })
]
//index.html:
...
<link rel="manifest" href="//www.greatytc.com/manifest.json">
<meta name="theme-color" content="#1976d2">
...
//angular.json文件:
"assets": [
...
"src//www.greatytc.com/manifest.json"
],
此时,一个PWA应用的基本框架就搭建好了。
PWA应用界面设置
在src目录下可以找到名为manifest.json的文件,该文件的作用是允许开发者控制PWA添加到桌面,允许定制桌面图标、URL等等。示例内容如下:
{
"name": "app",
"short_name": "app22",
"theme_color": "#1976d2",
"background_color": "#fafafa",
"display": "standalone",
"scope": "/",
"start_url": "/",
"icons": [
{
"src": "assets/icons/icon-72x72.png",
"sizes": "72x72",
"type": "image/png"
},
...
]
}
参数解释如下:
- name:主屏幕上应用启动时,在splash界面显示的名称
- short_name:在浏览器中添加至主屏幕时显示的缺省名字
- theme_color:主题颜色
- background_color:背景颜色
- display:PWA应用显示的方式,可选值:fullscreen、standalone、browser,其中standalone是原生应用的观感,通常选此值
- icons:设置PWA应用的图标
- start_url:应用启动链接
关于manifest文件的详细说明,参见参考文档。
注意:上述配置仅对Android手机有效,对于iOS,需要在index.html文件中设置。
设置如下:
<!-- 苹果应用的名字-->
<meta name="apple-mobile-web-app-title" content="Wallet">
<!-- 允许使用独立模式显示Web内容-->
<meta name="apple-mobile-web-app-capable" content="yes">
<!-- 自定义苹果的图标-->
<link rel="apple-touch-icon" href="assets/ios/icon/icon-76.png">
<!-- 针对不同屏幕大小,使用不同图标 -->
<link rel="apple-touch-icon" sizes="120x120" href="assets/ios/icon/icon-76.png">
...
<!-- 自定义苹果启动界面的图片-->
<link rel="apple-touch-startup-image" href="assets/ios/splash/Default@2x~universal~anyany 2732 2732.png">
<!-- 针对不同屏幕大小,自定义苹果启动界面的图片-->
<!-- iPhone Xs Max (1242px x 2688px) -->
<link href="/assets/ios/splash/iphone5_splash.png" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image" />
...
<!-- 设置状态栏样式,black-translucent、 black、default-->
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
Service worker配置
在src目录下可以找到名为ngsw-config.json的文件,该文件中设置的缓存的策略,示例内容如下:
{
"index": "/index.html",
"assetGroups": [
{
"name": "app",
"installMode": "prefetch",
"resources": {
"files": [
"/favicon.ico",
"/index.html",
"/*.css",
"/*.js"
]
}
},
...
]
}
参数解释如下:
- index:缓存的路径,通常为/index.html
- assetGroups:需要缓存的assets进行分组
- name:每个分组的名字
- installMode、updateMode:初始缓存、更新缓存的模式,可选:prefetch(预先缓存)、lazy(请求时才缓存)
- resources:缓存的资源文件
在Chrome的调试工具 -> application -> Cache Storage下,可以看到缓存的内容。
使用http-server启动应用
由于Service worker配置的是生产环境下生效,开发测试时可以使用http-server组件创建一个Web服务器,安装命令如下:
npm install -g http-server
构建应用的产品包:
ionic build --prod
http-server ./www -p 8000
这样通过 127.0.0.1:8000 或者 localIP:8000 就能访问应用了。
测试PWA效果
使用浏览器
这里使用的是Chrome浏览器测试效果。
网页中输入 127.0.0.1:8000,在Chrome的调试工具中打开Application -> Manifest,见下图:
这里可以查看manifest.json文件内容,单击 “Add to homescreen”,看见浏览器弹出:
如果没有出现这个提示框,可以在Console中看到错误原因,多半是Service Worker没有注册成功。
在Service Workers中可查看Service worker的相关内容:
真机上测试
同时也可使用移动设备上的浏览器访问 localIP:8000,将此页面添加至移动设备的桌面,来查看PWA的效果。
Xcode中的iOS模拟器亦可进行测试。
Android和iOS上对PWA的使用有一些不同点,例如iOS可修改PWA应用的名字,Android可设置屏幕方向等。同时还有一些限制,比如iOS对于Native API没法使用等。具体内容见参考文档6。
使用Lighthouse评测Web应用
我们还可以采用更为专业的方法来对应用进行测评。这里推荐使用Lighthouse。它是一个开源的自动化Web应用评测工具,可参考其评测结果,对Web应用进行完善。
如果你使用Chrome浏览器,可以安装Lighthouse的组件,或者使用使用命令行方式进行改进。
在应用下执行:
npm install -g lighthouse
lighthouse your-url-path --view
//参数view会直接在浏览器中打开测试报告,例如:lighthouse http://127.0.0.1:8000/ --view
这样,就完成了一个PWA应用,可以浏览器、Android、IOS通吃了。惬意啊!
Ionic PWA Toolkit
除了上述配置方法外,Ionic还提供了一个开箱即用的PWA小工具——Ionic PWA Toolkit,使用它可以直接创建好一个PWA的应用。只是这个工具是基于Stencil的,待有时间了再研究下。
小结
上述方法不仅仅受限于Ionic或者Angular。PWA应用说白了还是一个Web应用,理论上讲对于任何的Web应用,只要参考PWA的标准对其进行改造,就可支持PWA,只是在改造前需要对现有应用做下评估,是否触碰了Android或iOS对PWA的限制。