Hummingbird 蜂鸟 - Flutter的Web端运行引擎浮出水面

flutter

#1

在2018年12月4日举行的Flutter Live 2018发布会上,Flutter/Dart首席产品经理Tim Sneath演示了新项目 Hummingbird,即Flutter的Web运行引擎。因为尚处于实验阶段,本次演示没有展示代码,但Flutter项目组组员Yegor Jbanov发表了文章对Hummingbird进行了技术讲解,现尝试对该文要点进行归纳总结。


设计/原型

Flutter使用多层架构,最底层是C++编写的引擎,之上是用Dart编写的多层框架。引擎通过dart:ui库暴露给上层框架,dart:ui只负责图片(Picture)绘制,其他工作都由上层框架完成。大部分引擎代码使用C++编写,与特定平台相关的如插件系统等,使用平台对应的语言编写:iOS使用Objective-C,Android使用Java。

Flutter移动端架构:


要使Flutter运行于Web之上,需要解决三个主要问题:1. 编译Dart为JavaScript 2. 选择可运行于Web之上的功能,剔除与特定平台相关的模块 3. 选择合适的Web特性来实现Flutter的功能。为此,Flutter项目组实现了三种原型:纯组件层(widgets)、组件加自定义布局(Widgets + custom layout),以及构建全新的底层Web引擎。诸多尝试后,Flutter项目组发现只有第三种方式才能够保证真正跨平台,即为Flutter实现一个全新的Web引擎。

Flutter Web Engine架构:

实现

Web引擎的实现大致需要三个步骤:构建组件、排版以及绘制。

组件的构建过程相对简单直接,将组件载入内存,监控它们的状态变化,并把需要更新的数据输送到排版、绘制阶段即可。得益于Dart最新的super-mixin特性,所有Flutter组件和组件框架都几乎能被完美编译为JavaScript。

排版阶段相对复杂,最大的挑战来自文字排版。Flutter使用段落(Paragraph)的 layout 方法完成文字排版,但Web端却没有相应的文字排版API。此问题的解决方法:将文本插入到html dom中,先让浏览器完成排版,然后再读取回文本的高度、宽度等各种属性。

最后的也是最复杂的绘制阶段。Web端可用的特性有HTML/CSS、Canvas、SVG和WebGL等,其中WebGL过于底层和复杂,而纯HTML/CSS的实现又要求改动Flutter现有的API。项目组还在积极研究此阶段的最优方案,目前的候选方案有两种:HTML+CSS+Canvas 和 CSS Paint API。下面简要概括这两种方案的原理:

  • HTML+CSS+Canvas - Flutter上层框架会生成大量层(Layer),其中简单的图片层使用HTML+CSS绘制,且称之为DomCanvas实现;复杂的图片层则使用2D Canvas绘制,并称之为BitmapCanvas实现(浏览器底层使用Bitmap实现canvas)。除图片(Picture)外的其他层,会被转换为自定义html标签表示,比如:Opacity 会被转换为 <flt-opacity>。这样,Flutter页面就被转换为由html标签、DomCanvas以及BitmapCanvas组成的树状结构。这种实现方式在所有现代浏览器都可以正常工作,是目前首选的方案。

    转换前:

    转换后:

  • CSS Paint API - CSS Paint 是众多浏览器厂商合作设计的Web端新API,它的主要特性是使普通的Html元素具备绘图能力,它底层不使用Bitmap,效率高而且不阻塞JavaScript线程。借助此API,可以直接使用<p>和<span>并配合自定义CSS属性完成绘制。CSS Paint API还比较新,不是所有浏览器都支持,但它应该是未来Flutter Web的完美实现方案之一。

其他

  • Flutter Web应用可以调用所有已有的Dart Web库,而且支持使用dart:js和package:js与JavaScript交互。

  • 出于性能以及可移植性考虑,Flutter Web应用目前不支持直接使用CSS,即跟原生Flutter一样,全部使用组件代码来实现样式。

  • Flutter Web应用暂不支持嵌入到其他Web应用中,但可能会使用iframe或Shadow Dom方式实现。

  • 其他Web组件如:html自定义标签、React组件、Angular组件等,都还不能嵌入Flutter Web应用中。主要问题是这些组件会引入CSS,可能带来不可预知的影响,项目组还在研究应对方案。

  • Flutter Web版将保证最大的可移植性,但并不意味所有Flutter应用都不用修改就能运行于Web之上,比如:使用了ARCore等Web端不具备的功能的应用。

目前,Hummingbird已经可以渲染Flutter Gallery(Flutter的官方demo)的大部分页面,包括所有Material组件和主题。Hummingbird的项目代码暂不公开,但最终会开源并迁移到Github,更多消息将会在2019年的Google I/O大会放出,敬请期待。


文章链接:


Dart是否可以做到Web端和移动端的代码复用?
Dart 移动开发框架 Flutter 正式公布1.0版本