PWA应用|轻应用

如果 Chrome 浏览器版本比较新就可以直接让其安装到桌面上作为应用来处理:

image

无论手机还是桌面浏览器都能将网页安装到桌面从而变成 APP 来使用.

这里实现的方法其实十分简单, 只需要在 html 页面上追加 manifest 声明网页元数据:

1
2
3
<head>
<link rel="manifest" href="manifest.json">
</head>

这里的 manifest.json 就是声明 PWAJSON 格式配置文件, 实际上就是相当于调用本地浏览器的 Web 应用入口,
也就是 轻应用 的概念的由来, 无须复杂的桌面|移动端开发来构建的应用.

manifest.json 配置是所有浏览器通用的, 这里提供 Mozilla
的官方说明: Mozilla Manifest

配置的样例如下:

lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
{
"name": "HackerWeb",
"short_name": "HackerWeb",
"start_url": ".",
"display": "standalone",
"background_color": "#fff",
"description": "A simply readable Hacker News app.",
"icons": [
{
"src": "images/touch/homescreen48.png",
"sizes": "48x48",
"type": "image/png"
},
{
"src": "images/touch/homescreen72.png",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "images/touch/homescreen96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "images/touch/homescreen144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "images/touch/homescreen168.png",
"sizes": "168x168",
"type": "image/png"
},
{
"src": "images/touch/homescreen192.png",
"sizes": "192x192",
"type": "image/png"
}
],
"related_applications": [
{
"platform": "web"
},
{
"platform": "play",
"url": "https://play.google.com/store/apps/details?id=cheeaun.hackerweb"
},
{
"platform": "windows",
"id": "example.app1"
},
{
"platform": "amazon",
"url": "https://www.amazon.com/product/dp/B000XA1000"
}
]
}

这里挑选需要说明的配置讲解:

  • name: 应用名称, 安装之后显示的应用名称
  • short_name: 短名, 在名称过长的时候展示的缩略名称
  • start_url: 启动的应用路径, 支持网页路径和本地相对路径, 这里地址可以追加 ?utm_source=pwa 识别启动的地址
  • description: 应用详情信息, 可以显示应用具体描述信息, 可有可无的添加项
  • theme_color: 启动时的边框和页面主题色, 用于让应用颜色让更加贴合应用内部, 可有可无的添加项
  • display: 启动时候的显示方式, 常规采用 standalone 处理, 具体显示模式:
    • fullscreen: 启动时候应用采用全屏覆盖屏幕, 注意他会尽可能隐藏浏览器UI并让内容填充屏幕
    • standalone: 启动时候象独立应用一样屏蔽隐藏掉本来浏览器的界面(导航栏、工具栏等), 让其更类似独立应用
    • minimal-ui: 和 standalone 类似, 但是不同的是他会尽可能UI缩小成按钮, 不同浏览器会呈现不同显示效果
    • browser: 浏览器默认配置, 启动时候和打开浏览器一致
  • orientation: 应用的显示方向, 桌面应用感知不到, 但是移动端有竖屏和横屏应用来处理(还有平板电脑之类), 具体显示方向:
    • landscape-primary|landscape-secondary: 横屏状态, 对应是 +-90° 的横屏差别(也就是左|右偏移的方向)
    • portrait-primary|portrait-secondary: 竖屏状态, 也是对应 +-90° 的竖屏差别
    • landscape: 会按照不同设备平台自由切换 landscape-primary|landscape-secondary, 也就是横屏处理
    • portrait: 同上, 都是按照设备平台来处理切换 portrait-primary|portrait-secondary, 也就是竖屏处理
    • natural: 同上, 按照设备自由切换成 portrait-primary(竖屏)|landscape-primary(横屏), 不同 any 自由旋转角度的强制方向
    • any: 根据屏幕旋转角自由切换 landscape-primary|landscape-secondary|portrait-primary|portrait-secondary 配置
  • icons: 设备显示图标的列表, 用于指定轻应用的图标尺寸等信息, 也是比较关键配置项
    • src: 图标URL地址, 支持 URL 和本地相对图标
    • type: 图标的 MIME 类型, 不填写浏览器也会采用默认图片处理去匹配检索对应类型, 建议最好 image/png 并直接声明
    • sizes: 图标宽高, 注意如果单个图片支持多种尺寸可以通过空格声明, 如 48x48 96x96 128x128 这样声明支持多尺寸图标
  • prefer_related_applications: 用于是否弹出安装原生本地 app 应用的提示, 默认为 false, 详情见下.
  • related_applications: 只有在 prefer_related_applications:true 情况下才会生效用于转原生应用下载平台地址.
    • platform: 必须填写的下载平台, 比较常见的 play(Google商店)|itunes(苹果商城)|windows(Win桌面),
      具体可见 平台声明
    • url: 下载的平台跳转的 URL 地址
    • id: 应用下载平台上表示应用程序的标识 ID

