PWA 的核心技术
前文提到,PWA 的核心是用户体验,能让 PWA 达到原生应用的体验并不仅仅依赖于某一项技术,而是多管齐下,进行改进,从而在安全、性能和体验上都获得很大的提升。下面将简单介绍几个 PWA 应用中经常使用到的技术,后面的章节会进行更详细的讲解。
Web App Manifest
Web App 是依附于浏览器的,在一般情况下,用户需要先打开浏览器,然后输入网址或点击收藏的书签,才能够访问到网页内容,相比在移动设备主屏上拥有一席之地的 Native App,Web App 使用起来太麻烦了,这也是 Native App 相比 Web App 用户黏性更好的原因之一。因此 Web App 也需要这个能力,Web 应用清单(Web App Manifest)能够帮助我们实现这一点,也是 PWA 最核心的功能之一,开发者可以定义用户添加到主屏的图标、应用名称等,也许有人会说,有些移动设备上的浏览器可以在主屏上添加网页的快捷方式,但其实用户体验区别很大,Web App Manifest 允许开发者配置隐藏浏览器多余的 UI(地址栏,导航栏等),让 PWA 具有和 Native App 一样的沉浸式体验。
Web App Manifest 体现在代码上主要是一个 JSON 文件:manifest.json
,开发者可以在这个 JSON 文件中配置 PWA 的相关信息,应用名称、图标、启动方式、背景颜色、主题颜色等等。添加到桌面后,PWA 并不是一个快捷方式,而是能够在系统中作为一个独立的 App 存在的,用户可以设置它的权限,清除它的缓存,就和 Native App 一样。
添加主屏的好处是显而易见的,首先它缩短了用户和站点的距离,用户可以在主屏直达站点;其次是能够让网站具有更加接近 Native App 的体验,具有启动画面、沉浸式浏览体验;最后,PWA 会被系统的应用商店收录,目前只有 Windows 10 这样做了,但是可以预见在不远的将来,其他的主流平台也会进行收录。
Service Worker
在前文中,频繁的提及 Service Worker 是因为它真的很重要,毫不夸张的说,Service Worker 就像人体中心脏一样的存在,如果没有它,PWA 就像没有了动力,无法寸进。
Service Worker,直白的翻译就是服务工作线程,但一般我们不会这么做。它是浏览器在后端独立于网页主进程运行的脚本,它可以拦截网络请求,可以操作本地缓存,还可以接受服务器推送的离线消息,它的功能很丰富,并且 Service Worker 可扩展性很强,想象空间比较大,未来 PWA 很多的特性会基于 Service Worker 来设计,这也是笔者为什么说它是 PWA 的心脏。
简单归纳一下,Service Worker 的特点,如下:
- 一个特殊的 worker 线程,独立于当前网页主线程,有自己的执行上下文
- 一旦被安装,就永远存在,除非显式取消注册
- 使用到的时候浏览器会自动唤醒,不用的时候自动休眠
- 可拦截并代理请求和处理返回,可以操作本地缓存,如 CacheStorage,IndexedDB 等
- 离线内容开发者可控
- 能接受服务器推送的离线消息
- 异步实现,内部接口异步化基本是通过 Promise 实现
- 不能直接操作 DOM
- 必须在 HTTPS 环境下才能工作
Service Worker 在 PWA 中最重要的功能就是离线与缓存,在本书第三章,还会有很多笔墨来介绍 Service Worker 如何实现站点离线。
离线通知
Service Worker 是 PWA 很多功能的基础,正是有了 Service Worker,其他功能才能发挥更大的作用,离线通知就是其中之一。
离线通知是指在用户没有打开 PWA 站点的情况下,也能接受到服务器推送过来的通知并展现给用户,其中包括了两部分,离线推送和展现通知,分别是 Web Push 和 Notification API。
推送通知是一种时效性非常强的与用户沟通的方式,即使在 PWA 没有打开的情况下,依然可以触达用户,能够立即引起用户的注意,对于一些突发事件、限时活动、重大升级等时效性要求很高的场景,推送通知总是最好的选择,这也是过去 Native App 强于 Web App 的原因之一。因此 PWA 提供了 Web Push 和 Notification API 补全了这一功能。
浏览器在接受到对应的消息服务中心推送过来的离线消息时,会唤醒对应站点注册的 Service Worker,开发者可以在 Service Worker 文件中处理接受到的请求,显示通知。
Web Push 和 Notification API 在后面的章节也会重点介绍。
App Shell 和骨架屏
App Shell 是 PWA 强调的一个非常重要的设计理念,它能够缩短用户进入页面时的白屏时间,让用户一进入 PWA 就能快速看到 PWA 的整体框架,就和 Native App 一样。从概念上讲,App Shell 是 PWA 界面展示所需的最小资源集合,即让页面能够正常运行起来的最小的 HTML、CSS 和 JavaScript 等静态资源集,每个页面都需要加载这一部分资源。利用 Service Worker 把这部分资源缓存在本地,就能够在打开 PWA 时不需要从服务器端获取这部分资源,从而能够瞬间渲染出页面框架,不仅提升了首屏的速度,还减小了站点流量的消耗。
骨架屏(App Skeleton),也是提升首屏体验的有效方式。它的原理是在真实内容渲染完成之前,使用一些能够快速渲染的静态图片/样式/色块/部分真实内容进行占位,让用户对真实内容区域有心理预期。App Shell 和骨架屏都是提升首屏体验的绝好妙招。
App Shell 和骨架屏相辅相成,App Shell 显示页面的外框部分,初始内容就用骨架屏来填充,保证主体内容区域不会留白,它的特点是:
- 在页面加载初期预先渲染内容,提升感官上的体验
- 一般情况骨架屏和实际内容的结构是类似的,因此之后的切换不会过于突兀。这点和传统的 Loading 动图不同,可以认为是其升级版
- 只需要简单的 CSS 支持 (涉及图片懒加载可能还需要 JS ),不要求 HTTPS 协议,没有额外的学习和维护成本
- 如果页面采用组件化开发,每个组件可以根据自身状态定义自身的骨架屏及其切换时机,同时维持了组件之间的独立性
App Shell 和骨架屏在提升首屏体验上发挥了重要作用,本书第二章会首先介绍,在了解了这部分内容之后,就能够很好的理解 App Shell 结合 Service Worker 的重要性。
以上四点是笔者认为对应 PWA 非常重要的技术,因此列出来,并且后续也会重点讲述,其他在这里没有提到的技术对于 PWA 来说也同样重要,在本书中不会重点讲述,但也会有所提及,开发者可以去阅读一些相关的文档或者标准,比如 MDN 站点。