提升HTML5的性能体验系列之一 避免切页白屏

白屏 切换页面 性能 转场

提升HTML5的性能体验系列文章目录导航:
- [提升HTML5的性能体验系列之一 避免切页白屏]
- 提升HTML5的性能体验系列之二 列表流畅滑动
- 提升HTML5的性能体验系列之三 流畅下拉刷新
- 提升HTML5的性能体验系列之四 使用原生UI(nativeUI)
- 提升HTML5的性能体验系列之五 webview启动速度优化及事件顺序解析
- 提升HTML5的性能体验系列之六 降低内存占用

最后更新时间:2017年10月7日。

窗体切换白屏的现实问题

HTML5的性能比原生差很多,比如切页时白屏、列表滚动不流畅、下拉刷新和上拉翻页卡顿。
在低端Android手机上,很多原生App常用的功能和体验效果都很难使用HTML5技术模拟。
我们首先来看第一个问题,如何避免切页白屏。

浏览器的页面在切换时,由于其页面加载机制,在跳转到下一个页面时,先要请求联网、载入页面代码、构建dom、渲染,最后才显示出来。
在最终结果渲染完毕前,会出现几十毫秒甚至数秒的白屏。原生App是没有这个问题的。
虽然使用SPA单页应用模型,即ajax+div切换也可以避免白屏,但把所有页面写在一个SPA页面里,简单几个页面还行。但页面多了手机上也跑不起来,初始化非常慢,首页必然白屏,而且工程大了代码那个乱。。。被坑过的人自然知道。

解决窗体切换白屏的方案

标准HTML5无法解决,我们就使用扩展的手段。
HTML5+是一套增强HTML5的规范,它可以用JS调用几十万原生API。
想要解决切页白屏这个问题,需要使用plus.webview类来做MPA多页应用(不是SPA单页应用)。
plus.webview类是对原生的webview对象的js化封装,使用js可以操作webview。
解决白屏的原理是:把每个页面当作一个webview,但用js来控制它就像控制div一样。动画时通过原生的view动画飘webview进来而不是通过css动画飘div进来
同时webview之间相互独立,不会出现SPA下不同页面js和css冲突的问题。

通过操作webview来避免切页白屏,有几种常见的做法:

1、动画先飘不会白屏的原生title进来

既然webview加载慢,转场动画会白屏。原生view加载快,不会白屏。那么能不能使用原生view呢,或者至少动画时先飘一个原生view的title进来,也不会整屏白屏。
HBuilder7.2起,提供了plus.nativeObj.View,也就是原生的view对象(以下简称nview),可以使用js向原生的view直接写字、绘图(注意是原生view不是webview)。
从HBuilder8.8起,优化了nview和Webview的关系,为Webview引入了titleNView和subNView,是从属于Webview的原生界面。titileNView也称ntitle,进一步对title的原生化做了简化了操作,在plus.webview的style里,可以配置titleNView,如下示例:

plus.webview.create('new.html', 'new', {'titleNView':{'backgroundcolor':'#FFFFFF','titletext':'标题栏','titlecolor':'#FF0000'}});

这样创建webview时,会自带一个原生的title,文字、颜色、是否有返回箭头、分割线这些都可以设置,见http://html5plus.org/doc/zh_cn/webview.html#plus.webview.WebviewTitleNViewStyles。还可以通过getTitleNView()方法得到一个nview对象,自由的向上面写字、绘图、处理点击响应。参考nview文档http://html5plus.org/doc/zh_cn/nativeobj.html#plus.nativeObj.View
如果只是简单修改,比如修改title文字,也可以通过重设TitleNView的style来实现:
plus.webview.currentWebview().setStyle({titleNView:{titleText:'new text'}})

在mui框架中,进一步简化封装了mui.openWindowWithTitle()方法,参考http://dev.dcloud.net.cn/mui/window/#openWindowWithTitle

上面title有了,中间空白处可以先转个plus.nativeUI.waiting的原生雪花或显示加载中,这样转场时就不会飘白屏了。
一般本地页面加载都很快,转场动画300毫秒结束时,页面也渲染出来了。

另外提供几个让HTML页面渲染快的方法
- 页面渲染尽量不用js做,想要渲染快,就直接写HTML和css渲染,js渲染的界面显示更慢。
- 少用padding、margin,尽量写简单的代码,让页面一次渲染到位,而不是反复触发重绘。
- 减少图片尺寸,不要使用背景图(最常见的性能问题均来自于此)

理解了titleNView,我们再来看subnview。
同理,subnview也是原生渲染的view,它可用于更大面积的原生渲染。
在流应用里的唯品会中,商品详情界面的加载速度那么快,就是因为使用了subnview。参考视频http://v.qq.com/x/page/k05051mc143.html。
一般业务有titleNView就够了,追求极致体验的业务可以使用subnview。
所谓追求极致,就是要求在100毫秒渲染,动画期间就要完成联网和渲染。即使原生应用,大部分业务也是在动画完成后才渲染界面的。
使用subnview要在页面里大量通过js构造界面,不太直观。HBuilder8.3.3起,新增了wap2app项目,其中引入了nview模板,新建一个nview文件,可以使用类vue的方式开发,参考http://ask.dcloud.net.cn/docs/#//ask.dcloud.net.cn/article/12757。后续会把nview模板引入到5+应用开发中。

