前端也在进行不断的发展与革新,Web App 是否能弥补自身的不足呢?

浏览器还缺什么?

探索 Service Worker 前,我们思考一下为什么移动端 web 应用不能长期留住用户?假设我要使用 web 版淘宝购买商品,首先我要打开一个浏览器输入 taobao.com ,然后等待页面加载,然后再输入账号密码登录,再进行购物,我们发现以下几点用户体验非常不好的过程:

  • 输入长英文 url ,谁都不想在手机那么小的屏幕上输入长英文
  • 在手机浏览器浏览 Web App 时,浏览器顶部的 url 导航栏与底部的 BottomBar 占了屏幕一大部分,并且随着我滑动与停止,会 出现/消失 并存,这让我的注意力无法集中在 Web App 上
  • 当我与卖家沟通的时候,这个时候我切换到微信,卖家发消息给我时,我是无法知道的,因为系统不会给我推送通知。
  • 当我第二次还想使用该 Web App 时,我又要重新输入一次 url ,作为一个不带大脑的用户,是不会有这么耐心的
  • 当我想使用一个无需联网的的功能时,断网的情况下是无法打开网页的
  • 访问 Web App 跳转多个页面将会消耗大量浏览,而且这个跳转是需要加载的,不能做到秒开的效果

分析以上原因,我们大概能知道为什么移动端 Web App 无法留住用户,因为目前(指PWA还未出现时)浏览器还不支持以下功能:

  • 将应用添加到桌面,让用户快速访问
  • 无法将 web 扩展到整个屏幕
  • 无法推送 web 应用消息
  • 无法离线访问

为了稳固 Web 在移动端的地位,W3C 和 Google 针对性的解决以上问题,提出了 PWA 渐进式网页引用的概念。

什么是 PWA

PWA 的中文翻译叫渐进式网页应用,在2014年 W3C 便公布了 Service Worker 的相关草案,在 2015 年被 Chrome 支持,那么 Service Worker 与 PWA 又有什么关系呢?

首先我们需要明确的一点是,PWA 不是指某一项技术,而是指使用了多项技术的 Web App,这面的包括 App Manifest、Service Worker、Web Push 等,而最重要的技术就是 Service Worker ,所以说 Service Worker 的出现作为 PWA 的诞生时间。

从2015年, PWA 在不断升级优化,增强了用户体验,也提高了用户留存率,它具有类似于原生 APP 的交互,即时更新、可推送、可安装、可离线访问。

PWA 核心特点

可安装

我们这里所说的可安装不是传统意义上的安装APP,而是在用户使用浏览器访问 Web App 时,将该 Web App 添加到主屏,方便下次直接访问,特别要注意的是,这个特点与离线可访问是没有关系的,关于可离线访问的实现方案,我们下面会简单解释。

我们可以视为在主屏幕上添加了一个浏览器容器(去除 url 导航栏与底部 BottomBar),该容器设置了初始 url ,点击后能够直接访问。

我们使用 IOS 系统的手机,访问微博 Web App (https://m.weibo.cn)。
image

首先我们发现 图1 中是原生浏览器打开一个页面,顶部和底部都有一大片与内容无关的功能区域,接着我们点击 1标记 调出功能栏添加至主屏幕,然后进入 图3 中的确认信息,这里我们能看到该 Web App 的 icon 、名称、初始url,点击添加后,我们在主屏幕就能直接访问该 Web App,如图:

image

点击打开后,我们惊喜的发现能够秒开,而且没有烦人的顶部底部多余区域,就像访问原生的 APP 一样。

关于这里面的技术细节,我们可以在访问该页面时候进行抓包,找到一个manifest.json文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"name": "微博Lite",
"short_name": "微博",
"description": "随时随地分享新鲜事",
"icons": [
{
"src": "https://h5.sinaimg.cn/m/weibo-lite/icon-default-192.png",
"sizes": "192x192",
"type": "image/png"
}
],
"start_url": "/?standalone=1",
"display": "standalone",
"orientation": "portrait",
"background_color": "#F3F3F3",
"theme_color": "#F3F3F3",
"related_applications": [],
"prefer_related_applications": false
}

这个文件主要是描述 Web App 添加到主屏幕后的信息,我们简单列出:

  • start_url:启动网址
  • icons 添加到主屏幕图标
  • background_color 背景颜色
  • theme_color 主题颜色
  • display 启动样式

这里我们不赘述,具体可以查看官方文档:
The Web App Manifest

离线访问

我们打开原生 App 时,因为 App 的资源包是安装在手机里的,所以不需要加载资源,因此能够离线访问,而这一点在 Web 是无法做到的,但是 Service Worker 的出现改变了该局面,当用户第一次访问该页面时,将资源文件缓存到手机中,等第二次加载时,直接从缓存里面拉取,所以才能做到秒开并且可离线访问的效果。

image

我们可以看到,当手机没有任何网路链接时,依然能够打开 Web App,并且保留之前的数据展示给用户。

我们在这里简单的讲解解释其实现原理,以下是 Service Worker 的部分源码:

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
var cacheName = 'latestNews-v1';

// 首次加载
self.addEventListener('install', event => {
event.waitUntil(
caches.open(cacheName)
// 缓存资源文件
.then(cache => cache.addAll([
'/main.js',
'/style.css',
]))
);
});

// 第二次打开,监听 fetch 事件
self.addEventListener('fetch', function(event) {
event.respondWith(
// 获取的资源与缓存文件匹配上,则直接返回缓存中的资源
caches.match(event.request)
.then(function(response) {
if (response) {
return response;
}
return fetch(event.request);
}
)
);
});

简单来说,就是第一次将资源放入缓存,当第二次打开时,相同的资源能够直接从缓存中获取,于是能够实现秒开与离线访问。

消息推送

我们思考一下,消息推送的原理是什么,又分为几种推送,举个例子,比如一个 Web App 提供闹钟服务,那么推送消息的时,Web App 本身就能提供该提醒,无需与后端服务进行通信。再举一个例子,Web App 要给你推送当天的新闻,这个时候 Web App 就需要与后端进行通信,后端服务将需要新闻推送给 Web App。

从上面两个例子分析得到,我们有两种推送,在 PWA 概念中,恰好存在以下两种推送:

  • Push API:将目标浏览器作为唯一标识,后端向浏览器推送信息,浏览器接收信息进行展示。
  • Notification API:无需与后端通信,浏览器本身 API ,可以向用户发送通知,并且在通知的栏目上能够进行一些交互操作。

Push API 和 Notification API 其实是两个独立的技术,完全可以分开使用;不过Push API 和 Notification API相结合是一个常见的模式,比如浏览器接收 Push API 发送的信息,将该信息专递给 Notification API 展示,并且提供一些交互操作,两种 API 结合使用就能在用户关闭该 Web App 进行推送,这就弥补了 Web App 无法进行消息推送的缺陷。

总结

我们通过发现 Web App 存在的问题来探索 PWA 的特性,了解了其缘由以及主要特点,并且简单地学习了实现方案,目前来说,PWA 在各大厂商都进行了实践,并且取得了较好的用户体验收益,我们也能体会到,随着时代的演进,Web 技术的发展也一直没有停滞,PWA 在是否适合用在项目里还需要分析具体使用场景和实现成本,不管怎样,PWA 赋予了 Web App 强大的能力,我们需要尽可能地将用户体验做到极致