在 Twitter 上看到 Addy Osmani 发的视频被狂转, 开始注意
https://twitter.com/addyosmani/status/734753297274306561
之前几乎对这个词语没有印象, 看到是在 IO 的演讲还以为是新技术
在 Youtube 上找一下, 这次好多个视频是关于 Progressive Web Apps 的
视频的内容主要是讲网站优化, 分别用 React, Angular, Ember 做例子
可惜没有 Vue, 大概要等小右补... 方案应该没有问题
从视频看, 优化的效果非常显著, 本来好几秒的应用能优化到一秒内.. 很夸张
所以仔细了解了一下怎么回事, 现在大概了解
视频里给的优化方案大概分成几个步骤(细节还要看视频确认):
添加 manifest.json
文件, 生成 Android 主屏打开的网页加载页面
编写 Service Worker 脚本处理缓存, 更快读取缓存
服务端渲染, 用 App Shell 带来效果, 然后动态加载
启动过程 JavaScript 代码的性能优化
虽然是新技术, 但文档可以追溯到一年前甚至一年半以前
Service Worker 在 2014 年底就在 HTML5 Rocks 上介绍了
manifest.json
的识别功能在 Chrome 39 已经加入
App Shell 仅仅是模板渲染略过动态内容的一个优化
前两个 API 整体上是 Chrome 支持, 所以兼容性问题较大
那么 Google 既然在大会上推, 说明方案已经比较成熟值得深入了
简称 PWA 吧, 名字是从 Android Chrome 的"添加到主屏幕"开始的
Progressive Web Apps: Escaping Tabs Without Losing Our Soul https://infrequently.org/2015/06/progressive-apps-escaping-tabs-without-losing-our-soul/
2015 年六月份的文章, 第一次有了这个提法, 针对这类应用
网页应用在这样的场景下和移动应用很相似了, 可以从主屏打开
而且, 能快速地加载, 可以跑后台进程, 加密的连接, 离线使用等等
Instant Loading Web Apps With An Application Shell Architecture https://medium.com/google-developers/instant-loading-web-apps-with-an-application-shell-architecture-7c0c2f10c73
到了年底的时候 Addy Osmani 发了文章, 大致上已经是前面演讲的内容了
首先是渲染 App Shell 也就是页面的框架, 给用户更好的加载体验
而且可以通过 Service Worker 来做 App Shell 渲染, 去掉网络请求的时间
然后再动态地请求更多内容, 填充数据. 整体上看的加载速度会变快
2015 年底还有个 Google Developer Summit, 我以前都没注意到据说大会上 PWA 已经名声很大了, Medium 上专门介绍了一下
Chrome Developer Summit Recap https://medium.com/@davideast/chrome-developer-summit-recap-1137b022b2dc
Getting started with Progressive Web Apps https://addyosmani.com/blog/getting-started-with-progressive-web-apps/
演讲视频的话, YouTube 上几个大会录的演讲都挺丰富的:
https://www.youtube.com/results?search_query=progressive+web+apps现在已经有做了不少的 PWA 的 Demo 了, 比如第一个 washingtonpost
Washington Post https://washingtonpost.com/pwa
List of Progressive Web Apps Build status https://github.com/operasoftware/pwa-list
Progressive Web Apps collection https://github.com/ljinkai/pwa-collection
Hacker news demo https://progressive-web-application.herokuapp.com/
manifest.json
前面说了, 加进来挺久了, 主要是为了添加 Splash Screen
根据 manifest.json
可以自动生成一个网页(主屏幕按钮打开)的启动界面
这样看上去就很像一个 Native App 了, 包含图片, 文字, 背景
Splashscreen https://developers.google.com/web/updates/2015/10/splashscreen
Add to Homescreen https://developer.chrome.com/multidevice/android/installtohomescreen
128dp
对应最小要求 192px
我当时图片太小了结果很久没显示出来, 到文档上才发现
详细的 manifest.json
内容可以在下面一些界面找到
The W3C App Manifest specification http://html5doctor.com/web-manifest-specification/
Web app manifest https://developer.mozilla.org/en-US/docs/Web/Manifest
Web App Manifest, Living Document http://manifest.sysapps.org/
Manifest Generator http://brucelawson.github.io/manifest/
Web Manifest Validator https://manifest-validator.appspot.com/
Service Worker 可以简单理解成跑在网络请求的拦截器
或者当做是 Nginx, 它可以监听页面的请求, 判断返回什么内容
它可以通过 Cache
处理本地的缓存, 也可以用 fetch
抓线上的资源
另外演讲视频还有介绍处理消息推送功能, 类似离线收发消息, 还没细看.关于 API 使用需要深入看文档, 已经有很详细的介绍了:
[译]我的第一个 Service Worker http://www.w3ctech.com/topic/1593
Introduction to Service Worker http://www.html5rocks.com/en/tutorials/service-worker/introduction/
The offline cookbook https://jakearchibald.com/2014/offline-cookbook/
Google 提供了一些类库, 能实现 Express.js 风格的简化写法:
sw-precache https://github.com/GoogleChrome/sw-precache/
sw-toolbox https://github.com/GoogleChrome/sw-toolbox
具体的浏览器兼容性可以看:
is service worker ready? https://jakearchibald.github.io/isserviceworkerready/
can I use http://caniuse.com/#feat=serviceworkers
关于调试, Google Chrome 试验版本已经更新了 Application Tab
其中 Service Worker 被放到了显眼的位置, 不过, 功能多了还是挺复杂的
另外下面这些链接会有帮助:
Service Worker Debugging https://www.chromium.org/blink/serviceworker/service-worker-faq
chrome://inspect/#service-workers
chrome://serviceworker-internals
另外了解和尝试 Demo 的时候我也想到一些跟自己项目比较相关的内容
很 RN 一样这套方案能让网页应用在效果上更接近原生应用
PWA 主要是处理应用加载部分, 让应用能离线打开, 启动过程跟 App 一样变快
因此原来寄托在 RN 的功能已经能做到了, 离线, App 启动界面
我正在考虑把我以前某个 Demo 重写, 看下能有多像 App 的体验
从前简聊优化应用启动用过本地存储整个 Store 数据的办法
普通页面 App Shell 不错了, 而 React 应该能做整个页面放 Service Worker
或者说, Store 放进 Service Worker 里, Virtual DOM 也放进去
那么网页主线程其实只有 DOM 操作部分的代码, 可能启动速度能提升非常大
而且 React 已经有把 DOM Diff 放进 Worker 的尝试, 还可以延伸下
整个这样想, 对 React 应用的整体架构改变将会挺大的而 Angular, Vue 之类的框架应该也会做类似的架构调整
文档里的 Demo 对应的 sw.js
代码都是的直接用链接加载的
我们搭配 CDN 使用当有打包以及 revision 方便的考虑
这就要求打包工具要对 service worker 的语法做良好的支持
Webpack 有看到相关的 PR 提交对应的功能, 其他工具不了解:
https://github.com/webpack/worker-loader/pull/14 项目代码引用 sw.js
的写法:
navigator.serviceWorker.register('/sw.js')
sw.js
内部再引入其他代码的写法:
importScripts('serviceworker-cache-polyfill.js');
可能的话还需要把 CommonJS ES6 模块打包进去, 会挺复杂的以及局部更新, 热替换之类的开发环境的打包方案改进等等
有点意外, 似乎之前 iOS 有做过强制 HTTPS? 我第一次遇到
Service Worker 运行要求网站是 HTTPS 或者 localhost
这样的话本地开发, Android 上做 remote debugging 会有些不便
我找的办法是直接在本地 Nginx 配置不安全的证书来方便开发的:
https://serversforhackers.com/video/self-signed-ssl-certificates-for-development
比较直接的办法当然是找个有域名的服务器然后用 HTTPS 开发
fraserxu 教了我一招, 回头试试, 可以用 https://ngrok.com/
把本地的端口监听转化成一个在线的 HTTPS 地址...
考虑缓存处理上带来的速度提升, 我对 PWA 整套方案很看好
而且之前的 HTML5 应用缓存来说, PWA 的自由度和体验都改进了很多
所以会逐渐开始考虑现实往这方面做迁移的思路:
兼容性: 目前主要 Safari 不支持, 而 Chrome 方面已经比较成熟, 国产浏览器就...
工具链: 调试工具已经不错, 打包和局部更新还要等待技术支持
缓存方案: API 和语法糖都有了, 虽然代码比较啰嗦但是抄代码可以比较快
动态数据方案: 动态的数据怎么抓取和推送, 还不大了解, 不过 Google 有演示过一些
做到这些基本上已经可以对页面的加载过程做不小的优化了等待出更多的 Demo 以及大网站公布试验的数据如何...
未来的更多代码被放进 Service Worker 之后, 带来的改变会更大一些最后贴一张图片膜拜一下前端的复杂度:
https://twitter.com/sstephenson/status/730039913052176384