盘点主流移动端跨平台UI技术:实现原理、技术优劣、横向对比等

当前最热的跨平台UI技术无疑非 Flutter 莫属,Flutter通过自绘 UI 组件,构建高质量跨平台组件库,解决了此类框架难以解决的双端一致性, Bridge 通信效率等问题。并提供丰富的 Widget 组件,渲染性与 Native UI 相媲美,掀起了大家对下一代跨平台技术探索的热情。

同时对国内闲鱼、GCanvas、支付宝、Weex 等都投入了不少研究,通过 Flutter 打造自己的渲染引擎,支持 APP 内业务、小程序等业务。基于 Flutter 引擎有哪些误区?有木有性能媲美 Flutter 的跨平台渲染技术?

本文将通过阐述跨平台 UI 框架的的历史、实现原理、技术优劣,并简单进行横向对比,希望能为你在如今纷乱复杂的跨平台 UI 框架选型上提供一些参考意见

点评:经常有人在即时通讯网的群里或私信我,说基于Hybrid这种方案的移动端APP里能不能对接即时通讯?该使用什么协议通信?TCP?UDP?还是WebSocket?显然,要正确地认识这些问题,对于即时通讯或相关应用的开发者说,了解当前主流的跨平台移动端UI框架技术原理等,是很有必要的,以免在新产品或项目中的技术选型上走弯路。这也是为什么我要整理与此相关的文章的原因所在。

第一类:WebView 跨平台技术

第一代跨平台技术主要以 Webview 容器,代表有 PhoneGap/Cordova 。优点:功能丰富,标准强,历史悠久,有强大的前端生态支持;是目前最成功的跨平台渲染容器。支付宝及微信更是以此为载体,打造小程序内核。第一代渲染引擎主要缺点在于性能方面及高级组件方面,流畅性始终与 Native 无法媲美。

为何会这样,我们以 Blink 为例从三个方面来看此原因。

3.1WebView 的基础架构及线程模型

盘点主流移动端跨平台UI技术:实现原理、技术优劣、横向对比等_1.png
▲ Blink基础架构示意图

Android 平台 WebView 采用多进程架构,主要分为:

  • 1)Browser 进程;
  • 2)Render 进程;
  • 3)GPU 进程。

Browser 进程负责用户输入, Touch 事件处理、平台相关的对接等功能。 Render 进程 Main Thread 负责 JS 的执行, CSS 解析, Layout Paint ,输出 DisplayList 供 CC 使用。 Work Threads 进行图片的编解码。 Compositor Threads 负责 Layer 的合成,和 Tile 分片;将分片输出成 Bitmap 或者 GL 指令,通过 IPC 输出到 GPU Process 。 GPU Process 的 GPUThread 线程负具体指令的绘制,将绘制指令渲染输出到显示器上。

3.2WebView渲染流程及线程模型

WebView 的渲染一般从载构建成 DOM Tree 开始算起。下图是 Blink 发起一个样式变更,到最终渲染到屏幕上渲染流程。图片来自于 A Pixel Life In Blink 。

盘点主流移动端跨平台UI技术:实现原理、技术优劣、横向对比等_2.png
▲ 一个像素从更新发起到显示的具体流程

下面是 WebView 渲染具体的具体执行的线程模型:
盘点主流移动端跨平台UI技术:实现原理、技术优劣、横向对比等_3.png

WebView 的 JS 执行, DOM 构建, RenderObject 的构建, Layout Paint 都在主线程执行。 Compositor Thread 负责 Layer 合成, Worker Thread 进行图片解码及 GPU 光栅化。 GPU Thread 进行最终的指令合成和渲染显示。

盘点主流移动端跨平台UI技术:实现原理、技术优劣、横向对比等_4.png

上图 Render 进程是与 GPU 进程 GPU Thread 的交互图,WebView 每一帧的更新都需 IPC 调用更新到 GPU Process ,这种 IPC 模型相对线程通信还是比较昂贵的。

3.3HTML5 作为开放的技术标准,历史悠久,包袱多

