自动化生成 H5 骨架页面
骨架页面(Skeleton Page)指的是当你打开一个移动端 web 页面,在页面解析和数据加载之前,首先给用户展示页面的大概样式。在骨架页面中,图片、文字、图标都将通过灰色矩形块或圆形块来展示,在真实页面展示之前,用户能够感知到即将加载页面的基本 CSS 样式和页面布局。饿了么移动 web 端骨架页面如题图所示。
本篇文章将给读者阐述一种自动化生成上图骨架页面的方案,通过该方案,可以将自动化生成骨架页面与你的开发流程完美结合。
为什么我们需要骨架页面
首先我们将该问题分解成两个子问题,第一我们为什么需要骨架页面。
- 正如上文已经提及,骨架页面是在页面真正解析和应用启动之前给用户展示页面的 CSS 样式和页面布局,并通过骨架页面的明暗变化,告知用户页面正在努力加载中,让用户感知页面似乎加载得比以前快了。当应用启动、数据获取后,通过真实数据渲染的页面替换骨架页面。
- 在骨架页面出现之前,很多应用在真实数据获取之前,都是采用 Loading 图标的形式告诉用户数据正在加载,请等待,但是用户此时无法感知即将呈现的页面,也无法确定等待的时长,千篇一律的 Loading 图标已经让用户产生了审美疲劳,长时间的等待促使用户产生等待焦虑,根据 Google Research 的研究显示,53% 的用户在等待加载 3s 后,选择关闭 Web 页面或应用,导致用户流失。而骨架页面让用户觉得数据已经加载好,只是还在渲染过程中,这也是为什么用户觉得页面加载得比之前快的原因所在。同时由于骨架页面和真实页面样式布局完全一致,在用户视觉感知上,骨架页面可以平滑的切换到真实数据渲染的页面。如果是通过 Loading 图标切换到最终页面,用户感知上会显得比较突兀。
- 纵览当下前端框架,已然是 React、Vue、Angular 三足鼎立之势,市面上大多数前端应用也都是基于这三个框架或库及相应生态圈完成的,饿了么前端项目也不例外,比如移动端H5就是使用的 Vue 库。这三大框架都有一个共同的特点,其都是 JS 驱动,在 JS 代码解析完成之前,页面不会展示任何内容,也就是所谓的白屏。用户是极其不喜欢看到白屏的,什么都没有展示,用户很有可能怀疑网络或者应用出了什么问题。 拿 Vue 来说,在应用 bootstrap 时,Vue 会对组件中的 data 和 computed 中状态值通过
Object.defineProperty
方法转化成 set、get 访问属性,以便对数据变化进行监听。而这一过程都是在启动应用时完成的,这也势必导致页面启动阶段比非 JS 驱动(比如 jQuery 应用)的页面要慢一些。
第二个子问题,为什么需要自动化生成骨架页面。
其实原因很简单,程序员都是「懒惰」的,没有哪个程序员愿意重复去做一些相同或者类似的工作,「加钱也不行」。而手动编写骨架页面正是这样的工作,重复而没有创新。既然骨架页面样式及布局和真实数据渲染的页面一致,只是没有图片、文字和图片的填充,那么为什么不复用页面样式及布局呢?为什么不通过工具根据真实页面自动化生成骨架页面呢?这样在节约了自己时间的同时,也为公司节省了人力成本,何乐而不为!
通过 puppeteer 生成骨架页面
生成骨架页面的基本方案
通过 puppeteer 在服务端操控 headless Chrome 打开开发中的需要生成骨架页面的页面,在等待页面加载渲染完成之后,在保留页面布局样式的前提下,通过对页面中元素进行删减或增添,对已有元素通过层叠样式进行覆盖,这样达到在不改变页面布局下,隐藏图片、文字和图片的展现,通过样式覆盖,使得其展示为灰色块。然后将修改后的 HTML 和 CSS 样式提取出来,这样就是骨架页面了。
上面描述生成骨架页面的原理可能听起来还是有些模糊,下面将通过一些 page-skeleton-webpack-plugin (简称PSWP)中具体代码片段来阐述骨架页面的生成。PSWP 是饿了么大前端一款内部生成骨架页面的工具,内部团队已经在使用,项目正在积极开发中,GitHub 地址。
在阐述具体生成骨架页面之前,先了解下 puppeteer, GitHub 上是这样介绍的。
Puppeteer is a Node library which provides a high-level API to control