小试PWA

2,425 阅读6分钟

原文链接

PWA概念

PWA,全名 Progressive Web App,是提升Web App体验的一种新方法,它通过对应用的一系列改进,对应用在安全、性能和体验三个方面都有很大提升,使其兼具 Web App 和 Native App 的优点。

如下特点,可以解释为什么要选择PWA:

  1. 不限浏览器、不限设备:能访问Web应用的浏览器和设备均可使用;
  2. 原生应用的体验:Manifest的设置
  3. 持续更新:得益于Service worker,应用可以时刻保持最新;
  4. 可离线访问:这也是Service worker的功劳;
  5. 安全:通过HTTPS访问,保证了安全性;
  6. 安装方便:可以随时删除、随时安装,无需下载,节省流量;
  7. 部署便捷:这个优点开发人员应该深有体会,没有了繁琐的打包、加密、签名、审核过程。

简而言之,就是你的Web站点可以添加到移动设备的主屏幕,像原生应用一样安全的访问,且Android、iOS都支持,这就是PWA。

基本条件

一个合格的PWA应用必须具备如下条件:

  1. Web应用支持HTTPS
  2. 拥有 Web App Manifest 文件
  3. 成功注册了 Service worker
  4. 用户对站点的粘度符合一定条件

实现过程

明白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/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="/manifest.json">
<meta name="theme-color" content="#1976d2">
...

angular.json文件:

"assets": [
    ...
    "src/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"
        },
        ...
    ]
}

参数解释如下:

  1. name:主屏幕上应用启动时,在splash界面显示的名称
  2. short_name:在浏览器中添加至主屏幕时显示的缺省名字
  3. theme_color:主题颜色
  4. background_color:背景颜色
  5. display:PWA应用显示的方式,可选值:fullscreen、standalone、browser,其中standalone是原生应用的观感,通常选此值
  6. icons:设置PWA应用的图标
  7. 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"
                ]
            }
        },
        ...
    ]
}

参数解释如下:

  1. index:缓存的路径,通常为/index.html
  2. assetGroups:需要缓存的assets进行分组
  3. name:每个分组的名字
  4. installMode、updateMode:初始缓存、更新缓存的模式,可选:prefetch(预先缓存)、lazy(请求时才缓存)
  5. 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.png

这里可以查看manifest.json文件内容,单击 “Add to homescreen”,看见浏览器弹出:

addToHome.png

如果没有出现这个提示框,可以在Console中看到错误原因,多半是Service Worker没有注册成功。 在Service Workers中可查看Service worker的相关内容:

service worker.png

真机上测试

同时也可使用移动设备上的浏览器访问 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的限制。

参考文档

  1. Manifest文件说明
  2. Ionic4中实现PWA
  3. Lighthouse介绍
  4. Service worker配置
  5. iOS 12.2对PWA的改进
  6. PWA 登陆 iOS