PWA,你需要知道的那些事
(ps: 有一段时间没发文了,忙得不可开交,之前团队分享PWA,答应大家整理出来,终于兑现了~)
PWA简介
PWA,英文全称是 Progressive Web App,2015年 由 Google 提出。PWA是提升 Web App的体验的一种新方法,能给用户原生应用的体验,兼具了 Web App 和 Native App 的优点。
PWA 主要特性
- 可靠 - 即使在不稳定的网络环境下,也能瞬间加载并展现;
- 体验 - 快速响应,并且有平滑的动画响应用户的操作;
- 粘性 - 像设备上的原生应用,具有沉浸式的用户体验,用户可以添加到桌面。
特点:
渐进式 - 适用于选用任何浏览器的所有用户,因为它是以渐进式增强作为核心宗旨来开发的。自适应 - 适合任何机型:桌面设备、移动设备、平板电脑或任何未来设备。
连接无关性 - 能够借助于服务工作线程在离线或低质量网络状况下工作。
类似应用 - 由于是在 App Shell 模型基础上开发,因此具有应用风格的交互和导航,给用户以应用般的熟悉感。
持续更新 - 在服务工作线程更新进程的作用下时刻保持最新状态。
安全 - 通过 HTTPS 提供,以防止窥探和确保内容不被篡改。
可发现 - W3C 清单和服务工作线程注册作用域能够让搜索引擎找到它们,从而将其识别为“应用”。
可再互动 - 通过推送通知之类的功能简化了再互动。
可安装 - 用户可免去使用应用商店的麻烦,直接将对其最有用的应用“保留”在主屏幕上。
可链接 - 可通过网址轻松分享,无需复杂的安装。
PWA 本身强调渐进式,但并不要求一次性达到安全、性能和体验上的所有要求,开发者可以通过 PWA Checklist 查看现有的特征。
PWA功能丰富,相比原生应用更加轻量。我们可以把 PWA 网站添加到桌面上,不管在PC端还是移动端,都类似于一个原生应用,并且拥有媲美原生应用的体验。它也拥有原生 APP 应用一般的启动闪屏,也可以进行消息推送——不过要知道,它源自 Web,通常只有传统 APP 的体积的十分之一甚至更小。它不用等待下载安装的时间,打开网页的时候就已经「下载」并且「安装」完毕。
APP Shell
App Shell 架构是构建 PWA 的一种方式,这种应用能可靠且即时地加载到您的用户屏幕上,与本机应用相似。
定义
App Shell 是支持用户界面所需的最小的 HTML、CSS 和 JavaScript,如果离线缓存,可确保在用户重复访问时提供即时、可靠的良好性能。这意味着并不是每次用户访问时都要从网络加载 App Shell。 只需要从网络中加载必要的内容。 看下面这张图来了解下:
构建单页应用时,可以使用APP Shell,它依赖渐进式缓存 Shell(使用服务工作线程)让应用运行。App Shell 非常适合用于在没有网络的情况下将一些初始 HTML 快速加载到屏幕上。
App Shell 应能完美地执行以下操作:
- 快速加载
- 尽可能使用较少的数据
- 使用本机缓存中的静态资产
- 将内容与导航分离开来
- 检索和显示特定页面的内容(HTML、JSON 等)
- 可选:缓存动态内容 App Shell 可保证 UI 的本地化以及从 API 动态加载内容,但同时不影响网络的可链接性和可检测性。 用户下次访问同一应用时,应用会自动显示最新版本。无需在使用前下载新版本。
Service Worker与离线存储
依赖
Service Worker 作为现代浏览器的高级特性,依赖于 fetch 、promise 、CacheStorage、Cache API、等浏览器的基础能力, Cache 提供了 Request / Response 对象对的存储机制。CacheStorage 则提供了存储 Cache 对象的机制。
功能和特性:
- 一个独立的 worker 线程,独立于当前网页进程,有自己独立的 worker context。
- 一旦被 install,就永远存在,除非被手动 unregister
- 用到的时候可以直接唤醒,不用的时候自动睡眠
- 可编程拦截代理请求和返回,缓存文件,缓存的文件可以被网页进程取到(包括网络离线状态)
- 离线内容开发者可控
- 能向客户端推送消息
- 不能直接操作 DOM
- 必须在 HTTPS 环境下才能工作
- 异步实现,内部大都是通过 Promise 实现
注意:
- SW通过postMessage与页面之间通信,让页面自己去操作DOM
- 是一个可编程的网络代理,允许开发者控制页面上处理的网络请求
- 在不被使用的时候,它会自己终止,而当它再次被用到的时候,会被重新激活,所以你不能依赖于service worker的onfecth和onmessage的处理函数中的全局状态
- 如果你想要保存一些持久化的信息,你可以在service worker里使用IndexedDB API
- 只能在 HTTPS 环境下才能使用SW,因为SW 的权利比较大,能够直接截取和返回用户的请求
- Push Notification ( 消息通知 ) Push 和 Notification 是两个不同的功能,涉及到两个 API 。 Notification 是浏览器发出的通知消息。Push 和 Notification 的关系,Push:服务器端将更新的信息传递给 SW ,Notification: SW 将更新的信息推送给用户。
用法
使用ServiceWorker之前,需要先判断浏览器是否支持,代码如下:
如果支持,则注册serviceWorker.js
,注册后,就可以 install 并写入具体的逻辑代码了,简单看个例子:
细心的同学应该注意到这里的 self
和 caches
,这里简单提一下,SW 有一些全局变量
- self: 表示 Service Worker 作用域, 也是全局变量
- caches: 表示缓存
- clients: 表示 Service Worker 接管的页面
- skipWaiting: 表示强制当前处在 waiting 状态的脚本进入 activate 状态
IndexedDB与异步存储
Web Storage 包括 Local Storage、Session Storage。它们使用简单的键值对来存储,方便灵活,但是它们的内存较小,当遇到大量的结构化数据时,就无法应对了。浏览器数据存储方式还有IndexedDB、Web SQL 和 Cookie。接下来就来看下IndexedDB,它能够在客户端存储大量的结构化数据。例如,在PWA应用中,我们可以用它来离线存储大量的聊天记录。
关于IndexDB的介绍,引用这篇文章中的一段话:
indexedDB 是 HTML5 提供的一种本地存储,一般用户保存大量用户数据并要求数据之间有搜索需要的场景,当网络断开的时候,可以做一些离线应用,它比 SQL 方便,不用去写一些特定的语句对数据进行操作,数据格式为 json。
IndexDB 使用索引高效检索的API,如打开一个IndexedDB数据库,可以这样写 window.indexedDB.open(name)
。需要注意的是,IndexDB的功能之一就是它有异步的API,类似于 ajax
请求。我们通过代码来了解下
如代码所示,打开数据库后,有以下几个回调:
onerror(err => {}) onsuccess(res => {}) onupgradeneeded(data => {})
分别处理数据库打开失败、成功的回调,以及请求数据库版本变化的回调。
IndexDB 在使用时,需要注意以下几点:
- 过大的数据不适合存放在IndexDB,浏览器初始化分配是50M
- 部分浏览器不支持IndexDB,使用前先用
"indexedDB" in window
判断下 - 敏感数据不能存在客户端
- 受到同源策略的限制
HTTPS
HTTPS,简单来讲就是 HTTP 的安全版,它是HTTP over SSL/TLS的缩写。PWA 只能在 HTTPS 协议下使用,本地开发时支持 localhost
和 127.0.0.1
。https下调试可以用 github page
。
HTTPS 会对传输的数据进行加密,建立一个信息安全通道,来保证传输过程中的数据安全。同时,也会对网站服务器进行真实的身份认证。
关于HTTPS,大家都比较熟悉,这里就不多赘述了。
入门与实践
关于PWA开发与调试的,题叶老师写了一篇文章PWA 入门: 写个非常简单的 PWA 页面,介绍了如何开启一起简单的PWA应用,感兴趣的童鞋可以去看看。
总结
PWA作为下一代 Web 应用模型,在国外非常受重视,在国内同样受到各大互联网企业的欢迎。去年饿了么也实现了一场PWA升级实践。之前看过一篇文章,说PWA在印度广受欢迎,因为当地2/3G网络覆盖比较多,PWA的优势就明显了。下面借用列出了一些站点,从最开始的 Flipcart,到目前的 Instangram、Uber、Twitter、Starbucks 等,不仅数量在增加,站点等级和质量也在不断地提升。
篇幅有限,无法面面俱到,只能抛装引玉,欢迎批评指正~