以上就是比较常用到的 PWA 配置项目, 具体可以按照自身所需的情况处理从而开发泛用的轻度应用.

关于 display 配置, 可以通过 display-mode 这个查询条件去指定在不同的显示类型下不同的显示样式, 如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/* display:fullscreen 适用的 CSS 样式 */
@media all and (display-mode: fullscreen) {
body {
margin: 0;
}
}

/* display:standalone 适用的 CSS 样式 */
@media all and (display-mode: standalone) {
body {
margin: 1px;
}
}

/* display:minimal-ui 适用的 CSS 样式 */
@media all and (display-mode: minimal-ui) {
body {
margin: 2px;
}
}

/* display:browser 适用的 CSS 样式 */
@media all and (display-mode: browser) {
body {
margin: 3px;
}
}

站点在同一浏览器中被访问至少两次的时候, 默认会调用浏览器的安装提示引导应用去将 PWA 应用安装到本地, 这里提供 JS
事件来用于监听处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// 判断用户是否安装此应用
// beforeinstallprompt 事件返回一个名为 userChoice 的 Promise 对象, 并在当用户对横幅进行操作时进行解析
// promise 会返回属性 outcome, 该属性的值为 dismissed 或 accepted, 如果用户将网页添加到主屏幕, 则返回 accepted
window.addEventListener('beforeinstallprompt', function (e) {
// beforeinstallprompt event fired
e.userChoice.then(function (choiceResult) {
if (choiceResult.outcome === 'dismissed') {
console.log('用户取消安装应用');
} else {
console.log('用户安装了应用');
}
});
});

// 取消或延迟安装横幅的触发事件
// 网站虽然不能主动触发安装横幅的显示事件, 但是当该事件被浏览器触发之后, 可以对其进行取消或者延迟
// 通过阻止 beforeinstallprompt 事件的默认行为, 即可取消横幅弹出
window.addEventListener('beforeinstallprompt', function (e) {
e.preventDefault();
return false;
});


// 通过按钮点击事件触发横幅显示
// 阻止系统默认的安装弹出, 让网页按钮接管安装弹出从而安装到本地
var dfdPrompt = null;
var button = document.getElementById('btn');// 自定义点击按钮

// 禁用系统默认弹出
window.addEventListener('beforeinstallprompt', function (e) {
dfdPrompt = e; // 存储事件
button.style.display = 'block'; // 显示按钮
e.preventDefault(); // 阻止默认事件
return false;
});

// 按钮触发弹出安装下载
button.addEventListener('click', function (e) {
if (dfdPrompt == null) {
return;
}
dfdPrompt.prompt(); // 通过按钮点击事件触发横幅显示

// 监控用户的安装行为
dfdPrompt.userChoice.then(function (choiceResult) {
alert(choiceResult.outcome);
});
button.style.display = 'none'; // 隐藏按钮
dfdPrompt = null;
});

PWA 应用可以依托浏览器技术开发出更加编写的轻度应用, 不需要复杂安卓|iOS打包技术从而降低开发难度;
但很多原生系统功能只能看浏览器的规范支持, 同时对于网络依赖也更深(网络中断连本地资源都无法加载).

不过回过头来说很多应用功能大部分比较简单, 如果后面扩展起来最多 prefer_related_applications 设为 true 引流转原生应用也可以.