前言
2018 年最热跨平台技术 Flutter 凌空出世,通过自绘 UI 组件,构建高质量跨平台组件库,解决了此类框架难以解决的双端一致性, Bridge 通信效率等问题。并提供丰富的 Widget 组件,渲染性与 Native UI 相媲美,掀起了大家对下一代跨平台技术探索的热情。同时对国内闲鱼、GCanvas、支付宝、Weex 等都投入了不少研究,通过 Flutter 打造自己的渲染引擎,支持 APP 内业务、小程序等业务。下一代跨平台技术非 Flutter 莫属吗?基于 Flutter 引擎有哪些误区?有木有性能媲美 Flutter 的跨平台渲染技术?本文通过阐述跨平台 UI 渲染引擎的历史,并且实际研究探索构建下一代跨平台 UI 渲染引擎。
1、第一类 WebView 跨平台技术
第一代跨平台技术主要以 Webview 容器,代表有 PhoneGap/Cordova 。优点:功能丰富,标准强,历史悠久,有强大的前端生态支持;是目前最成功的跨平台渲染容器。支付宝及微信更是以此为载体,打造小程序内核。第一代渲染引擎主要缺点在于性能方面及高级组件方面,流畅性始终与 Native 无法媲美。
为何会这样,我们以 Blink 为例从三个方面来看此原因。
1.1 WebView 的基础架构及线程模型
Android 平台 WebView 采用多进程架构,主要分为 Browser 进程, Render 进程和 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 线程负具体指令的绘制,将绘制指令渲染输出到显示器上。
1.2 WebView渲染流程及线程模型
WebView 的渲染一般从载构建成 DOM Tree 开始算起。下图是 Blink 发起一个样式变更,到最终渲染到屏幕上渲染流程。图片来自于 A Pixel Life In Blink 。
下面是 WebView 渲染具体的具体执行的线程模型:
WebView 的 JS 执行, DOM 构建, RenderObject 的构建, Layout Paint 都在主线程执行。 Compositor Thread 负责 Layer 合成, Worker Thread 进行图片解码及 GPU 光栅化。 GPU Thread 进行最终的指令合成和渲染显示。
上图 Render 进程是与 GPU 进程 GPU Thread 的交互图,WebView 每一帧的更新都需 IPC 调用更新到 GPU Process ,这种 IPC 模型相对线程通信还是比较昂贵的。
1.3 HTML5 作为开放的技术标准,历史悠久,包袱多
HTML5 标准在 Android/iOS 引擎实现不统一, Android 平台 Chrome(blink) , iOS 平台 WKWebview(Webkit) 。标准的实现难度非常高,每个引擎代码行数都在 500-1000 万行;庞大的代码规模导致入门和改动成本比较高,引擎定制成本非常复杂。目前从国内来看, UC /阿里云有能力做内核级别的高级定制开发,其它团队难以进行大规模内核级别的高级定制。无线端 Native 平台成熟的 List Scroller Cell 等高性能组件,无法在 WebView 内核级别做有效的支持。以小程序内嵌 NativeView 所需的同层渲染技术为例,在两个平台要做不同的技术实现。 HTML 规范从提出到落地时间非常长,一般 3-5 年后才能普及,业务难以等待。
1.4 WebView