HTML5 标准在 Android/iOS 引擎实现不统一, Android 平台 Chrome(blink) , iOS 平台 WKWebview(Webkit) 。

标准的实现难度非常高:

  • 1)每个引擎代码行数都在 500-1000 万行;
  • 2)庞大的代码规模导致入门和改动成本比较高,引擎定制成本非常复杂。

目前从国内来看, UC /阿里云有能力做内核级别的高级定制开发,其它团队难以进行大规模内核级别的高级定制。无线端 Native 平台成熟的 List Scroller Cell 等高性能组件,无法在 WebView 内核级别做有效的支持。以小程序内嵌 NativeView 所需的同层渲染技术为例,在两个平台要做不同的技术实现。 HTML 规范从提出到落地时间非常长,一般 3-5 年后才能普及,业务难以等待。

3.4WebView 渲染引擎设计的上的缺陷

 

  • 1)JS Execute,Layout, Paint 都在MainThread ,无法并行化。
  • 2)JS 的性能赶不上 Native Tookit 的 Java Dart Object-C 等编译型语言,执行复杂逻辑时会卡顿。
  • 3)渲染流水线非常长,导致浏览器对合成器动画和非合成器动画区分对待,非合成器动画性能不佳。
  • 4)OpenGL 设计上是推荐单线程模型,一个 Context 同时只能运行一个线程使用。 GPU Thread 运行在单独 GPU 进程, Render 进程无法访问 GPU 进程的 OpenGL Context ,两个进程无法 Texture 共享资源。 Render 进程只能输出 Bitmap/Command Buffer 通过 IPC 传递给 GPU 进程,无法直接在 GPU 进程的 Open GL Context 做直接光栅化,难以充分发挥现代 GPU 的性能。
  • 5)光栅化是异步进行的,进行惯性滚动时,会出现白屏,这个是 Webview 始终无法避免的问题。
  • 6)设备平台众多,需要兼容CPU渲染,无法进行 All In GPU 的设计。

 

4、第二类:Weex/React-Native 跨平台技术

第二类跨平台框架主要以 Weex/React-Native/ 鸟巢等为代表,这种技术最大化的复用前端的生态和 Native 的生态体系,把 Native View 的高性能组件积累输出给前端的技术体系。此方案和浏览器的最大区别在于 Script 的执行和 Native View 渲染体系。

4.1Weex 的基础架构

盘点主流移动端跨平台UI技术:实现原理、技术优劣、横向对比等_5.png

Weex 对外通过 Rax 和 Vue 前端框架进行功能输出,前端框架下有一层 JS Framework 来实现 dom 的功能。 WeexCore 负责基础的 Flex Layout ,然后通过 Component 分别对接到 Android/iOS 的 Platform Native View 体系。

4.2Weex 基础架构 JS 执行上相对 WebView 的优势

盘点主流移动端跨平台UI技术:实现原理、技术优劣、横向对比等_6.png
▲ Weex 和 WebView 在 JS Execute Layout Paint 线程模型区别

Weex 体系中, JS 的执行在 JS Thread,Layout 执行在独立的 Layout Thread ,渲染执行在系统的 MainThread ,三个线程相互独立,并行执行。在 WebView 的体系中 JS 的执行、 Layout 、 Paint 都在 MainThread ,相互影响,在进行复杂任务时会导致界面卡顿。

4.3Weex 体系渲染流水线及 OpenGL 设计上和 WebView 区别

Android Native 线程模型和 WebView 线程模型对比如下图:
盘点主流移动端跨平台UI技术:实现原理、技术优劣、横向对比等_7.png
盘点主流移动端跨平台UI技术:实现原理、技术优劣、横向对比等_8.png

两图对比可以看出:

  • 1)Android Native 采用更轻量级的渲染流水线,能更快更高效的的响应事件;
  • 2)RenderThread 直接操作 OpenGLContext ,进行 Direct GPU Raster ,充分发挥现代 GPU 的特性,提供高性能渲染和流畅的体验;
  • 3)部分耗时操作,如 Bitmap 上传 Texture , TextureThread 上传到 Share Open GL Context 中, Texture 完成后通知主线程进行绘制,通过 Share Open GL Context 与主线程共享 Texture 等资源。 WebView 只能在 Render Process 内部进行 Texture 的共享, RenderProcess 无法与 GPU Process 共享 Texture 等资源;
  • 4)Android Native 有 RecycleView ViewPager 等高级组件,每个高级组件都做了性能的最佳实践;浏览器上的高级组件只能通过 JS 模拟实现,优化定制效率低;
  • 5)浏览器流水线设计复杂,需要考虑到 PC 、手机、嵌入式设备等多种复杂的环境,不少设备上木有 GPU ,只能进行 CPU 渲染。无法像 Android Native 体系一样进行 All In GPU 的体系设计,全面发挥现代 GPU 的性能。

 

4.4Weex 体系在跨平台及性能上的不足

Weex 体系充分将 Native 的 View 体系输出到前端体系中,在进行 Android/iOS Native View 的封装过程中,存在不少难以逾越的障碍。

如:难以磨平的双端一致性问题、复杂样式能力难以实现、  Layout 动画需要执行两次(WeexCore Layout 和 Android Native 本身的 Layout )。组件的封装成本随着复杂度增加也越来越高,难以逾越 Native View 限制提供更细致的 W3C 标准能力。

5、第三类:Flutter 跨平台技术

2018 年 Flutter 横空出世,通过 Dart 语言构建一套跨平台的开发组件,所有组件基于 Skia 引擎自绘,在性能上和 Native 平台的 View 相媲美。引起大家广泛关注,充分验证了通过绘制构建组件做到 Native View 媲美的 UI 渲染引擎的可行性。

5.1Flutter 的基础架构

盘点主流移动端跨平台UI技术:实现原理、技术优劣、横向对比等_9.png
▲ Flutter基础架构

Flutter 基础架构主要分为三个部分:

  • 1)Framework 层:包含 Animation Painting Gestures RenderIng Widgets 等模块;提供基础的 UI 组件;
  • 2)Engine 层包括: Dart VM Manager , Frame Pipeline Rendering ,  TextLayout 等模块,主要负责 Skia 的渲染调度以及 Layer Tree 等合成;
  • 3)Embedber 层分别对接 Android/iOS 平台层,进行事件对接, Surface 对接,以及 Native 平台接口调用的插件机制。

 

5.2Flutter 的渲染流水线和 Android Native 对比

a. Flutter 的渲染流水线:

盘点主流移动端跨平台UI技术:实现原理、技术优劣、横向对比等_10.png
▲ Flutter 渲染流水线

Embedber 层收到 VSync 信号,把此信号传递给 Dart VM 中运行 Flutter Framework 。 Dart UI FrameWork 首先处理 Animation 差值,然后更新 Widget Tree ,接着更新 Element Tree ,最后更新 RenderObject Tree ,发起 Paint 流程。再由 SceneBuilder 输出 Layer Tree ,提交到 GPU 线程进行这一帧的阻塞式合成,合成完成后开始下一帧。

b. Android Native 渲染流水线:

盘点主流移动端跨平台UI技术:实现原理、技术优劣、横向对比等_11.jpg
▲ Android Native 渲染流水线

Android 系统 Native View Framework 收到 VSync 信号后,首先进行 Touch、Input 等事件处理,再进行 Animation 的更新处理,之后 View Tree 发起 Measure和 Layout 完成布局过程。通过 Draw 把本次更新的脏节点更新的 DispayList 绘制指令同步到 RenderThread 。 RenderThread 通过 DisplayList 对 RenderNode 更新合成,把指令转换成 OpenGL 绘制指令输出到 GPU , 整个流程和Flutter基本相同。

5.3Flutter 和 Android 在渲染方面相似点和不同点

a)Flutter 和Android 共同点:

  • 1)采用精简的渲染流水线,从事件到 GPU 更新整体渲染流程很相似;
  • 2)在 GPU 层面进行直接光栅化,充分利用现代 GPU 的高性能渲染性能;
  • 3)都采用 OpenGL Share Context 进行设计,异步进行图片 Texture 上传,共享图片等 Texture 资源;
  • 4)最新版本 Android Native 和 Flutter 底层共同采用 Skia 引擎进行合成绘制。

