DTeam 团队日志

Doer、Delivery、Dream

小试PWA

胡伟红 Posted at — Mar 26, 2019 阅读

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