DCloud_heavensoft
DCloud_heavensoft
  • 发布:2015-05-24 19:17
  • 更新:2019-06-26 17:28
  • 阅读:19626

5+动画详解

分类:HTML5+

转场动画是App非常重要的处理环境,要做到流畅不丢帧、快速渲染。

一般的动画只有300毫秒,要在短短的300毫秒内完成很多事情,包括新窗体创建、加载HTML、渲染内容、以60fps的方式移动窗体。。。
想想也是大难题。
所以开发者要非常重视动画的优化,否则很容易动画卡顿或页面渲染慢。

动画类型简述

5+中,Webview和nview均支持动画转场。这些动画都是native的动画,而不是css动画。
实际开发中,完全使用nview的动画转场比较少见,后面会单独介绍它的特殊用法,大多是Webview动画或含有subnview的Webview动画。

动画分进入和返回,这里是5+Webview的进入动画参数文档
http://html5plus.org/doc/zh_cn/webview.html#plus.webview.AnimationTypeShow

一般情况下,开发者只需要设置进入动画,返回动画是自动反向的。
比如设置进入是pop-in,那返回默认就是pop-out。
当然开发者也可以在返回时指定不同的动画类型,参考http://html5plus.org/doc/zh_cn/webview.html#plus.webview.AnimationTypeClose

常见的动画类型包括:
slide-in-right(从右侧横向滑入新窗体,覆盖老窗体)
pop-in(从右侧横向滑入新窗体,老窗体同时向左小幅移动,即新旧窗体联动挤压)
fade-in(从透明到不透明逐渐显示效果,常见于选项卡tab切换)

如果不指定动画类型,动画默认是slide-in-right。
pop-in是前后2个窗体联动挤压式动画,资源消耗大于slide-in-right,如果不注意优化,在Android手机上会有性能问题。

动画优化的常见策略

如果你的页面简单,使用默认的slide-in-right毫无性能问题,或者只是在iOS上使用pop-in,那可以暂时忽略本章节。
如果你页面复杂,或者使用了更耗资源的popin动画,或者动画已经出现卡顿、花屏、白屏等体验问题,请认真往下阅读。
做好动画的性能优化,一般有5招:

1. 动画期原生渲染

在Webview的style里设置titleNView和subnview,在动画期间让nview来渲染界面,而不是Webview。
nview的渲染速度比Webview快太多,并且动画稳定程度很高。
titleNView是几乎每个页面都必备的,subnview视情况而定。如果页面动画效果不够好,可以用这个来深度优化。
下面的视频是使用了subnview的流应用和原生应用的对比视频,可以看出subnview的效果非常好。https://v.qq.com/x/page/k05051mc143.html

2. 预载和重用

如果是列表到详情的转场,推荐使用预载+重用的方案。
在Hello mui的底部,有一个“从列表到详情的最佳实践”,就是把详情页面预载并重用了。每次点击列表上的item时,瞬间就出现了。
如果是本地数据或服务器联网非常快,这种方案甚至不需要动画过渡,把动画设为none,点击后界面立即出现。
具体方案有单独文章介绍:http://ask.dcloud.net.cn/article/12575
下面的视频就是应用了预载和重用的界面切换效果的视频对比:https://v.qq.com/x/page/v0507i0f05w.html

3. 截屏

动画期移动Webview的压力还是比较大的,尤其在低端机上运行popin动画,此时出现了一种截屏方案,即动画是移动的不是Webview,而是截图。
在窗体动画的规范里,http://html5plus.org/doc/zh_cn/webview.html#plus.webview.WebviewExtraOptions,有一个acceleration参数,值域包括 "auto" - 自动优化窗口动画; "none" - 关闭窗口动画加速功能; "capture" - 使用截屏方式加速窗口动画。 默认值为"auto"。
这里的capture,就是指动画时飘动的是截图而不是真的webview。
此时5+引擎在执行动画前,会先对新入的webview进行静态截屏,然后动画过程会移动静态截屏进来,这样的动画就会流畅稳定。而真实的Webview并不会移动。
但截屏方案也有需要注意的事项:

  • 注意1:截屏需要消耗时间,会导致动画的启动速度变慢几十或几百毫秒。如果是返回动画应用了截屏,那么会发现点了back后延迟了一点动画才启动。
  • 注意2:截屏后,动画期间就是静态图,不会在动画期间看到页面内容持续增加渲染的过程。
  • 注意3:变色问题。使用截屏加速动画如果发现动画界面的背景色变色,一般是因为新入窗体背景色设置了透明度,就是rgba里面的那个a,或者设置了渐变色。
    截屏动画使用的图像是不支持透明和渐变色的,建议把新webview里的透明度、渐变色相关设置去掉。不止是为了截屏动画不失真,在手机端透明度和渐变色本身也是非常耗费手机资源的,能不用就不用。

acceleration的默认值auto的策略需要详细解释下:
auto的意思是由5+引擎根据情况自动配置是否使用截屏加速,HBuilder8.3.3起,这个auto策略调整如下:

  • pop-in/pop-out动画
    Android5.0及以上:默认不使用截屏加速
    Android5.0以下:如果Webview中存在subNView则pop-in动画默认不使用截图加速,pop-out动画默认使用截图加速;如果Webview中不存在subNView则默认不使用截图加速
    使用截屏加速可能会引起动画延迟响应(截屏操作耗时),因此调整默认保证pop-in动画流畅, pop-out动画避免闪屏。

  • slide-*动画
    默认不使用截图加速
    此种情况下如果碰到页面分块渲染,应该避免在页面中使用高分辨率图片,或者关闭硬件加速,或者使用subNView来优化页面。具体参考http://ask.dcloud.net.cn/article/12837
    (之前版本在Android5.0及以下设备上窗口关闭时使用截图加速)

  • fade-in/fade-out动画
    默认使用截图加速

