PWA 的探索与最佳实践

4月20-22日 QCon 全球软件开发大会在北京召开,做为 InfoQ 举办的全球顶级技术盛会,总共汇集了 2500 名资深开发者参会,百度资深前端工程师彭星受邀参加大会,并在“前端实践思考和探索“专场分享了关于百度在 PWA 方面的探索与最佳实践。本文根据彭星的演讲整理而成。

PWA 是在 Web 端具备颠覆性的一个概念,在国外已经被广泛接受,不少站点已经改形成 PWA,而且取得了很是好的成绩。例如 twitter 改造 PWA 完成后,twitter lite 平均用户停留时长增加了65%。在国内,PWA 的概念愈来愈被普遍接受,微博、饿了么等不少大型的站点都已经改形成 PWA,而且还有更多的站点正在进行改造。css

PWA 是什么前端

对于 PWA 来讲,用户体验才是核心。PWA 不是一项具体的技术,他是应用了一系列技术进行使用体验优化后的Web APP,具备与Native App 一致的用户体验,可以添加主屏图标、离线可用、接收离线通知等。具体详情查看 Demo 演示。vue

PWA 具备三个主要的特性 git

  • 可靠  一方面是指 PWA 的安全性,PWA 只能运行在 HTTPS 上;另外一方面是指在网络不稳定或者没网状况下,PWA 依然能够访问。 github

  • 快速  快速响应用户的交互行为,而且具备平滑流畅的动画、加载速度、渲染速度和渲染性能等。 shell

  • 用户粘性  经过添加到桌面以及离线消息推送,能带来用户的第二次访问,而且依靠良好的用户体验吸引用户再次访问。 json

PWA 的核心技术浏览器

PWA 不是一项单独的技术,技术包括 Web App Manifest、Service Worker、Push API & Notification API 、App Shell & App Skeleton 等等技术,接下来咱们重点介绍几项技术以及相关问题的解决方法。缓存

Web App Manifest安全

Web App Manifest 是支持站点在主屏上建立图标的技术方案,而且定制 PWA 的启动画面的图标和颜色等,以下图:

Web App Manifest 功能虽然强大,可是技术上并不难,就是一个外链的 json 文件,经过 link 来引入:<link rel="manifest" href=“/assets/manifest.json”>,文件的具体内容以下:

Web App Manifest 的标准里还有不少其余的字段,能够去 W3C 的标准里查找

https://w3c.github.io/manifest

Service Worker

Service Worker 是 PWA 中最重要的概念之一,它是一个特殊的 Web Worker,独立于浏览器的主线程运行,特殊在它能够拦截用户的网络请求,而且操做缓存,还支持 Push 和后台同步等功能。

Service Worker 经过 Cache Storage 、Cache API 操做本地缓存,以及经过 fetch API 请求服务器端数据,不论是否有网络链接,或者站点发生了 404 、500,均可以让用户看到特殊定制的错误页面,而不是浏览器的默认 404 页面。

App Shell 和 App Skeleton

PWA 一般是 SPA 且一般采用 App Shell 设计模型。App Shell 在 PWA 里是很是重要的一个概念,那么 App Shell 是什么呢?

App Shell 是指支持页面所需的最小的 HTML、CSS 和 JavaScript 的资源集合。一旦离线,能够确保在用户重复访问时提供即时、可靠的良好性能,下面的截图是 App Shell 展示给用户的部分

以 Vue 的项目举例,AppShell 包含:

  1. 入口 HTML 文件

  2. 打包好的 Vendor JS 文件

  3. 导出的 CSS 文件

如上图所示,App Shell 渲染出了 header 部分,那么正文部分在加载数据以前,都是白屏,这对于用户来讲体验很是很差,有一个名词叫骨架屏(App Skeleton),在渲染出数据以前,在白屏位置占位,尽可能不出现长时间的白屏。

App Skeleton 须要在最短的时间内渲染给用户,因此,通常状况下,会将 App Skeleton 编译到 HTML 里,就像下面的代码,指望浏览器在加载完 HTML 以后就能先显示骨架屏。

