定义
Progressive Web Apps are experiences that combine the best of the web and the best of apps.
They are useful to users from the very first visit in a browser tab, no install required.
As the user progressively builds a relationship with the app over time, it becomes more and more powerful.
- 融合了web和app的最佳使用体验
- 首次访问通过浏览器tab页,无需安装
- 随着用户多次使用,与应用建立了更明确的关系,体验逐步增强
特点
Progressive
渐进增强-优雅降级。eq: 离线存储,Cache API Local Storage
Responsive
适配PC、移动端多种设备
Connectivity Independent
通过service worker实现在低质量网络或者离线条件下使用
App-like
建立在app shell模型基础上,就像在使用原生app
Fresh
通过service worker来保持资源更新
Safe
PWA服务的提供建立在 https 基础上
Discoverable
搜索引擎可抓取,得益于W3C manifest和service worker注册作用域
Re-engageable
通过类似推送通知的方式实现应用再次唤起
Installable
可让用户不通过app store等应用商店“安装”应用(至桌面)
Linkable
可简单地通过URl对应用进行分享
历史
Google,首次出现于2015.06 Googler Alex Russell的博客文章
《Progressive Web Apps: Escaping Tabs Without Losing Our Soul》
主要观点是: Web的发展方向应该是“在保留open web灵魂的基础上渐进增强” 。
环境要求
- chrome 52及以上、opera
- https
但因渐进式设计,所有设备都可以访问(包括iOS)
核心概念
application shell与content
- application shell
类似于原生app开发中发布上线的“the bundle of code”
包括支持用户界面所需的最基础的 HTML、CSS 和 JavaScript
如果离线缓存,可确保用户重复访问时即时、可靠的良好性能
这意味着并不是每次用户访问时都要从网络加载 App Shell
只需要从网络中加载必要的内容
- content
动态获取的数据
关键技术
service worker的角色
service-worker为浏览器启动单独后台运行线程,可以搭配Cache API做缓存、
可以拦截所有HTTP请求并使用Fetch API进行response,是一个完备的Proxy
service worker的生命周期
消息推送
一句话概述:Service Worker 的后台计算能力—Push API 推送—Notification API 通知
- 推送( Push API )
Push API 让推送服务具备了向 web 应用推送消息的能力;
它定义了 web 应用如何向推送服务发起订阅、如何响应推送消息、web 应用和服务器与推送服务之间的鉴权与加密机制;
由于 Push API 并不依赖 web 应用与浏览器 UI 存活,所以即使是在 web 应用与浏览器未被用户打开的时候,也可以通过后台进程接受推送消息并调用 Notification API 向用户发出通知
- 通知( Notification API )
负责所有与通知本身相关的机制,如通知权限管理、向操作系统发起通知、通知类型与音效,以及提供通知被点击或关闭时的回调等;
最早在 2010 年由 Chromium 提出,以 webkitNotifications 前缀方式实现;
2011 年进入标准化;
2012 年在 Safari 6(Mac OSX 10.8+)上获得支持;
2015 年 Notification API 成为 W3C Recommendation;
2016 年 Edge 的支持
示例:
案例体验
设计App Shell—由设计稿划分component组件
创建app shell对应的模版文件
完成相应逻辑-刷新天气,增加城市等
实现首次快速加载
使用localStorage实现对用户已选城市列表的存储
(实际使用场景中应该使用 IndexedDB 等快速存储机制)
使用service worker实现对app shell的预缓存(功能的离线使用)
注册service worker
a. 创建一个包含service worker的js文件:service-worker.js
(注意该文件位置在项目根目录,因为service worker的作用域由路径决定)
b. 通知浏览器注册该service worker
缓存网页资源
当service worker注册完成,用户首次访问该应用时触发“install”事件,在回调函数中我们可以对应用所需要的静态资源进行缓存。
- caches.open()
打开指定的缓存
- cache.addAll()
接收一个URL列表,从服务端获取数据并添加到缓存
此时,在控制台可以看到已经注册的service worker
然后,再在service-worker.js中添加“active”事件绑定
此时,在控制台可以看到已经注册的service worker处于active状态
继续丰富“active”回调函数的内容:
确保任何app shell所需的任何静态文件有变化时,service worker都能及时更新
通过缓存提供app shell的内容
service worker提供了拦截http请求并进行处理的能力,
这意味着可以在service worker内部使用缓存进行响应
测试离线情况
首先,点击选择“offline”,network出现黄色叹号标志标明已经处于离线状态
此时,查看已缓存的文件:
使用service worker对data预缓存
核心:静态资源离线优先;动态资源网络优先
通过manifest.json支持在设备home screen添加icon
注:
提示添加的条件:
- 注册了service worker
- 有manifest文件
- 5min内访问2次以上
(不同浏览器实现不同)
预览
扩展话题
对Android/iOS平台原生能力的调用支持
页面质量检测
Lighthouse—灯塔,PWA官方提供检测工具
与前端框架的结合(Twitter React PWA)
https://twitter.com/necolas/status/829128165314306048
参考资料
PWA官方文档
(https://developers.google.com/web/progressive-web-apps/)
App Shell 模型
(https://developers.google.com/web/fundamentals/architecture/app-shell)
服务工作线程Service Worker
(https://developers.google.com/web/fundamentals/getting-started/primers/service-workers)
PWA 在饿了么的实践经验
(https://zhuanlan.zhihu.com/p/25800461)