移动端跨平台方案的简单介绍
跨平台方案有哪些
跨平台技术开发的出现,都是为了一个目标:增加业务代码的复用率,减少因为要适配多个平台带来的工作量,从而降低开发成本。这些年来出现了很多跨平台开发方案,大致可以分为,web 跨平台方案、泛web跨平台方案、自绘制引擎方案。
web 跨平台方案
基于 Web 相关技术通过浏览器组件来实现界面及功能,典型的框架包括 Cordova(PhoneGap)、Ionic 和微信小程序。这也许是最早的跨平台方案,也是最成功的跨平台方案,到现在还一直是用。
采用的是原生应用内嵌浏览器控件 WebView(iOS 为 UIWebView 或 WKWebView,Android 为 WebView)的方式进行 HTML5 页面渲染,并定义 HTML5 与原生代码交互协议,将部分原生系统能力暴露给 HTML5,从而扩展 HTML5 的边界。这类交互协议,就是我们通常说的 JS Bridge(桥)。 这样既有HTML5 又有原生代码,也称为 Hybrid 开发模式。
web 跨平台方案,可以很大程度上保证了页面UI的统一,但是在渲染上比较复杂的页面时,从肉眼可以感觉有些卡顿,这是因为HTML5 页面的展示要经历浏览器控件的加载、解析和渲染三大过程,性能消耗要比原生开发增加 N 个数量级。
泛 web 跨平台方案
采用类 Web 标准进行开发,在运行时把绘制和渲染交由原生系统处理,代表框架有 React Native、Weex 和快应用,广义的还包括天猫的 Virtual View 等。
在 web 方案的基础上,对加载、解析和渲染这三大过程进行优化,就是 泛web 跨平台方案。把影响它们独立运行的 Web 标准进行了裁剪,以相对简单的方式支持了构建移动端页面必要的 Web 标准(如 Flexbox 等),也保证了便捷的前端开发体验;同时,这个解决方案基本上完全放弃了浏览器控件渲染,而是采用原生自带的 UI 组件实现代替了核心的渲染引擎,仅保持必要的基本控件渲染能力,从而使得渲染过程更加简化,也保证了良好的渲染性能。
前端还是使用JavaScript开发,把加载、渲染机制大大简化,然后交给原生处理,使用原生控件显示出来。React Native 和 Weex就是其中的代表。
自绘制引擎方案
自带渲染引擎,客户端仅提供一块画布即可获得从业务逻辑到功能呈现的多端高度一致的渲染体验。Flutter就是其中的代表。
在泛web跨平台方案上,对加载、渲染进行了优化,对性能有和很大的提升;但是由于随着系统版本变化和 API 的变化,我们还需要处理不同平台的原生控件渲染能力差异,修复各类奇奇怪怪的 Bug。然后 自绘制引擎 方案就横空出世了。
flutter 从头到尾写了一套跨平台的UI框架,包括逻辑渲染和开发语言。使用 靠跨平台的 Skia 图形库来实现Skia 完成渲染,使用同时支持 JIT(Just-in-Time,即时编译)和 AOT(Ahead-of-Time,预编译)的 Dart
flutter运行机制和原理
运行机制
在计算机系统中,图像的显示需要 CPU、GPU 和显示器一起配合完成:CPU 负责图像数据计算,GPU 负责图像数据渲染,而显示器则负责最终图像显示。
CPU 把计算好的、需要显示的内容交给 GPU,由 GPU 完成渲染后放入帧缓冲区,随后视频控制器根据垂直同步信号(VSync)以每秒 60 次的速度,从帧缓冲区读取帧数据交由显示器完成图像显示。
flutter 控件渲染机制采用的方案也是使用这种方案。
flutter 关注在两个硬件时钟的 VSync 信号之间计算并合成视图数据,然后通过 Skia 交给 GPU 渲染:UI 线程使用 Dart 来构建视图结构数据,这些数据会在 GPU 线程进行图层合成,随后交给 Skia 引擎加工成 GPU 数据,而这些数据会通过 OpenGL 最终提供给 GPU 渲染。
原理
这是flutter 官网的一张图,可以看到结构分为三层:
Framework 层则是一个用 Dart 实现的 UI SDK,包含了动画、图形绘制和手势识别等功能。为了在绘制控件等固定样式的图形时提供更直观、更方便的接口,Flutter 还基于这些基础能力,根据 Material 和 Cupertino 两种视觉设计风格封装了一套 UI 组件库。这是我们应该开发使用到的控件都在这里面可以找到。
Engine 层主要包含 Skia、Dart 和 Text,实现了 Flutter 的渲染引擎、文字排版、事件处理和 Dart 运行时等功能。Skia 和 Text 为上层接口提供了调用底层渲染和排版的能力,Dart 则为 Flutter 提供了运行时调用 Dart 和渲染引擎的能力。而 Engine 层的作用,则是将它们组合起来,从它们生成的数据中实现视图渲染。
Embedder 是操作系统适配层,实现了渲染 Surface 设置,线程设置,以及平台插件等平台相关特性的适配。从这里我们可以看到,flutter 平台相关特性并不多,这就使得从框架层面保持跨端一致性的成本相对较低。