PWA是最近一个热门话题,很多开发同学都在尝试落地,其中也有些还在犹豫。这篇文章主要阐述对几个问题的看法,供大家参考。
注: 这不是一篇介绍PWA的文章。
简而言之(TL;DR):
. PWA落地最大的纠结在于iOS支持的问题,且短时间难以得到改善。如果你的业务仅限于iOS,就不用再往下看了。
. 事实上,PWA本身与其它技术方案并不冲突,比如各类的Web性能优化方案,以及基本的H5技术仍然可以落地共存,PWA只是在其之上进行更进一步。这正是其所谓渐进式命名的由来。
. PWA正在拥有一个完善的技术体系,涉及五个层次,从Web平台,到各类工具。
. 无论是从最近Web生态的发展,到未来应用开发技术的演进,再到实际开发落地和维护,PWA都代表了一个正确方向,值得投入。
iOS之痛是个伪命题
iOS中Safari内核支持一直是PWA绕不开的问题。2016年参加Google I/O时,与Chrome团队做了一次交流。他们明确表达了期望UC参与Chromium社区,越多人使用Chromium内核,Safari承受的压力就越大,就能促使其快速跟进Chrome提出的一系列新标准,其中的重点就是PWA方向。Safari团队虽然将Service Worker列入其五年计划,但并没松口开工。反观Microsoft Edge要积极的多。曾经打破浏览器格局的WebKit(Safari)已显然要成为移动时代的IE6了,主要着眼于其封闭的生态思考!
但是,iOS支持的问题不应该阻碍了PWA技术选型!原因是PWA是渐近增强式(Progressive)的技术,其核心是增强,而不是直接替代(比如没有替换某个H5特性,而是新增。),在不支持的场景下可以安全降级。以离线存储为例,AppCache实在太难用, 在没有支持Cache API的情况下可以使用Local Storage实现,如果支持了Cache API,就可以直接使用ServiceWorker+Cache来实现。在技术方案上,有一个基本的实现方案,是通用的。
在支持PWA相关标准的环境下,还可以进一步使用加强的技术方案。正如软件开发没有银弹一样,不能期望一个新技术可以解决所有问题。之前要解决的问题还是要继续分析解决,比如JS逻辑优化、图片压缩、CDN配置优化之类的工作,还是应当要一样展开的。
如果一定在iOS要使用到某些PWA特性带来的好处。可以考虑:
- 评估使用Polyfill的可行性。直接到下面Polyfills那一节看下。
- 实现一套在独立线程(类似于Service worker)运作的扩展机制,使用JS Bridge提供给页端使用。有一定的风险,可以提供主要特性的支持,比如Cache & Fetch。
- 通过各种渠道(Mailing list, App Store, Twitter, etc.)向Safari吐槽。这条简单易行!
PWA === Servie Worker + Fetch + Cache?
初次进行PWA落地,我们往往会聚焦于几个抢眼的特性。从小步快走的角度来看这是正确的,但不能仅限于这一点,我们还需要更加系统了解PWA的技术体系。
从整个技术体系上看,分成五个层次:
- PWA Features 通过标准定义,开放传播。易于各方理解和支持,特别是凝聚一些中间力量。因为Top的玩家也可以选择玩封闭的生态。
- Web Platforms (各家浏览器及WebView) Web平台的支持,才能让PWA有应用的空间。特别是进一步与OS的结合,提高了Web应用与原生应用的竞争力,才能保证Web App能够成为应用开发的选项之一。从平台的角度思考,它一定会支持多种技术方案,更多的应用形式能帮助整个应用市场活跃起来。
- 组件库及工具库(Polymer等) 开发最容易纠结在库、框架、组件的选择上,因为这是实实在在的痛点。有了进一步封装的库、组件、解决方案,无论具体什么形式,它必须要简化PWA的开发,是一个可以复用的技术方案,以降低开发成本和技术风险。
- 工具及支撑平台 工具则包括开发调试、检测等可以提高开发效率的工具。支撑平台则是为这个生态提供基础服务的。
- 设计思想和开发模式 在一个技术生态内,对实践的指导原则可以理解对最佳实践的抽象总结,可以帮助开发者更好理解这个生态面对的问题和解决的思路。最终它会影响到工具和组件,甚至是平台和Features。
Features不用多说,Web Platforms则是除了Safari之外的主流浏览器都有支持,只是Edge在支持的范围上有所差异。以下是工具和组件的构成:
- 开发调试工具: Chrome - DevTools, 各主流浏览器除Safari外都可以在其对应的工具上进行调试。
- 检测工具: lighthouse
-
支撑平台:
- Firebase : Database, Push Notification等。国内使用阿里云及Agoo ! (PWA on Firebase)
- 后台服务最好迁移到HTTP2!Instant Loading with HTTP2。
-
组件库及工具库
- Google Chrome之SW Toolbox: 重在动态使用不同策略进行资源加载。
- Google Chrome之SW Precache : 重在预加载及缓存。
以上两个库都是为了降低Service Worker的使用成本, 使用说明: PWA Summit 2016: Tools for Success - Google Chrome之SW Helpers : 新一代更为系统的工具库。
- Polymer, 基于Web Components的Web App组件库
Polymer App Toolbox: To build PWA (体现AppShell & PRPL)。
-
设计思想及开发模式
最后特别需要提醒的是,落地过程也是一个持续学习和优化的过程。比如Polymer本身有一些性能优化策略,如果简单的使用可能会发现有性能上的降级,UC的同学也是在实践中积累了些经验。
工具库示例:sw-toolbox
工具库固化了一些常用的实现,以sw-toolbox为例,其核心是提供一组离线应用的策略机制,可以结合导航使用不同加载策略。详细的策略说明文档是: The Offline Cookbook, 其中总结并定义了在离线应用中涉及的五种加载策略。sw-toolbox对应定义如下的策略:
- networkFirst
- cacheFirst
- fastest
- cacheOnly
- networkOnly
其中fastest的策略是同步从Cache和网络中加载,使用先返回的数据。另外还可以指定超时时间等加载选项。超时选项(networkTimeoutSeconds)设置是需要考虑的,因为Chrome的网络请求没有默认的Timeout机制,UC则是自己做了实现。详细内容看它的API定义文档。
整个使用非常简洁,下面是一个service worker的写法,使得进入offline/时仅从缓存加载:
// DEMO for sw-toolbox.
importScripts('sw-toolbox/sw-toolbox.js');
// Optional
toolbox.options.cache.name = 'sw-toolbox-cache';
toolbox.precache(['./caching.html', './offline/index.html']);
// Define different strategies as below:
toolbox.router.default = toolbox.fastest;
// Below router means to load data from cache only while navigating to offline.
toolbox.router.get('/offline/.*', toolbox.cacheOnly);
// For more details, please refer to SW-Toolbox API:
// https://googlechrome.github.io/sw-toolbox/api.html
HTTPS还是HTTP2?
这里有一个清晰的技术链条:
- PWA要求使用HTTPS。
- HTTP2较HTTPS提供更高的性能表现。
所以在考虑PWA落地,还要纠结下HTTPS和HTTP2。HTTPS本身会有一定的成本(证书、CPU等)和性能影响(首次明显),HTTP2则有更好的性能收益,但应用上有不同的Web优化策略,核心是多路复用和Server Push,使得之前的一些优化实践无效,甚至有负作用,比如内联资源,分散服务器等。可以简单参考Web 开发者的 HTTP/2 性能优化指南。
除了自己的服务部署,还要涉及CDN的支持。正如之前HTTP Pipeline的支持,浏览器乐于支持,但实际测试数据却发现性能更差,原因就是大部分的服务器后台和CDN都没有支持。现在的情况是,目前国内的主要CDN可以支持HTTPS,如阿里云还支持了HTTP2。 长远来看一定是HTTP2,只是需要从业务本身出发,仔细评估下相关的风险和影响,绝非是后台做了支持就万事大吉了。
PWA特性支持不完整,怎么破?
PWA这个体系涉及的功能很多,也是逐渐在完善。Chrome本身迭代比较快,国内浏览器有一个较长的跟进周期。所以特性支持不全是比较容易遇到的问题。举个例子,饿了么团队在PWA实践中遇到了Fetch Redirect失败的问题。从页端或者后台还是比较容易处理的。
但是不是所有的问题都能这样解决,也会有必须内核进行支持的问题,这种情况下,浏览器是可以做部分升级的。如果你遇到了,欢迎随时和我们联系。
关于Polyfills
给有需要的同学参考:
Cach polyfill 仅是实现了Cache.addAll()PWA的未来
PWA首先瞄准的是应用开发,以其官方定义,是为应用开发者提供多一个选择。所以会尽力缩小其与原生应用在能力上的差距。回头想到2012年前后那股也是Chrome推动的WebApp,最终不了了之。现在的PWA机会其实也就是H5的未来空间。
可以想象未来5年,应用开发的技术模式一定会有很大的变化。总体方向就是高动态性、低开发成本(包括了低风险), 产品形式上超级应用 (包括OS)和轻快的小型应用两极分化,前者越来越寡头,后者则占据绝大多数。
纵观现在App开发技术上的创新都是在这个方向上,包括RN, Weex, AMP(或者Instant Article), PWA, Android Instant App之类。无论Native容器、或者原生应用本身如何发展,产品对动态性的需求只会越来越高。而产品技术的复杂度也会越来越高,开发周期、变更成本、维护成本都有越来越高的要求。
Web的优势是开放的标准,一是持续改进,不断扩展和丰富,使其展现能力越来越强。二是技术清晰透明,易于理解和传播,有助于降低开发成本,包括风险。着眼于未来,不在于现在谁的市场占比提升速度,而在于哪方能更稳健地持续提供系统的支持,让生态更完整。
具体到内容展现,或者渲染技术上。虽然Web目前仍然有较大的性能问题,但它正通过自身的优化、以及提供原生扩展不断缩小差距。以UC实践的经验来看,除了内核演进外,前端对渲染性能的理解和优化也是同样关键的问题。可以参考Roger的对页端开发高性能(交互/动画) Mobile WebApp 的一些思考。
再回到2016年底到现在3月份,Node.js的成熟推广,Weex/RN发力,再到小程序造的势(轻快),让页端承担应用+H5主力开发的模式越来越清晰。
再从Google对Web开发者的推崇(16年底的开发者大会)以及对业界的技术推广活动,到iOS AppStore的热修复门,一边推,一边收紧,所产生的不确定性反而让H5方向更为明确。
问题总是越辨越明,欢迎大家指正。