百度在 PWA 方面的探索与最佳实践

2018-06-05 14:22

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

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

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

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

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

  Web App Manifest 的标准里还有很多其他的字段,可以去 W3C 的标准里查找

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

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

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

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

  App Skeleton 需要在最短的时间内渲染给用户,所以,一般情况下,会将 App Skeleton 编译到 HTML 里,就像下面的代码,期望浏览器在加载完 HTML 之后就能先显示骨架屏。

  但是会阻塞骨架屏的渲染,直到 CSS 文件加载完成之后,浏览器才会渲染出骨架屏,这样用户看到的白屏时间会比预想中的长。这个问题很少有站点会注意到,即使做了骨架屏,也不一定会解决 CSS 加载骨架屏渲染的问题,比如饿了么的 PWA 首页就没解决。

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

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

  SEO 是每个站点都很关心的问题,PWA 通常是 SPA,众所周知,传统的搜索引擎是无法索引通过 JS 来渲染的页面的,那么,我们需要怎么解决这个问题?

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

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

  通过这种方式,不仅能够解决 SEO 的问题,站点能完全离线,还能缩短白屏时间,更重要的一点是它还能大大降低服务器 SSR 带来的压力。因为用户只有第一次渲染才需要服务器运行 SSR 的逻辑,之后的请求都是走的前端渲染。

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

  关注 Open Web 开发者,回复“加群”,让我们一起推动 Open Web 技术的发展!