b)Flutter 和 Android 不同点:

  • 1)Android Native 采用 Java 构建 UIFramework , Flutter 采用 Dart ;
  • 2)Android Native 支持局部更新,在 Open GL 层面做了非常多的深层次的优化, Flutter 这块工作目前不足;
  • 3)Android HW UI 是系统应用,可根据手机机型及 GPU 进行参数调优,深度定制;这是 Flutter 框架做不到的;
  • 4)目前 Android 生态 UI 库比较全面,模块之间融合成本低。 Flutter 自成体系,和 Native View 融合上存在一定成本。

 

5.4Flutter 相对 Weex Native 的优势与不足

Flutter 引擎基于 Skia 构建跨平台组件,解决了 Weex 难以解决的双端一致性等问题。

但是:

  • 1)上层采用 Dart 语言,没有利用到前端最强大的 JavaScript 生态;
  • 2)和 NativeView 的融合上也存在一些问题,难以复用 Native 多年来积累的强大组件。

这些是它相对于 Weex 的不足。

在性能方面, Flutter 和 Weex 解决方案,本质上基本相同,实际页面性能取决于最佳实践,目前实际情况看 Weex 的 NativeView 性能优势更强一些。

5.5在 Flutter 渲染引擎上的探索与实践

Weex 团队、GCanvas 团队、UC 团队、支付宝团队都在研究 Flutter Engine 。

目前主要由 C++ 流和 JavaScript 流两种做法。这两种做法的共同点核心仍采用 Flutter Engine 的渲染流水线,去除 Dart VM ,引入 JavaScript 生态,把 Flutter 标准转换成 W3C 标准对外输出。

下面简单介绍一下这两种做法:
盘点主流移动端跨平台UI技术:实现原理、技术优劣、横向对比等_12.jpg
▲ Flutter体系向前端输出尝试探索

方案一:通过把 Flutter Widget 整个体系采用 TypeScript 重写,来实现 Flutter 的 JavaScript 的化,上层再基于 JavaScript 的 Widget 封装框架。

方案二:通过把 Flutter的 Framework 采用 C++ 重写,在 Widget 上层封装一层 Component 层,完成 Widget 到 W3C 标准层的转换,然后通过 JavaScript Binding 把 HTML 标准讲功能对外输出。

两种方案都难以把 Flutter 整个体系迁移过来,只能挑选核心的组件进行重写,都是非常不错的尝试。

5.6Flutter 引擎走 HTML 子集输出的缺陷

Widget 标准对于前端不友好,因此不少团队开始尝试把 Widget 体系转换成前端标准子集进行功能输出。在完善的 Flutter Widget 的前提下,Flutter Widget 通过 Component 封装转换成前端 HTML5 标准进行输出。

此方式相对 Weex 封装 Android/iOS 平台 Native View 做法,具有解决 Weex 面临的双端一致性的问题优势。

但Weex 从 Native View 到 W3C 的标准转换很难去完美适配,Flutter 的 Widget 实际到 HTML5 标准转换过程中一样会存在。在深层次标准适配时,会出现难以解决的样式和布局能力扩展的问题。由于引擎本身绘制能力可扩展性,这些方面的缺陷相对 Weex 会弱一些。

整体来看:

  • 1)Widget 的标准转换到 HTML5 标准只能做部分实现,难以完美适配;
  • 2)进行复杂样式组合时会碰到和标准不一致的现象,难以像下一代定制内核的UI渲染引擎一样高效。

 

6、横向对比以上三类跨平台技术

上面整体介绍了三类主流的跨平台渲染引擎,下面从特点和技术方面来总结上面的跨平台渲染引擎。

6.1跨平台渲染引擎的特点上对比

盘点主流移动端跨平台UI技术:实现原理、技术优劣、横向对比等_13.jpg

备注: WebView性能目前随着手机性能的提升而逐步提升,在某些高端机上简单页面的性能已经非常流畅,但在复杂页面尤其是有交互的页面和Weex还是有一定的性能差距。

