QCon 全球软件开发大会(北京站)门票 9 折倒计时 4 天,点击立减 ¥880 了解详情
写点什么

创新高性能移动 UI 框架 -Canvas UI 框架

2015 年 2 月 26 日

最近有人在知乎讨论 React Native,我也凑个热闹,来个技术贴。

WebView 里无法获得的能力虽然是「体验增强」与「端基本能力」,但现都基本上有成熟解决方法。但后期的 UI 和 Layout 的性能反而是目前 Web 技术欠缺的。所以,无论是 Titanium 与 React Native 都是解决性能作为探索的出发点。

性能慢与快的分水岭

慢与快的标准,是按照每秒大于等于 60 FPS(60 帧每秒) 的理论,而为什么是 60 FPS,这不多描述。

按此理论,那么「每帧」里所有的操作都必须在 16ms 完成。

WebView 里 UI 性能慢的原因

  • WebView 单线程模型;
  • DOM/CSS 排版复杂,渲染上需要大量计算;
  • 动画是也很重要的考量因素。

多说两句动画。

最早做动画都是用 setTimeout/setInterval。而 setTimeout/setInterval 的处理回调的时间 tick time 精度都在 16ms 左右。

所以,可以想象正常用这两个函数就已经 16 ms 了,再加 reflow/repaint/compositing 卡顿或跳帧就是家常便饭了。

还好的是 w3c 标准和各浏览器厂商较早就支持了动画接口 RAF(RequestAnimationFrame 函数)来处理动画帧回调。解决了上述 setTimeout/setInterval Animation 不足的问题。

DOM 性能低下的原因

浏览器执行的几个步骤:

restyle/reflow/repaint 触发条件:

了解完以上信息,考虑以下条件:

  • 把 JavaScript 逻辑、复杂的 DOM 与样式合成,并完成渲染;
  • HTTP 请求下载多媒体;
  • 在一个线程里;
  • 移动上的 ARM 架构;

以上操作能在每帧 16ms 里完成,想想都觉得是一件 TMD「不可思议」的事情。于是各种各样的奇葩优化出现了。

WebView 里高性能组件分类

已知的高性能组件的几类方法:

常规方法:

这类的原理主要是利用人为或规范的方式,减少 restyle/reflow/repaint 触发次数:

  • 通用组件优化 DOM 结构,甚至用 Virtual DOM(虚拟 DOM)减少 reflow 和 DOM 的复杂度;
  • 优化 CSS,少用或跳过 repaint 阶段。用编译的手段识别部分 CSS,将 left/top 变换变成 transform;

跳过 layout 与 paint 阶段,就是多使用 Layer composite 技术,即 css 的「opacity」和「transform」属性作动画。

只能在 css 和 DOM 结构上去抠出些性能优化的空间,缺陷优化空间有限;这种优化技巧通常是放在最后调优时冲剌使用,不能做为常规手段。

进阶方法

原理是尽可能利用 native 能力,甚至将 JavaScript 转换成 native App 代码。

  • 用 JavaScript 调起 native 组件,将增强与高性能组件交给 native 来处理,以前在 FEX 提的「轻组件」就是这么做的。这个原理类似 PC 时代的 ActiveX;
  • 将 WebView 里无法实现的功能用 native 实现。
  • 利用 native Activity 的渲染线程,分担浏览器渲染压力(WebViewCoreThread 是 WebView 线程)。
  • 最 dirty 的事在于处理 native 上 UI 的层次管理。需要后台有线程一直在检测 scroll/resize/ui change 时 UI 边界是否有相互覆盖与叠加的问题。
  • JavaScript 翻译成 Java/OC 代码。类似 React Native/Titanium,将 JavaScript 翻译成 native 代码,特别是 UI 组件上。(有兴趣的同学可以反编译 React Native 写的 Facebook Group)
  • 例:用 React,通过虚拟 Web UI 映射至 Native View,并且将代码逻辑翻译成 native。

新方法 — Canvas UI

这也是要说的重点,用「开发游戏」的思路来做 UI 组件探索,我把它称为 Canvas UI framework。

Canvas UI framework

用游戏的思路做 UI,最早我有这个想法是 2014 年。

为什么要用 Canvas?

Canvas 是 H5 的画布元素,即一个 DOM 元素。通过脚本控制逻辑给画布上增加文字与图像,而浏览器只需要绘制一次形成一幅图。

  • 只用一个 Canvas DOM 元素,降低 DOM 数量与渲染的复杂度,可以将原来 CPU 密集型变成 GPU 操作。绝大多数针对 Canvas 是用硬件 GPU 加速渲染。
  • GPU 的 ALU(计算单元) 比 CPU 要多很多,而控制运算(逻辑)则可以用 JavaScript 在 CPU 里做,甚至还可以用 WebWorker 多线程处理 CPU 密集型的操作,从而达到充分利用硬件资源的能力。
  • Canvas 画布无论是 JavaScript & H5,还是 native 都有类似的 API。所以:
  • 本地调试可在浏览器里完成。
  • 最差方案可以用 Canvas UI 跑在浏览器里。
  • 更进一步,可以把浏览器 Canvas 接口的反射到用 native 画布上,以此提高性能。

值得一提的是,腾迅的 X5 内核已经将 egret(白鹭游戏引擎与 cocos2dx)内置,所以时间线拉长来看,WebView 的画布功能将会更加强大。

在 2014 年中时,很多人见识过默认置入 cocos2dx 引擎的浏览器,用 WebView 玩「捕鱼达人」很流畅。

由此说明 Canvas 做 UI 组件可行性还是蛮高的。

解决方案

用游戏的思路来解决 DOM paint 的问题,业界早就有实验。最早实验的是 zynga 做 angry birds 游戏的厂家,2010 年写的 demo scroller:

设计、开发一个基于 Canvas 的 UI 框架系统,由于系统相对比较复杂,需接管浏览器构建的整个过程:

验证在实践环境中的效果,要把原来页面的 DOM 写成 canvas,再加上一些调优与比较,工作量相对大,(包括 zynga 也只是实现了一个简单的 demo 而已)

就暂时搁置了。

最近这阵子在翻 github 与新闻时,我惊喜的发现也有人在做同样的事了,最后发现 Flipboard 同学们写的一个 demo:

https://flipboard.com/@flipboard/flipboard-picks-8a1uu7ngz

这个 demo 足够复杂,动画也足够多、炫。是用 canvas 来构建整个 UI。

测试过后:

  • 这么复杂的 demo 在 MI4 以及配置以上性能很好,流畅度无限接近于 native,比较理想。
  • 对比过 G+ 的 Android 应用,G+ 的 App 从动画上比 Flipboard 提供的的 demo 还「卡」些。
  • 在小米 Note 上的动画流畅度已秒掉 iPhone 6,非常赞。

按照摩尔定律,可以预计明年 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 子集的解决方案,实现了:

  • padding
  • width
  • margin
  • border
  • flex
  • position( relative/absolute )

等等 Feature。

github 地址: https://github.com/facebook/css-layout

这些 css 布局子集基本能满足我们前期开发预期。

开发框架

用 css-layout 再加上 UI 管理层,就可以比较清晰的实现出 canvas 的 UI 组件框架了。那么,剩下的事就是:

  • 应用开发框架的选择,如:选择 React/MVC 框架。
  • 模拟 DOM 层次,即图层管理。

并且,让我非常欣喜的是,Flipboard 在 2 月已经完成了构建,基于 React 框架。 https://github.com/Flipboard/react-canvas

基于 css-layout + React 基础上整合而成。

Canvas UI 框架不足与风险

看上去 Canvas 框架这么牛逼,但有很多缺陷。

  • 对开发人员的要求较高。需要用 JavaScript 实现一些浏览器基本的布局、图层管理。
  • 第三方使用者学习成本高。不象是用传统「标签」就可以实现 UI 在浏览器的输出。
  • 开发者是否买账,对于框架的开发易用性有「很大」的挑战。
  • 对开发质量提出新要求。由于所有的 UI 组件与交互都在画布 Canvas 里,所以调试成本比较高,需要有较为完整的 Logging 与 Debugging 方案。
  • 用户可用性会受影响。例如:* 语音无法识别 Canvas 里的文字。* 无法象 WebView 里一样将画布里的文字选中并复制出来。

