## 饿了么的 PWA 升级实践 文 / 黄玄 自 Vue.js 在官方推特第一次公开到现在,我们就一直在进行着将饿了么移动端网站升级为 Progressive Web App 的工作。直到近日在 Google I/O 2017上登台亮相,才终于算告一段落。我们非常荣幸能够发布全世界第一个专门面向国内用户的 PWA,但更荣幸的是能与 Google、UC 以及腾讯合作,一起推动国内 Web 与浏览器生态的发展。 ### 多页应用、Vue.js、PWA? 对于构建一个希望达到原生应用级别体验的 PWA,目前社区里的主流做法都是采用 SPA,即单页面应用模型(Single-page App)来组织整个 Web 应用,业内最有名的几个 PWA 案例 Twitter LiteFlipkart LiteHousing Go Polymer Shop 无一例外。 然而饿了么,与很多国内的电商网站一样,青睐多页面应用模型(MPA,Multi-page App)所能带来的一些好处,也因此在一年多前就将移动站从基于 AngularJS 的单页应用重构为目前的多页应用模型。团队最看重的优点莫过于页面与页面之间的隔离与解耦,这使得我们可以将每个页面当做一个独立的“微服务”来看待,这些服务可以被独立迭代,独立提供给各种第三方的入口嵌入,甚至被不同的团队独立维护。而整个网站则只是各种服务的集合而非一个巨大的整体。 与此同时,我们仍然依赖 Vue.js 作为 JavaScript 框架。Vue.js 除了是 React、AngularJS 这种“重型武器”的竞争对手外,其轻量与高性能的优点使得它同样可以作为传统多页应用开发中流行的“jQuery/Zepto/Kissy+模板引擎”技术栈的完美替代。Vue.js 提供的组件系统、声明式与响应式编程更是提升了代码组织、共享、数据流控制、渲染等各个环节的开发效率。Vue.js 还是一个渐进式框架,如果网站的复杂度继续提升,我们可以按需、增量地引入 Vuex 或 Vue-Router 这些模块。万一哪天又要改回单页呢?(谁知道呢……) 2017年,PWA 已经成为 Web 应用新的风潮。我们决定试试,以我们现有的“Vue.js+多页”架构,能在升级 PWA 的道路上走多远,达到怎样的效果。 ### 实现“PRPL”模式 “PRPL”(读作“purple”)是 Google 工程师提出的一种 Web 应用架构模式,它旨在利用现代 Web 平台的新技术以大幅优化移动Web的性能与体验,对如何组织与设计高性能的 PWA 系统提供了一种高层次的抽象。我们并不准备从头重构我们的 Web 应用,不过我们可以把实现“PRPL”模式作为我们的迁移目标。“PRPL”实际上是“Push/Preload、Render、Precache、Lazy-Load”的缩写,我们接下来会展开介绍它们的具体含义。 #### Push/Preload,推送/预加载初始 URL 路由所需的关键资源 无论是 HTTP2 Server Push 还是``,其关键都在于,我们希望提前请求一些隐藏在应用依赖关系(Dependency Graph)较深处的资源,以节省 HTTP 往返、浏览器解析文档,或脚本执行的时间。比如说,对于一个基于路由进行 code splitting 的 SPA,如果我们可以在 Webpack 清单、路由等入口代码(entry chunks)被下载与运行之前就把初始 URL,即用户访问的入口 URL 路由所依赖的代码用 Server Push 推送或``进行提前加载。那么当这些资源被真正请求时,它们可能已经下载好并存在缓存中了,这样就加快了初始路由所有依赖的就绪。 在多页应用中,每一个路由本来就只会请求这个路由所需要的资源,并且通常依赖也都比较扁平。饿了么移动站的大部分脚本依赖都是普通的`