延伸:既然有nview,那是不是可以使用nview做完整界面,废除webview?类似react native那样。
DCloud一直遵循的是HTML5+的规范和理念,即不推翻HTML,而是在HTML做的不好的地方强化补足。
即使在动画期间大量使用了subnview,但滚动后的完整的页面仍然应该是HTML的。
这样的解决方案即能满足用户体验要求,又能兼容好HTML5,是更好的解决方案。

早些年mui曾推荐使用过head和body分开载入的方案,此方案已废弃,由这里描述的原生title方案替代。

2、预加载html

既然HTML渲染慢,是否可以后台预加载,需要使用时直接动画进来?
当然是可以的。所谓预载,即后台预载新页面的HTML文件及资源,使用时直接调出这个已经创建好的webview。
尤其是从一个列表页面反复打开详情页面,仅仅是其中的数据不同,此时应该预载和复用详情Webview。
在Hello mui里有一个列表到详情的最佳实践示例,就是使用了这个思路,强烈建议大家在列表到详情时研究使用这个示例。文章参考http://ask.dcloud.net.cn/article/12575

只要服务器返回数据不拖后退,一样可以实现100毫秒渲染,动画期间完成联网和渲染。

预加载,由于不显示出来,并不会过多增加资源占用。(同时显示在屏幕上的webview不要超过3个,隐藏在后台的webview不要超过10个)
如果是list转到content,不同的item点击只是一个页面,完全可以使用预载。
但如果页面不同且较多,此时不建议预载太多Webview。后台预载太多webview需要耗很长,会抢cpu,此时用户如果在前台显示的Webview里操作比如滚动列表,会感觉到卡。

mui框架的窗体函数封装

mui框架为了简化窗体管理的工作,把一些常用的窗体模型做了简化封装。
但对于复杂的窗体切换,仍需开发者搞明白上面提到的窗体切换原理。
mui的init方法,通过参数封装了preload,这样就可以方便的预载webview。
mui的openWindow方法,封装了显示waiting,载入新页面,处理动画,关闭waiting等工作。
mui的openWindowWithTitle()方法,封装了原生title。
mui的back样式控制,自动封装了窗体的隐藏和关闭。
这些方法具体参考mui的js API。

启动后首页的白屏

首页是没有预加载的概念的。
首页的控制基本都在manifest里进行。
有2个与启动白屏有关的manifest设置。
1.launchwebview
在launchwebview里可以配置首页的titlenview,以及使用subnview制作tab。
这样顶部和底部实际上是由原生引擎渲染的,可以迅速显示。
参考文章:基于subnview模式的原生tab

  1. splashscreen
    启动封面的图片如何关闭是在manifest里配置的。
    默认是在首页的webview的loaded事件发生后关闭。但又提供了若干选项。
    不管你的首页是白屏了还是觉得进入太慢了,都可以控制。
    在工程下manifest.json里找到plus、splashscreen节点,这里有event选项,可以配置是在哪个事件时close splash,默认是loaded,也可以配成titileUpdate、rendering、rendered。
    默认配置loaded事件是偏保守的,避免有的开发者首页代码写的不高效,导致白屏。
    如果你的首页代码效率高、渲染快,则推荐配置成titileUpdate事件。

还有一种手动控制splash关闭的技巧,如果splashscreen节点下的autoclose设置为false,即手动,可以在首页代码里写js控制封面图片的消失时机。
此时在首页合适的位置,比如说联网结束或业务上的其他时间点,调用js关闭封面图片,plus.navigator.closeSplashscreen();
但不管什么方法,5+引擎的splash显示时间不会超过6秒,如果6秒内开发者仍不能做到首页渲染,那么用户会看到白屏。

关于如何优化启动速度,可以参考这篇文章http://ask.dcloud.net.cn/article/571

5+动画详解

这篇文章详细描述了5+提供的各种原生动画的特点及优化技巧,是必读文章http://ask.dcloud.net.cn/article/225

Android5的动画花屏、分块渲染解决方案

如果你遇到了相关问题,可以参考http://ask.dcloud.net.cn/article/12837

后记

不管使用哪种方法,都要注意一点,手机App的HTML页面必须本身性能足够高。
这是老生常谈的问题,但现实中还是大量App因为这个问题而导致性能体验出问题。
编写干净整洁、一次渲染的页面非常重要。
现在太多开发者在研究模式、框架,让页面渲染要经历二次、甚至四五次重绘才能完成。在短短几百毫秒的动画期间,这么干要不让页面卡、要不让渲染慢。
减少js二次渲染很重要的就是减少使用js渲染页面,页面结构要用简单朴素的HTML写,js可以动态填充数据,但如果js动态绘制页面主体,那渲染速度上不去。
减少css二次渲染,就是少用复杂的选择器,少用padding、margin这些会二次修正页面的css。
如果追求极致的话,那jquery、zepto这些框架也不要使用,手机上都是webkit引擎,直接写document的api操作dom即没有兼容问题又没有效率问题。