总结

Canvas UI 框架作为柳暗花明又一村的技术。 https://github.com/Flipboard/react-canvas 短短一周多,已经近 4K 的 star。确实很赞。

与其看 FB 开源 react native,不如好好研究 react-canvas 吧。


刘平川是QCon 北京2015 大会的讲师。更多精彩内容尽在 QCon 北京 2015 ,现在购票可享 9 折优惠。

感谢郭蕾对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。

2015 年 2 月 26 日 20:1617185

评论

发布
暂无评论
发现更多内容

新思科技发布《美国不良软件质量成本:2020年报告》

InfoQ_434670063458

软件质量 新思科技

kotlin高阶函数let、with、apply、run、also使用场景

陈吉米

kotlin

内存数据库解析与主流产品对比(三)

星环科技

数据库 大数据

【推荐收藏!】Gradle 与 Android 构建入门

百度Geek说

研发工具 andiod

阿里巴巴内部MySQL宝典意外流出!极致经典,堪称数据库的天花板

Crud的程序员

MySQL 数据库

《程序员修炼之道》- 务实的哲学(3)

石云升

读书笔记 28天写作 批判性思维 程序员修炼之道 完成好过完美

Flink 学习路线总结

大数据学习指南

大数据 flink

抽奖助手利益相关方

杨柳

爱了!Alibaba技术官甩出的SpringCloud笔记,GitHub已标星81.6k

周老师

Java 编程 程序员 架构 面试

拍乐云 Flutter SDK 全新发布,跨平台音视频开发更easy

拍乐云Pano

flutter 音视频 WebRTC RTC

译文《全新首发JDK 16全部新特性》

潘潘和他的朋友们

Java jdk JVM

译文《最常见的10种Java异常问题》

潘潘和他的朋友们

Java 异常 java异常处理 Exception

Alibaba最新产物手册宝典:分布式核心原理解析,简直是Java程序员福音!

996小迁

Java 架构 分布式 面试程序人生 面试c

一周信创舆情观察(1.18~1.24)

统小信uos

Redis核心剖析:为什么这么“快”的秘密

Java架构师迁哥

厌倦了EXCEL想玩点新花样?教你利用Python做数据筛选(下)

智分析

Python

产品训练营--第二期作业

曦语

产品训练营

内存数据库解析与主流产品对比(一)

星环科技

数据库 大数据

关注直播 走近滴滴夜莺K8S监控组件

Obsuite

k8s 滴滴技术 监控告警 滴滴夜莺

一文读懂Java动态代理

潘潘和他的朋友们

Java jdk 动态代理

数据库恢复子系统的常见技术和方案对比(一)

星环科技

数据库 大数据

从零开始学习Git

ITCamel

git SSH

智慧社区建设,平安社区解决方案服务商

135深圳3055源中瑞8032

“区块链+电子证照”-助推数字政府建设

135深圳3055源中瑞8032

读阿里P8大佬15W字的Spring文档,面试犹如开了挂,成了Offer收割机

Crud的程序员

spring

区块链+数字版权-区块链技术如何保护版权

135深圳3055源中瑞8032

数据库恢复子系统的常见技术和方案对比(二)

星环科技

数据库 大数据

内存数据库解析与主流产品对比(二)

星环科技

数据库

TcaplusDB常见问题-数据库原理类

TcaplusDB

数据库 nosql 分布式 游戏开发

就业篇-如何抉择自己合适的路

小诚信驿站

团队管理 团队建设 成长笔记 28天写作

区区一个SpringBoot问题就干趴下了?我却凭着这套“神级PDF文档”吊打面试官

云流

Java 编程 面试 微服务

边缘计算隔离技术的挑战与实践

边缘计算隔离技术的挑战与实践

创新高性能移动 UI 框架-Canvas UI 框架-InfoQ