如果默认的auto策略不称心,开发者可以自行调整。创建Webview时生效,不支持创建后动态调整。

4. 减少动画期的其他运算

动画未完成时,也就是在动画运行的200-300毫秒期间,不管新入页面,还是老页面,都要注意节约计算和渲染资源,不要做消耗资源的其他事情。
新入页面的运算和渲染,要分层处理,与动画显示无关的部分,应该延后到动画结束后再处理。
举个例子,如果新入的界面里设置了plus提前生效并立即预载了另一个页面C,由于预载会占用cpu,过早预载就造成pop-in动画快结束时卡一下。其实页面C的预载不需要这么急,应该在新入页面loaded之后延时1秒再预载不迟。

5. 减少HTML页面的渲染复杂度

这是老生常谈的问题,但现实中还是大量App因为这个问题而导致性能体验出问题。
编写干净整洁、一次渲染的页面非常重要。
现在太多开发者在研究模式、框架,让页面渲染要经历二次、甚至四五次重绘才能完成。在短短几百毫秒的动画期间,这么干要不让页面卡、要不让渲染慢。
减少js二次渲染很重要的就是减少使用js渲染页面,页面结构要用简单朴素的HTML写,js可以动态填充数据,但如果js动态绘制页面主体,那渲染速度上不去。
减少css二次渲染,就是少用复杂的选择器,少用padding、margin这些会二次修正页面的css。

Android下popin动画的额外限制

两个webview挤压是比较容易做的,但3个或更多webview挤压会产生很多问题。目前只有iOS支持3个webview挤压动画。Android不支持3个webview的挤压动画。
从HBuilder8起,官方已经废除多Webview同屏并显、父子Webview之类的方案。如果开发者使用nview替代了同屏多Webview,就不会遇到这个坑。

nview动画在SPA应用中的使用场景

上面讲的基本是Webview的动画。其实5+还支持纯nview的动画。
假使开发者已经完成了一个SPA的单页应用,但动画肯定是卡的不行,此时可以把这个项目导入到HBuilder中,利用nview动画做一个封面动画,来弥补SPA的动画卡顿问题。比如点击列表项时:

  1. 使用js创建一个独立nview(不创建Webview,也不设置subnview,就是一个独立nview),在nview上自己画title和一些界面元素。
  2. 把这个nview做动画移动进来。这样动画看起来很平顺,虽然是一个假的封面吧。
  3. 不要再使用div动画了,让spa的详情视图的div直接渲染内容,渲染完毕后关闭nview,漏出SPA的div界面。
  4. 注意这种用法,nview的创建、位移、隐藏、关闭、重用,全部需要使用js api手动控制。
    具体参考http://html5plus.org/doc/zh_cn/nativeobj.html#plus.nativeObj.View

uni-app

uni-app框架层使用了自动的预载技术,转场非常快。
但有时新页面渲染太快,且新页面里渲染大图和新页面动画一起进行,就会抢资源,引发动画掉帧。
如果遇到这种问题,可适当延时新页面的大图加载,或优化图片尺寸。
uni-app还支持nvue的weex渲染,性能也很高。

30 关注 分享
Android_mabo 蔡繁荣 Geeker tjs 07560255833 M5 唐糖 hilongjw 默默39 8023 佳人逝水丶 freechina running Xero lyndsey zgrlbq bzliukai 小郭哥 MooGu 周羊羊 xiaohei111 最爱橙子 雪之梦技术驿站 156359098 137068774@qq.com Android_XR gaohuazi 取代原生 1422667480@qq.com Eason

要回复文章请先登录注册

余红杰

余红杰

nview 的“pop-in”动画结束,view就快速回弹消失了
2018-10-31 19:52
MS橘子小姐

MS橘子小姐

针对第四点有点疑问。@DCloud_heavensoft,
1.不支持多webview挤压,那侧滑页面只能写在主界面了,根据条件判断显隐按钮???
2.如果这样,。主界面是写了滑动事件的。。但是滑动打开关闭侧滑都无效。。。只能点击触发事件。。
window.addEventListener("swiperight", openMenu);
window.addEventListener("swipeleft", closeMenu);
window.addEventListener("menu:close", closeMenu);
2017-03-29 14:44
e891377@126.com

e891377@126.com

要是有个git看一下就好了
2017-01-19 09:33
wowkk@qq.com

wowkk@qq.com

mask
2016-07-21 17:40
jingxin

jingxin

有些页面css写的不好,会二次渲染,即开始时页面显示一个样子,很快页面被二次渲染显示成另一个样子。

请问写css的时候要注意些什么呢?我现在的页面就是这样的,可是不知道哪个css有问题了,实在是头疼,找不到原因
2016-06-20 23:23
周羊羊

周羊羊

mark
2016-05-20 08:57
蝮蛇

蝮蛇

lihaia
2016-04-15 18:00
bzliukai

bzliukai

马克
2015-12-17 17:38