Web 时代的方案,主要采用的是原生应用内嵌浏览器控件 WebView的方式进行 HTML5 页面渲染,并定义 HTML5 与原生代码交互协议,将部分原生系统能力暴露给 HTML5,从而扩展 HTML5 的边界。这类交互协议,就是我们通常说的 JS Bridge。
这种开发模式既有原生应用代码又有 Web 应用代码,因此又被称为 Hybrid 开发模式。由于 HTML5 代码只需要开发一次,就能同时在多个系统运行,因此大大降低了开发成本。由于采用了 Web 开发技术,社区和资源非常丰富,开发效率也很高。但一个完整 HTML5 页面的展示要经历浏览器控件的加载、解析和渲染三大过程,性能消耗要比原生开发增加 N 个数量级。
泛 Web 容器时代
虽然 Web 容器方案具有生态繁荣、开发体验友好、生产效率高、跨平台兼容性强等优势,但它最大的问题在于承载着大量 Web 标准的 Web 容器过于笨重,以至于性能和体验都达不到与原生同样的水准,在复杂交互和动画上较难实现出优良的用户体验。而在实际的产品功能研发中,我们通常只会用到 Web 标准中很小的一部分。面对这样的现实,我们很快就想到:能否对笨重的 Web 容器进行功能裁剪,在仅保留必要的 Web 标准和渲染能力的基础上,使得友好的开发体验与稳定的渲染性能保持一个平衡?
答案当然是可以。
泛 Web 容器时代的解决方案优化了 Web 容器时代的加载、解析和渲染这三大过程,把影响它们独立运行的 Web 标准进行了裁剪,以相对简单的方式支持了构建移动端页面必要的 Web 标准(如 Flexbox 等),也保证了便捷的前端开发体验;同时,这个时代的解决方案基本上完全放弃了浏览器控件渲染,而是采用原生自带的 UI 组件实现代替了核心的渲染引擎,仅保持必要的基本控件渲染能力,从而使得渲染过程更加简化,也保证了良好的渲染性能。
也就是说,在泛 Web 容器时代,我们仍然采用前端友好的 JavaScript 进行开发,整体加载、渲染机制大大简化,并且由原生接管绘制,即将原生系统作为渲染的后端,为依托于 JavaScript 虚拟机的 JavaScript 代码提供所需要的 UI 控件的实体。这,也是现在绝大部分跨平台框架的思路,而 React Native 和 Weex 就是其中的佼佼者。
自绘引擎时代—Flutter
泛 Web 容器时代使用原生控件承载界面渲染,固然解决了不少性能问题,但同时也带来了新的问题。抛开框架本身需要处理大量平台相关的逻辑外,随着系统版本变化和 API 的变化,我们还需要处理不同平台的原生控件渲染能力差异,修复各类奇奇怪怪的 Bug。始终需要 Follow Native 的思维方式,就使得泛 Web 容器框架的跨平台特性被大打折扣。
而这一时期的代表 Flutter 则开辟了一种全新的思路,即从头到尾重写一套跨平台的 UI 框架,包括渲染逻辑,甚至是开发语言。