PWA笔记三:App Shell模型

Brandonxiang NOV 5, 2019

引子

我们现在使用的 web 技术更多是倾向于兼容老浏览器,没有考虑新的 API 的使用。例如 fetch,IndexedDB 等,只能等到浏览器份额超出一大半,才会考虑到使用。换句话说,浏览器还有很多潜力有待我们开发。webapp 和 nativeapp 之间的差距除了页面交互效果外,最大的不同点就是首屏加载的等待中白屏。白屏的时间差一直是我们需要面对的一个问题,可以用以下方法解决:

skeleton 是骨架屏幕下文有介绍。SSR 不在这里赘述。

PWA 全称为“Progressive Web Apps”,渐进式网页应用。它的核心技术包括:

成功案例

成功案例

国外有非常多 pwa 提高转换率的案例。同样,国内大厂也纷纷试水。它们无一例外都采用了 App Shell 模型。

ele

sina

lavas

App Shell 模型

PWA 的原理就是改变 HTTP 缓存的机制,优先取本地的资源,在下一次加载才会采用新的内容。这时候谷歌提出一个新的概念----App Shell。不是所有内容都要进行离线缓存,App Shell 更像是 app 的空壳。壳将会进行离线缓存,这些“条条框框”是不需要每次都修改的,这个“空壳”仅包含页面框架所需的最基本的 HTML 片段,CSS 和 javaScript,而对实时性要求比较高的内容将不会进行进行额外的缓存,例如列表。

这样部分离线渲染的情况被称之为 App Shell 模型,以便它可以在离线时正常展现,达到类似 Native App 的体验。stale-while-revalidate会成为一个非常重要的概念,SWR 是优先于本地缓存数据,再发送请求,最后在替换为新数据。

SWR first returns the data from cache (stale), then sends the fetch request (revalidate), and finally comes with the up-to-date data again.

开发一个 App Shell, 我们通常要注意以下几点:

明确以上内容之后,我们就可以着手开发、定制自己的 App Shell 。就下图这个例子而言,我们可以将头部组件以及标签栏组件写入页面,对 html 进行stale-while-revalidate的缓存策略,并且对标签栏的接口数据进行离线缓存,那么头部组件就成为一个离线加载的 App Shell。下面的内容由于没有进行离线处理,则为实时接口,保证了新闻内容的实时性。

这样说来,两个点成为 App Shell 的关键。

app shell 例子

Skeleton

Skeleton 也被称为骨架页面,在页面的空白处插入 html 的图像,减缓视觉差距。页面在数据尚未加载前先给用户展示出页面的大致结构,直到请求数据返回后再渲染页面,补充进需要显示的数据内容,常用在单页面应用的列表页。

骨架屏

骨架图的制作也有很多中方法。

我个人建议移动端使用图片,PC 端写样式,比较简单处理。由于图片只有两种分色,所以图片大小不大。

接口缓存

后续的文章会介绍怎么使用 workbox 进行接口缓存。

接口缓存同样可以做到优先读本地数据再请求远端数据。sw-toolbox是针对动态/运行时请求的离线缓存的工具,它已经 Deprecated。后续,workbox 已经把sw-precachesw-toolbox进行了整合为一个平台,提供大量插件。precache是默认读取本地文件,runtimeCaching则是提供动态缓存的功能,动态缓存分为五种情况:

配置文件设置 runtimeCaching,可以拦截所有/api/的接口,按照设置的情况进行缓存。cacheFirst可以大大提高首屏 App shell 数据加载的效率。

runtimeCaching: [{
  urlPattern: /api/,
  handler: 'fastest',
  options: {
    cache: {
      name: 'my-api-cache',
      maxEntries: 5,
      maxAgeSeconds: 60,
    },
  },
}],