【编者按】百度FEX总负责人刘平川针对讨论热烈的React Native,发表文章提出了用“开发游戏”的思路来做UI组件探索,并将它称为Canvas UI Framework。文中详细介绍了Canvas UI 框架的设计理念及解决方案。全文转载如下:
欢迎加入CSDN前端交流群:218126086,进行前端技术交流。
最近有人在知乎讨论React Native,我也凑个热闹,来个技术贴。
WebView里无法获得的能力虽然是“体验增强”与“端基本能力”,但现都基本上有成熟解决方法。但后期的UI和Layout的性能反而是目前Web技术欠缺的。所以,无论是Titanium与React Native都是解决性能作为探索的出发点。
性能慢与快的分水岭
慢与快的标准,是按照每秒大于等于60FPS(60帧每秒)的理论,而为什么是60FPS,这不多描述。
按此理论,那么“每帧”里所有的操作都必须在16ms完成。
WebView里UI性能慢的原因:
多说两句动画。
最早做动画都是用setTimeout/setInterval。
而setTimeout/setInterval的处理回调的时间tick time精度都在16ms左右。
所以,可以想象正常用这两个函数就已经16ms了,再加reflow/repaint/compositing卡顿或跳帧就是家常便饭了。
还好的是W3C标准和各浏览器厂商较早就支持了动画接口RAF(RequestAnimationFrame函数)来处理动画帧回调。解决了上述setTimeout/setInterval Animation不足的问题。
DOM性能低下的原因
浏览器执行的几个步骤:
restyle/reflow/repaint触发条件:
了解完以上信息,考虑以下条件:
以上操作能在每帧16ms里完成,想想都觉得是一件“不可思议”的事情。
于是各种各样的奇葩优化出现了。
WebView里高性能组件分类
已知的高性能组件的几类方法:
(1)常规方法
这类的原理主要是利用人为或规范的方式,减少restyle/reflow/repaint触发次数:
(3)新方法——Canvas UI
这也是要说的重点,用“开发游戏”的思路来做UI组件探索,我把它称为Canvas UI Framework。
Canvas UI Framework
用游戏的思路做UI,最早我有这个想法是2014年。
为什么要用Canvas?
Canvas是H5的画布元素,即一个DOM元素。通过脚本控制逻辑给画布上增加文字与图像,而浏览器只需要绘制一次形成一幅图。
所以:值得一提的是,腾迅的X5内核已经将egret(白鹭游戏引擎与cocos2dx)内置,所以时间线拉长来看,WebView的画布功能将会更加强大。
在2014年中时,很多人见识过默认置入Cocos2dx引擎的浏览器,用WebView玩“捕鱼达人”很流畅。
由此说明Canvas做UI组件可行性还是蛮高的。
解决方案
用游戏的思路来解决DOM paint的问题,业界早就有实验。
最早实验的是zynga做Angry Birds游戏的厂家,2010年写的Demo Scroller:
https://github.com/zynga/scroller
设计、开发一个基于Canvas的UI框架系统,由于系统相对比较复杂,需接管浏览器构建的整个过程:
验证在实践环境中的效果,要把原来页面的DOM写成Canvas,再加上一些调优与比较,工作量相对大,(包括zynga也只是实现了一个简单的Demo而已)
就暂时搁置了。
最近这阵子在翻Github与新闻时,我惊喜的发现也有人在做同样的事了,最后发现Flipboard同学们写的一个Demo:
https://flipboard.com/@flipboard/flipboard-picks-8a1uu7ngz
这个Demo足够复杂,动画也足够多、炫。是用Canvas来构建整个UI。
测试过后:
按照摩尔定律,可以预计明年Note的标配的CPU和GPU配置会成为主流。
而现在用Canvas UI框架用在MI4以下机器仍然比较慢。而2015年H5开发App,对很多公司来说只是plan B计划,大公司甚至plan B都不是。所以,如果一定要在纯H5上搞牛逼动画,还是再等等吧。
布局系统CSS Layout
说回到Canvas Component Framework,回到我上面画的这张图:
UI组件基于“文本”与“图像”。但Framework,除了UI组件本身以外,还需要有Layout,而CSS只适用于浏览器本身的Layout而无法适用于Canvas画布。
要给开发者好且排版可控的方案,那就要开发一个用JavaScript实现类似CSS的布局子集的框架。
否则UI的组件在画布上没有Layout就无意义。
这个布局框架实现成本(简单实现)理论上并不大,大的是在于未来增加新Feature并相互组合时与浏览器本身有差异,需要有完整的Unit Test。
正好最近Facebook也开源了一个用JavaScript写CSS Layout子集的解决方案,实现了:
等等Feature。
Github地址:https://github.com/facebook/css-layout
这些CSS布局子集基本能满足我们前期开发预期。
开发框架
用css-layout再加上UI管理层,就可以比较清晰的实现出Canvas的UI组件框架了。
那么,剩下的事就是:
总结
Canvas UI框架作为柳暗花明又一村的技术。https://github.com/Flipboard/react-canvas短短一周多,已经近4K的star。确实很赞。
与其看Facebook开源React Native,不如好好研究react-canvas吧。
本文转载自: