窗体切换白屏的现实问题
HTML5的性能比原生差很多,比如切页时白屏、列表滚动不流畅、下拉刷新和上拉翻页卡顿。
在低端Android手机上,很多原生App常用的功能和体验效果都很难使用HTML5技术模拟。
我们首先来看第一个问题,如何避免切页白屏。
浏览器的页面在切换时,由于其页面加载机制,在跳转到下一个页面时,先要请求联网、载入页面代码、构建dom、渲染,最后才显示出来。
在最终结果渲染完毕前,会出现几十毫秒甚至数秒的白屏。原生App是没有这个问题的。
虽然使用SPA单页应用模型,即ajax+div切换也可以避免白屏,但把所有页面写在一个SPA页面里,页面多了手机上也跑不起来,而且工程大了代码那个乱。。。被坑过的人自然知道。
解决窗体切换白屏的4种方案
标准HTML5无法解决,我们就使用扩展的手段。
HTML5+是一套增强HTML5的规范,它可以用JS调用几十万原生API。
想要解决切页白屏这个问题,需要使用plus.webview类来做MPA多页应用。
plus.webview类是对原生的webview对象的js化封装,使用js可以操作webview。
解决白屏的原理是:把每个页面当作一个webview,但用js来控制它就像控制div一样。
因为webview可以隐式创建,后台载入内容,并且在载入完毕时有js事件通知,我们可以在新页面载入完成后再把它通过动画移入屏幕,从而避免白屏。
同时webview之间相互独立,不会出现SPA下不同页面js和css冲突的问题。
通过操作webview来避免切页白屏,有几种常见的做法:
一种是称之为预载,即后台预载新页面的HTML文件及资源,使用时直接调出这个已经创建好的webview;
另一种称之为现载,即点击前页的链接开始走waiting转圈,同时后台开始加载完整的新页面,加载完再用js控制显示到前台。
还有一种称之为分开载入,随后会细讲。
- 1、预加载
所谓预载,即后台预载新页面的HTML文件及资源,使用时直接调出这个已经创建好的webview。
Hello mui、csdn、36kr等项目源码,都使用了预载思路。
以新闻类app为例,启动首先载入资讯列表list页面,然后后台创建了一个隐藏的webview,加载了一个内容模板show页面。
在点击list页面的一个新闻item时,调用webview的窗体控制动画,把show页面侧滑进屏幕。
但show页面仅仅是一个模板而没有数据,在show页面刚侧滑进屏幕时,在show页面有一个“加载中”的提示。
紧接着show页面开始执行ajax请求,联网加载数据并显示出来。
我们可以在list页面的item点击里,一边移动窗体,一边通知新页面执行ajax。webview间相互传递消息使用webview的evalJS方法。
这种做法,相当于用户是在新的show页面来等待联网数据。
示例代码如下: