Flutter是什么?
Flutter是Google一个新的用于构建跨平台的手机App的SDK。写一份代码,在Android 和iOS平台上都可以运行。Flutter移动应用程序SDK是为开发人员提供一种创建快捷、美观的应用程序的新方式,从而摆脱过去那种千篇一律的app,尝试过Flutter的人都会真的爱上它;例如,这位开发者,这位,或者这位,或者由第三方编辑的一系列文章和视频。
跟React Native、Weex等有什么不同?
和React Native一样,Flutter也提供响应式的视图,Flutter采用不同的方法避免由JavaScript桥接器引起的性能问题,即用名为Dart的程序语言来编译。Dart是用预编译的方式编译多个平台的原生代码,这允许Flutter直接与平台通信,而不需要通过执行上下文切换的JavaScript桥接器。编译为原生代码也可以加快应用程序的启动时间。
React Native、Weex等一直存在一个问题,就是性能跟原生App存在很大的差异。这跟它们的原理有很大的关系,下面从原生App,RN、Weex,Flutter的简单原理说一下它们的不同。
-
原生App
苹果2008年发布iOS,Google 2009年发布Android,它们的SDK是基于两种不同的编程语言Objective-C 和 Jave.现在又有了Swift和Kotlin。

最早的跨平台方案是基于JaveScript 和 WebView的,像PhoneGap、Cordova、Ionic等。

RN不仅桥接系统服务,也将系统UI也桥接到了JaveScript中,这样写出来的UI最终也会渲染成原生的控件。

Flutter
Flutter使用Dart语言开发,Dart可以被编译(AOT)成不同平台的本地代码,让Flutter可以直接和平台通讯而不需要一个中间的桥接过程,从而提高了性能。

