使用骨架屏
首先我们学习骨架屏技巧的一个使用。
骨架屏顾名思义是展示一个页面骨架而不含有实际的页面内容,给用户的感觉是数据正在紧张的加载,真实数据马上就可以呈现。从渲染效率上来讲,骨架屏它并不能使首屏渲染加快。由于骨架屏的一些使用又向用户渲染了额外的一些内容,这些内容是额外添加的、本来是不需要渲染的,它反而从整体上加长了首屏渲染的一个时长。但是骨架屏在这个页面白屏的时候,它给了用户及时的反馈,减缓了用户焦急等待的一个情绪,这是它的意义所在。
在小程序启动流程的第三阶段即首页渲染阶段,在使用真正的数据渲染页面之前也就是在这个Page.onLoad事件派发之后有一个空档期,这个时候这个视图页面它已经开始展示了,但因为动态数据还没有到,页面往往产生为白屏,动态数据的数据量加载越多,空档期它就会越长、白屏现象也会越严重。
在我们的实际的项目里面,主页在这个页面开始显现之前有明显的白屏现象,在主页里面有一个很长的列表,列表渲染出来之前,下方列表的位置也有轻微的一个白屏现象,这些现象稍后我们在演示的时候都会看到。
为了避免白屏现象的一个出现,我们可以这样优化:开发者可以在这个数据完成加载之前使用骨架屏和Loading提示,在这个数据完成之后将骨架屏和Loading做不渲染的一个处理,再展示真正的一个页面内容。
一般具体的做法是这样:当前这个页面里面,数据源对象里面我们加一个loading提示这样的变量初始值设置为true,数据加载完成以后再将这个变量通过setData方法设置为false,在WXML这个页面里面我们通过loading变量切换骨架屏内容以及Loading提示还有真正页面内容的一个显示,为主页添加上骨架屏以后,从用户的体验这个角度来看,他这个感觉已经好了很多。现在我们在屏幕上看到了,这个就是最终的一个骨架屏渲染的一个效果。
现在我们开始代码演示。首先看一下我们的项目,现在我们看到的微信开发者工具展示的就是我们的优化项目的初始的状态,然后为了更好地编辑这个项目,我同时还开了另外的一个编辑器,就是VSCode。VSCode下面在这个project下面有一个miniprogram,这个目录下也就是我们的小程序项目。我们同时会用这两个编辑器去编辑我们项目的一个代码,在这个里面我们看到模拟器里面已经展示了三个页面,默认展示的这是主页,然后前面有一个商品页,最后面一个我的是用户主页,一共这三个页面。
首先我们看一下我们这个项目首页在加载的时候它有什么样的一个问题。单击编译看一下它的一个表现效果,我们看到这个页面有长期的一个白屏并且上面这个图加载以后,下面列表区域在渲染之前与完全渲染之间也有一个很长时间白屏,可以明显地可以感觉到。
接下来我们就用骨架屏这个技巧对它进行一个优化,这个页面在完成渲染以后,我们在模拟器这个区域下方有三个点,单击这个菜单会有一个辅助菜单,上面选择生成骨架屏,然后它会有一个提示,单击确定,我们主页这个是在index目录下面,然后在这个地方,这个里面有一个子目录,这是我们的一个主页面。我们现在看到这个目录下面多出来的两个文件,以index开头了,然后中间加了一个skeleton,这个是骨架屏的一个意思。同时我们这个页面里面 这个代码也会有所修改,我们看一下这个代码,这两个文件是它默认生成的一个代码:一个是wxml,下面这个是它的样式代码,这两个代码我们再重新编译一下这个项目看一下它的现在的一个表现。
现在骨架屏代码已经生成了但是还没有在我们主页这个页面上,没有去应用上去,怎么去应用?
首先我们看样式代码,这里面有提示,我们需要将这个代码给它拷贝一下,在我们index.wxss这个页面里面,在这个上面,将这个代码给它拷贝在这个地方,这是添加了样式。
然后接下来在这个视图页面里面,还有把这个代码也给它拷贝一下放在我们主页的视图页面里面,放进来这个地方,这有一个loading,loading我们现在还没有,需要在我们js这个页面里面,在data数据对象里面加上loading,默认给了一个值是true 默认能显示。
另外我们还需要有一个loadingTip提示语,再加一个额外的提示语:页面正在加载,放在我们的页面里面。可以放在这个地方,然后用这个数据绑定的语法把它放在这个,就是小胡子语法,然后这个地方我们也要给它一个渲染的控制。拿了一个wx:if if loading等于true的时候进行渲染,这两个内容它会随着变量的一个改变,会同时显示或隐藏,loading开始是true 什么时候给它改成false。在我们这个代码里面我们要看一下有一个关于数据加载,就是列表数据加载,在onReady里面有一个 request的一个数据接口的一个调用,在success回调里面,最后面这个地方 我们在这个地方设置this.setData,然后loading等于false,这样我们这个代码已经全部写好了,骨架屏也已经安排好了。
现在我们重新编译,测试一下它的效果,我们看到在真正的数据加载之前这个地方是有一个骨架屏的效果的,但是我们这个效果好像有一点点不是很美观对吧,特别是在我们列表的数据真正的加载完成并渲染之前,我们会看到它上面会有一些重叠,对不对?
这个其实是骨架屏和我们真实的页面它的一个处理,我们可以这样来处理,下面这不有一个container,这是另外的一个地方,这个地方我们可以加一个else,它和上面是一个互斥的一个关系,然后我们再看一下它的一个表现。等到这个数据加载完成以后,然后再开始真实的一个页面的显示。
这是我们看到一个效果,改变以后整体上一个效果比原来稍好了一点。但是应该我们也注意到,本质上我们这个页面的整体的加载时间并没有减少,然后用户在看到骨架屏这个时间仍然是等了很长时间,骨架屏它只是缓解了我们用户等待的一个焦虑情绪,它其实并没有从根本上去将我们启动时间减少。
最后总结一下我们应该如何使用骨架屏以及在哪个时间节点使用骨架屏呢?
至少有三点需要注意:
第一点在data数据对象中默认设置loading等于true。
给骨架屏使用的loading变量,它默认就写到data数据变量这个里边,它在initDataSendTime这个时间节点它会发送到这个视图层,然后进行渲染,从后端接口动态加载的一个数据这个动作要放在Page.onLoad这个周期函数里面甚至更早的周期函数里面去执行。一等这个数据加载完成了立马就将这个数据塞到数据源对象里边,同时将loading设置为false,消除骨架屏的一个渲染,这是第一点。
第二点就是不要直接修改生成的骨架屏的一个代码。
现在我们在屏幕上看到一个网址,这个网址就是官方的骨架屏的一个文档。从这里面我们可以看到骨架屏功能它有loadingtext.color等配置节点,在这个我们项目里面,有一个就是project.config.json这个配置文件。这个文件里面我们可以看到如我们现在屏幕上展示的这些配置字段,它可以配置骨架屏的一个默认样式以及它的一个默认行为,这些行为其中就包括动画行为,其中global节点控制所有页面的一个骨架屏风格,pages节点下面还可以分别控制每个页面的一个个性设置,注意修改配置以后要重新生成骨架屏代码。
微信开发者工具在生成时它会读取这些配置,开发者不要直接去修改生成的骨架屏的代码,如果是有个性控制的一个需要,我们可以通过修改这个配置然后进行控制,这样方便我们在多个骨架屏页面保持统一的一个风格。还有就是后续如果我们这个页面,就是我们主页它的WXML这个代码甚至它的JS逻辑代码如果有修改的话,还需要重新去生成骨架屏代码,开发者工具它是不会帮助我们自动去更新这个页面的。
第三点就是不要过度去使用骨架屏。
既然这个骨架屏它可以提高用户体验,那么我们为每一个小程序页面都添加一个骨架屏的效果 ,这样不是可以吗?有人可能会这样想对吧,一般不这样做。
一般我们只给主页去添加骨架屏效果,骨架屏它是小程序提供的一种优化用户体验的一个机制,但其实任何的一个渲染都有消耗,骨架屏也是。骨架屏本质上它是一个模板,我们可以看到它本质上是一个WXML文件,在主页里面引用以后其实引用的是一个template的模板,它和我们开发者自定义这个模板本质上没有区别。如果是在骨架屏里边我们再写了复杂的一些节点以及动画效果的话,反而不利于我们整体上小程序首页的一个快速加载和渲染。
一般我们推荐的方案是这样的,仅使用微信开发者工具,它默认生成的骨架屏,如果要修改的话也仅是修改一下,通过我们配置修改一下它整体上的一个样式,这些代码它里面的动画效果一般也不要去使用。页面布局改动以后,再重新根据我们源的页面再生成一下骨架屏这个页面代码。
在微信开发者工具的模拟器里面基于已经渲染的页面直接就可以快速生成骨架屏代码了。我们只需要在这个页面的data数据对象里面添加一个loading变量将其设置为true,并且在动态数据加载完成以后再将loading变量设置为false,这样就可以了。
但是我们也应该注意不能无节制地去使用骨架屏,还有给骨架屏组件使用的变量,我们在Page.onLoad这个事件派发之前要准备好,最好是直接写在data数据对象里面。