6.2跨平台渲染引擎的技术上进行对比

盘点主流移动端跨平台UI技术:实现原理、技术优劣、横向对比等_14.jpg

此表格概括了目前主流的三代跨平台渲染引擎的技术特点。

7、最后总结

目前各种渲染引擎并不是一成不变的,都在蓬勃发展。如 Blink 的 Slimming Paint 项目采用和 Native View 相同的策略, Render Layer 只输出 Display List ,由 CC 根据策略是采用 Layer Compositor 还是 Direct GPU Raster 思路? Firefox 的 WebRender 渲染引擎,尝试把 JS 的执行, Layout、Paint 的执行并行化,并采用更高级的 GPU 绘制元素的方式。

 

全面了解移动端DNS域名劫持等杂症:技术原理、问题根源、解决方案等
美图App的移动端DNS优化实践:HTTPS请求耗时减小近半
金蝶随手记团队分享:还在用JSON? Protobuf让数据传输更省更快(原理篇)
金蝶随手记团队分享:还在用JSON? Protobuf让数据传输更省更快(实战篇)
腾讯技术分享:社交网络图片的带宽压缩技术演进之路
通俗易懂:基于集群的移动端IM接入层负载均衡方案分享
QQ音乐团队分享:Android中的图片压缩技术详解(上篇)
QQ音乐团队分享:Android中的图片压缩技术详解(下篇)
腾讯原创分享(一):如何大幅提升移动网络下手机QQ的图片传输速度和成功率
腾讯原创分享(二):如何大幅压缩移动网络下APP的流量消耗(上篇)
腾讯原创分享(三):如何大幅压缩移动网络下APP的流量消耗(下篇)
基于社交网络的Yelp是如何实现海量用户图片的无损压缩的?
腾讯技术分享:腾讯是如何大幅降低带宽和网络流量的(图片压缩篇)
腾讯技术分享:腾讯是如何大幅降低带宽和网络流量的(音视频技术篇)
最火移动端跨平台方案盘点:React Native、weex、Flutter
盘点主流移动端跨平台UI技术:实现原理、技术优劣、横向对比等
iPhone X 的 UI界面适配官方指南!》
《[url=http://www.52im.net/thread-1843-1-1.html]新浪微博技术分享:微博短视频服务的优化实践之路

全面掌握移动端主流图片格式的特点、性能、调优等
迈向高阶:优秀Android程序员必知必会的网络基础
HTTPS时代已来,打算更新你的HTTP服务了吗?
移动端APP的日志上报机制的优化实践
移动端网络优化之HTTP请求的DNS优化
伪即时通讯:分享滴滴出行iOS客户端的演进过程
Android版微信从300KB到30MB的技术演进(PPT讲稿) [附件下载]
微信团队原创分享:Android版微信从300KB到30MB的技术演进
Android程序员的痛你永远不懂(一):Bitmap到底占用多大内存?
Android程序员的痛你永远不懂(二):如何减少Bitmap内存占用?
Android反编译利器APKDB:没有美工的日子里继续坚强的撸
微信团队原创分享:Android内存泄漏监控和优化技巧总结
全面总结iOS版微信升级iOS9遇到的各种“坑”
微信团队原创资源混淆工具:让你的APK立减1M
微信团队原创Android资源混淆工具:AndResGuard [有源码]
Android版微信安装包“减肥”实战记录
iOS版微信安装包“减肥”实战记录
移动端IM实践:iOS版微信界面卡顿监测方案
iOS端移动网络调优的8条建议
微信“红包照片”背后的技术难题
移动端IM实践:iOS版微信小视频功能技术方案实录
移动端IM实践:Android版微信如何大幅提升交互性能(一)
移动端IM实践:Android版微信如何大幅提升交互性能(二)
移动端IM实践:iOS版微信的多设备字体适配方案探讨
爱奇艺技术分享:爱奇艺Android客户端启动速度优化实践总结

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/314276.html

(0)
上一篇 2024年7月24日 17:11
下一篇 2024年7月24日 17:17

相关推荐

发表回复

登录后才能评论