和React Native一样,Flutter也提供响应式的视图,Flutter采用不同的方法避免由JavaScript桥接器引起的性能问题,即用名为Dart的程序语言来编译。Dart是用预编译的方式编译多个平台的原生代码,这允许Flutter直接与平台通信,而不需要通过执行上下文切换的JavaScript桥接器。编译为原生代码也可以加快应用程序的启动时间。
实际上,Flutter是唯一提供响应式视图而不需要JavaScript桥接器的移动SDK,这就足以让Fluttter变得有趣而值得一试,但Flutter还有一些革命性的东西,即它是如何实现UI组件的?
Flutter将UI组件和渲染器从平台移动到应用程序中,这使得它们可以自定义和可扩展。Flutter唯一要求系统提供的是canvas,以便定制的UI组件可以出现在设备的屏幕上,以及访问事件(触摸,定时器等)和服务(位置、相机等)。
Dart程序(绿色)和执行数据编码和解码的原生平台代码(蓝色,适用于iOS或Android)之间仍然有一个接口,但这能比JavaScript桥接器快几个数量级。
将UI组件和渲染器移动到应用程序中确实会影响应用程序的大小。Android上的Flutter应用程序的的初始大小约为6.7M,这与类似的工具构建的最小应用程序的大小相似,您可以决定Flutter的优势是否值得权衡,因此本文的余下部分将讨论这些优势。
布局
Flutter最大的改进之一就是它的布局,布局是基于一组规则(也称约束)来决定UI组件的大小和位置。
传统上,布局使用大量可以应用于任何UI组件的规则。这些规则实现多种布局方法,我们就以众所周知的CSS布局为例(尽管Android和iOS中的布局基本相似)。CSS具有适用于HTML元素(UI组件)的属性(规则), CSS3定义了375个属性。
CSS包含大量的布局模型,如多种箱模型、浮动元素、表、多列文本、分页媒介等。还有像flexbox 和 grid的布局模型在之后也被添加进去,因为开发人员和设计人员需要对布局进行更多地控制,而不得不使用表格和透明图像来获取他们想要的布局。在传统布局中,开发人员无法添加新的布局模型,因此必须将flexbox 和 grid添加到CSS中并在所有浏览器上实现。
传统布局的另一个问题是规则可以相互影响甚至发生冲突,通常有几十种规则元素的规则应用于他们,这使得布局变慢。更糟糕的是,布局性能通常为指数性下降,因此,随着元件数量的增加,布局变慢得更快。
Flutter最开始是Google Chrome浏览器小组成员进行的实验项目,我们想看看如果我们忽略了传统的布局模式,是否可以构建更快的渲染器。几周后,我们在性能上取得了显著增长,我们发现:
- 大多数的布局是相对简单的,例如:滚动页面上的文本,其大小和位置只取决于显示大小的固定矩形,还有一些表格,浮动元素等。
- 大部分布局只作用于UI组件树的一部分,并且这子树通常使用一个布局模型,因此这些UI组件只需要少量的规则。
我们意识到如果完全改变以前的布局模式,布局就可以大大被简化:
- 每个UI组件都将指定自己简单的布局模型,而不是拥有可以应用于任何UI组件的一整套布局规则。
- 因为每个UI组件都有一个更小的一套布局需要考虑,所以布局可以大量优化。
- 为了进一步简化布局,我们几乎将所有内容都转换为UI组件。
定制设计
因为UI组件现在是应用程序的一部分,你可以添加新的UI组件,并且可以自定义现有的UI组件,以使其具有不同的外观或感觉,或匹配公司的品牌,移动设计的趋势正在与几年前普遍使用的千篇一律的应用程序背离,开始走向让用户愉悦的定制设计。
更多关于响应式视图
现有的响应式web视图库都引入了虚拟DOM,DOM代表HTML的文档对象模型。JavaScript用DOM提供的API来操纵表现为一个元素树的HTML文档。虚拟DOM是使用编程语言中的对象(在这种情况下为JavaScript)创建的DOM的抽象版本。
Dart编程语言
因为Flutter 像使用响应式视图的其他系统一样,刷新每个新框架的视图树,它会创建许多只能在一帧(六十分之一秒)内存在的对象。幸运的是,Dart使用“generational garbage collection ”对于这样的系统来说是非常有效的,因为对象(特别是寿命短的)消耗资源相对较少。此外,可以使用单个pointer bump来完成对象的分配。这是一个快速且不需要锁定的pointer bump。这有助于避免UI 卡顿。
热重载
Flutter最受欢迎的功能之一是其快速,保留程序状态的热重载 (hot reload)。 您可以在Flutter应用程序运行时对其进行更改,重新加载应用程序的代码,将其从之前的操作位置继续下去。一次热重载通常用不到一秒钟。 如果您的应用遇到错误,您通常可以修复错误,然后继续,就像错误从未发生过。 即使你必须完全重新加载,它也是很快速的。
兼容性
因为UI组件(和这些UI组件的渲染器)是您的应用程序的一部分,而不是平台的一部分,不需要“兼容库 ”。 您的应用程序不仅可以正常工作,而且在最近的操作系统版本Jelly Bean以后的安卓系统和 8.0以后的iOS系统上也是一样的 。 这显著降低了在旧版本操作系统上测试应用程序的需求。 此外,你的App有很大可能与未来的操作系统版本兼容
我们曾被问到一个潜在的问题。由于Flutter不使用原生UI组件,因此,当新的iOS或Android版本出现时,Flutter UI组件是否需要更新才能支持新的部件,或更改现有部件的外观或行为吗?
-
首先,Google是Flutter的内部的一个大用户,所以我们有很大的动机来更新UI组件,使其保持最新状态并尽可能接近当前的原生UI组件。
-
如果有一段时间我们在更新一个UI组件时太慢,Google并不是Flutter唯一一个保持UI组件最新的用户。Flutter的UI组件是可扩展和可定制的,任何人都可以更新它们,包括你自己, 甚至不需要提交一个请求。 你永远不必等待Flutter自己更新。
-
只有当您想要在应用中反映出新的更改时,上述要点才适用。 如果您不想要更改影响您的应用程序的外观或工作方式,那么就没有必要使用上面所说的。 UI组件是您的应用程序的一部分,所以UI永远不会在你不知情的情况下擅自改变,并使您的应用程序看起来不好(或更糟的是,破坏您的应用程序)。
-
还有一个额外的好处,您可以编写您的应用程序,以便即使在较旧的操作系统版本上也能使用新的UI组件.