可是<link rel=“stylesheet” href=“/static/index.css”> 会阻塞骨架屏的渲染,直到 CSS 文件加载完成以后,浏览器才会渲染出骨架屏,这样用户看到的白屏时间会比预想中的长。这个问题不多有站点会注意到,即便作了骨架屏,也不必定会解决 CSS 加载阻止骨架屏渲染的问题,好比饿了么的 PWA 首页就没解决。

那么,咱们怎么解决这个问题呢,能够经过 link 的 preload 解决,preload 不会阻止 HTML 渲染,在 preload 的资源加载完成以后,改回 stylesheet,调用 mount 来展示 JS 的渲染结果。以下面的代码所示(下面的代码并不能直接运行,只用来代表思路)

除了经过 preload 的这种方式解决以外,还能够将 link 里的 CSS 内联到 JS 里面,Vue 的项目默认就是 CSS In JS 的。

PWA 全称是 Progressive Web Apps,意味着是渐进式的,也就是在现有的基础上进行逐渐添加,从而改善用户体验,并不须要推倒重来,对整个站点进行改造。

PWA SEO 问题解决方案

SEO 是每一个站点都很关心的问题,PWA 一般是 SPA,众所周知,传统的搜索引擎是没法索引经过 JS 来渲染的页面的,那么,咱们须要怎么解决这个问题?

首先须要说明的是百度不是那个传统的搜索引擎,百度、Google 都是可以索引移动端的 SPA 页面的。那么对于其余搜索引擎,解决 PWA SEO 的问题惟一方法就是服务器端渲染(SSR),如今市面上主流的 MVVM 框架都有提供 SSR 的解决方案,好比 React、Vue、San 等。

SSR 的页面是服务器直出的,内容页是同时出来的,那么这种方式如何结合 Service Worker 来离线呢?如何作到 AppShell 的启动效果呢?咱们采用 Service Worker + App Shell + SSR + (Vue/React/San) 的方案来很是完美的解决这个问题。

第一次请求,服务器直接输出 SSR 以后的内容,页面加载完成以后注册 Service Worker,Service Worker 在 install 阶段预缓存一些静态文件或者其余资源,在这里咱们新增一个请求,地址是 /appshell,这个 /appshell 的请求返回的内容是 App Shell 的 HTML,这个 HTML 有引用 JS 和 CSS 的代码,能够举一个 Vue 的例子:

https://github.com/lavas-project/lavas-template-vue/blob/release-basic/pages/Appshell.vue

在第二次请求的时候,Service Worker 经过request.mode === ‘navigate’ 来判断当前这个请求是不是页面请求,若是是,将事先缓存好的 /appshell HTML 结构返回给页面,渲染以后,App Shell 经过当前 URL 去请求对应的 JS 和数据来渲染页面的正文内容。

经过这种方式,不只可以解决 SEO 的问题,站点能彻底离线,还能缩短白屏时间,更重要的一点是它还能大大下降服务器 SSR 带来的压力。由于用户只有第一次渲染才须要服务器运行 SSR 的逻辑,以后的请求都是走的前端渲染。

PWA 的兼容性

PWA 在 2017 年初,仅仅 Chrome 和 Firefox 支持 PWA,通过一年的发展,国内主流浏览器都已经支持 PWA,iOS 在 新发布的11.3 版本中也支持了 PWA。

推荐

更多 PWA 教程、文档、Lavas 官网、Codelab、PWA 效果示例、兼容性请访问 Lavas 官网,点击左下角“阅读原文”便可进入官网。

Brilliant Open Web 

BOW(Brilliant Open Web)团队,是一个专门的 Web 技术建设小组,致力于推进 Open Web 技术的发展,让 Web 从新成为开发者的首选。

BOW 关注前端,关注 Web;剖析技术、分享实践;谈谈学习,也聊聊管理。

关注 Open Web 开发者,回复“加群”,让咱们一块儿推进 Open Web 技术的发展!

相关文章
相关标签/搜索