提升HTML5的性能体验系列之一 避免切页白屏相关推荐

  1. 提升html5的性能体验系列之一避免切页白屏

    窗体切换白屏的现实问题 HTML5的性能比原生差很多,比如切页时白屏.列表滚动不流畅.下拉刷新和上拉翻页卡顿. 在低端Android手机上,很多原生App常用的功能和体验效果都很难使用HTML5技术模 ...

  2. [重磅] 让HTML5达到原生的体验 系列之一 避免切页白屏

    很多人都想.甚至曾使用HTML5开发跨平台App,并且想达到原生App的体验. 最后的结果都是无奈的放弃,HTML5貌似美好,但坑太多,想做到原生App的体验几乎不可为. 也曾有过著名的faceboo ...

  3. [重磅] 让HTML5达到原生的体验 系列之中的一个 避免切页白屏

    非常多人都想.甚至曾使用HTML5开发跨平台App.而且想达到原生App的体验. 最后的结果都是无奈的放弃.HTML5貌似美好,但坑太多.想做到原生App的体验差点儿不可为. 也曾有过著名的faceb ...

  4. 【Android 性能优化】应用启动优化 ( 启动白屏问题 | 应用启动时间测量 | 冷启动 | 热启动 | 应用启动时间计算源码分析 )

    文章目录 一. APP 启动白屏 / 黑屏 二. APP 启动速度测量 1. 通过 Logcat 日志查看应用启动时间 2. 通过 adb 命令查看界面启动时间 三. APP 冷启动与热启动 四. A ...

  5. 前端白屏问题_前端性能优化之白屏时间

    前言 该篇文章会为您分享在前端性能优化中非常重要的一环-白屏时间,将从白屏时间的概念.重要性以及白屏的过程一一进行阐述,同时提供性能优化的策略与实践. 一.概念 白屏时间:即用户点击一个链接或打开浏览 ...

  6. 服务器显示屏出现白屏,前端性能优化之白屏时间

    定场诗 曲木为直终必弯,养狼当犬看家难: 墨染鸬鹚黑不久,粉刷乌鸦白不天. 蜜饯黄莲终需苦,强摘瓜果不能甜: 好事总得善人做,哪有凡人做神仙. 前言 该篇文章会为您分享在前端性能优化中非常重要的一环- ...

  7. 小程序字符串提取图片地址src导致苹果手机体验版白屏

    小程序开发中想把一段html字符串里图片的src取出来,这段html字符串如下图: var srcReg = /(?<=(src="))[^"]*?(?=")/ig ...

  8. 【Webpack 性能优化系列(8) - PWA】使用渐进式网络应用程序为我们的项目添加离线体验

    webpack系列文章: [Webpack 性能优化系列(9) - 多进程打包]极大的提升项目打包构建速度!!! [Webpack 性能优化系列(7) - 懒加载和预加载] [Webpack 性能优化 ...

  9. 手机支持html5绘图性能,【高级系列】Canvas绘制性能专题

    总原则: 在移动APP中,因为手机硬件性能有限,其实不宜做太多特效,应该往简洁突出重点的方向考虑. 1 性能建议 英文引文地址: 提高HTML5 canvas性能的几种方法! 1.1 预渲染 1.PR ...

最新文章

  1. AIX的用户和组管理
  2. 移位运算[c][code]
  3. 一份来自亚马逊工程师的Google面试指南,GitHub收获9.8万星,已翻译成中文
  4. 恢复SQL Server被误删除的数据
  5. linux扩充单个路径下的内存,超详尽!Linux云服务器存储扩容实操
  6. 在 VS Code 中轻松 review GitHub Pull Requests
  7. CF535C Tavas and Karafs 二分 + 结论
  8. normalize函数_Pandas 数据处理(一) —— 几个简单函数掌握!
  9. 04-07 接口请求构造
  10. 十年后,若中国基建基本完成了,还有什么能大规模拉动经济?
  11. spring配置线程池
  12. IEnumerable和使用收益回报的递归
  13. 蓝湖 for Mac(自动切图sketch插件)中文版
  14. 智慧解析第20集:破解迷魂术
  15. 谷歌浏览器安装插件教程步骤,开发用这2个插件工作效率倍增
  16. VUE使用百度地图API实现三维地球
  17. 联想一键恢复系统教程
  18. MES的发展历程及功能模块
  19. Python解析json文件
  20. 【MATLAB】命令行窗口乱码问题

热门文章

  1. Numpy库及ndarrary基础知识
  2. js控制屏幕双屏显示
  3. 学习ARM开发(15)
  4. com.alibaba.fastjson.JSONException: syntax error, pos 1, line 1, column 2
  5. 肿瘤免疫新抗原鉴定(一)OptiType安装与运行
  6. Windows 上的网络通信编程
  7. 修改google搜索引擎非hk方法
  8. 什么是 RESTful ?
  9. 钉钉企业内部机器人python开发(公网部署版本)
  10. Flask 蓝图 Blueprint