翻译原文连接html
Flutter移动应用程序SDK是一种构建快速,美观的移动应用程序的新方式,可帮助开发人员摆脱过去常见的“cookie切割”应用程序。 试过Flutter的人真的喜欢它; 例如,看这个,这个,或者这个。 或者,这是第三方编辑的文章和视频列表。react
就像任何新的系统同样,人们想知道Flutter的不一样,或者换句话说,“Flutter有什么新鲜和使人兴奋的东西?”这是一个公平的问题,本文将从技术角度来回答它 - 而不是 只是什么是使人兴奋的,但为何。 可是,首先,有一点历史。android
移动应用程序开发是一个相对较新的领域。 第三方开发人员已经可以在不到十年的时间内开发移动应用程序,因此工具仍在不断发展并不奇怪。git
Apple iOS SDK于2008年发布,2009年发布Google Android SDK。这两个SDK分别基于不一样的语言:Objective-C和Java。github
第一个跨平台框架基于JavaScript和WebViews。 例如Titanium和一系列相关的框架:PhoneGap,Apache Cordova,Ionic等等。 在苹果发布iOS SDK以前,他们鼓励第三方开发者为iPhone构建webapps,因此用web技术构建跨平台的应用程序是一个显而易见的步骤。web
像ReactJS(和其余)这样的响应式Web框架已经变得流行,主要是由于它们经过使用从响应式编程中借用的编程模式来简化Web视图的建立。 2015年,建立了React Native将响应式视图的诸多好处带给移动应用程序。编程
这里是理解React Native性能的主要关键之一。 每一个领域自己都很是快。 当咱们从一个领域转移到另外一个时,性能瓶颈每每会发生。 为了构建高性能的React Native应用程序,咱们必须保持桥梁经过最低限度。redux
像React Native同样,Flutter也提供响应式风格的视图。 Flutter使用编译的编程语言即Dart的方法来避免JavaScript桥引发的性能问题,。 Dart被“提早编译”(AOT)编译成多个平台的本地代码。 这使得Flutter能够与平台进行通讯,而无需经过执行了上下文切换的JavaScript Bridge。 编译为本机代码也能够提升应用程序的启动时间。 Flutter是惟一提供响应式视图而不须要JavaScript Bridge的移动SDK的事实应该足以让Flutter变得有趣而且值得尝试,可是Flutter还有一些更具革命性的地方,那就是它如何实现widgets。react-native
Widgets是影响和控制应用程序的视图和界面的元素。 说Widgets是移动应用程序最重要的部分之一,这并非夸大其词。 事实上,Widgets能够成就或挫败一个应用程序。浏览器
Flutter有一个新的架构,包括外观和感受不错,快速,可定制和可扩展的Widgets。 没错,Flutter不使用OEM Widgets(或DOM WebViews),它提供了本身的Widgets。
Flutter将Widgets和渲染器从平台移动到应用程序中,从而使其能够自定义和扩展。 Flutter对平台的需求平台是一个画布,在这个画布中,Widgets能够呈如今设备屏幕上,并能够访问事件(触摸,定时器等)和服务(位置,摄像机等)。 Dart程序(绿色)和本地平台代码(iOS或Android蓝色)之间仍然存在一个接口,能够进行数据编码和解码,但这可能比JavaScript Bridge 快几个数量级。
将Widgets和渲染器移动到应用程序中会影响应用程序的大小。 Android上Flutter应用程序的最小大小约为6.7MB,与使用相似工具构建的最小应用程序相似。 由您决定是否Flutter的好处是值得的权衡,因此本文的其他部分讨论这些好处。
Flutter最大的改进之一就是它的布局。布局根据一组规则(也称为约束)来肯定widgets的大小和位置。 传统上,布局使用一堆可应用于(虚拟)任何widgets的规则。规则实现了多种布局方法。让咱们以CSS布局为例,由于它是众所周知的(尽管和Android和iOS的布局基本类似)。 CSS具备属性(规则),这些属性应用于HTML元素(widgets)。 CSS3定义了375个属性。 CSS包含许多布局模型,包括(多个)框模型,浮动元素,表格,多列文本,分页媒体等等。其余的布局模型,如flexbox和grid,后来被添加,由于开发人员和设计师须要更多的控制布局,并使用表和透明图像来得到他们想要的。在传统布局中,开发人员没法添加新的布局模型,所以必须将flexbox和网格添加到CSS并在全部浏览器上实施。 传统布局的另外一个问题是规则能够相互影响(甚至相互冲突),而且元素一般应用了许多规则。这使布局变慢。更糟的是,布局表现一般是N阶有序的,因此随着元素数量的增长,布局变得更加缓慢。 Flutter是由Google的Chrome浏览器团队成员进行的一项实验开始的。若是咱们忽略了传统的布局模型,咱们想看看是否能够创建更快的渲染器。几周后,咱们取得了显着的业绩增加。咱们发现:
这里是Flutter代码来建立一个布局简单的widget树:
new Center(
child: new Column(
children: [
new Text('Hello, World!')),
new Icon(Icons.star, color: Colors.green)
]
)
复制代码
这个代码的语义是足够的,你能够很容易地想象它会产生什么,可是这里获得的结果是:
在这个代码中,一切都是widget,包括布局。Center widget将其中心放置在其父级(例如屏幕)中。Column布局widget垂直排列其子元素(widget列表)。该列包含一个文本widget和一个图标widget(它有一个属性,它的颜色)。 在Flutter中,居中和填充是widget。主题是widget,适用于他们的孩子。甚至应用程序和导航都是widget。 Flutter包含了不少用于布局的widget,不只包括列,还包括行,网格,列表等。此外,Flutter还有一个独特的布局模型,咱们称之为“sliver layout model”,用于滚动。 Flutter中的布局很是快,能够用于滚动。想想。滚动必须是瞬间发生的和平滑的,以致于用户感受像屏幕图像在他们拖过物理屏幕时被附着到他们的手指。 经过使用滚动布局,Flutter能够实现高级类型的滚动,以下所示。请注意,这些动画GIF图像,Flutter更平滑。你能够(也应该)本身运行这些应用程序;请参阅本文末尾的参考资料部分。
大多数时候,Flutter能够一次完成布局,这意味着线性时间,因此它能够处理大量的widgets。 Flutter也作缓存和其余事情,因此能够避免布局。
由于widgets如今是应用程序的一部分,因此能够添加新的widgets,而且能够定制现有的widgets以使其具备不一样的外观或感受,或匹配公司的品牌。 移动设计的趋势远离几年前常见的cookie应用程序,而且朝向取悦用户并赢得奖项的定制设计。 Flutter为Android,iOS和Material Design提供了丰富的,可自定义的widgets集(事实上,咱们已经知道,Flutter是Material Design中最高保真实现之一)。 咱们使用Flutter的可定制性来构建这些widgets集,以匹配多个平台上的本机widgets的外观和风格。 应用程序开发人员可使用相同的可定制性来进一步调整窗口widgets,以知足他们的需求。
用于reactive web views的库引入了virtual DOM。 DOM是HTML文档对象模型(HTML Document Object Model),一个使用JavaScript用来处理HTML文档的API,用一个元素树来表示。 虚拟DOM是使用编程语言中的对象建立的DOM的抽象版本,在这种状况下是JavaScript。
在 reactive web views(由ReactJS等系统实现)中,虚拟DOM是不可变的,每当有任何变化时,都会从头开始重建。 将虚拟DOM与真实的DOM进行比较,生成一组最小的更改,而后执行这些更改以更新真实的DOM。 最后,平台从新渲染真实的DOM并将其绘制到画布中。
这可能听起来是不少额外的工做,但它是很是值得的,由于操纵HTML DOM是很是昂贵的。 React Native作相似的事情,但对于移动应用程序。 它不是DOM,而是操纵移动平台上的原生widgets。 它不是虚拟DOM,而是构建一个widgets的虚拟树,并将其与本机widgets进行比较,只更新那些已更改的widgets。
请记住,React Native必须经过Bridge与Native widgets进行通讯,所以widgets的虚拟树有助于将Bridge过程消耗保持在最低限度,同时仍容许使用本机窗口widgets。 最后,一旦Native widgets被更新,平台将把它们呈如今画布上。 React Native是移动开发的一大胜利,是Flutter的灵感来源,但Flutter更进一步。
回想一下,在Flutter中,widgets和渲染器已经从平台上升到用户的应用程序中。没有原生的OEM widget tree能够操做,那么virtual widget tree如今是widget tree。 Flutter渲染widget tree并将其绘制到平台画布上。这是很好,简单(和快速)。另外,动画发生在用户空间中,因此应用程序(以及开发者)对其有更多的控制。
Flutter渲染器自己颇有趣:它使用几个内部树结构来渲染那些须要在屏幕上更新的widgets。例如,渲染器使用“structural repainting using compositing”("structural"意味着是经过widget,比经过屏幕上的矩形区域更有效)。不变的widgets,甚至是那些已经移动的widgets,都是从高速缓存中“bit blited”的。这是Flutter中即便在高级滚动(在上面讨论和示出)中滚动如此执行的事情之一。 为了仔细了解Flutter渲染器,我推荐这个视频。你也能够看看代码,由于Flutter是开源的。固然,您能够自定义甚至替换整个堆栈,包括渲染器,合成器,动画,手势识别器和(固然)widgets。
由于Flutter就像使用反应视图的其余系统同样,为每一个新帧刷新视图树,因此它建立了许多只能存活一帧(六十分之一秒)的对象。 幸运的是,Dart使用对这类系统很是有效的“分代垃圾收集”,由于对象(尤为是短命的)相对cheap。 另外,对象的分配能够用single pointer bump来完成,这是快速的而且不须要lock。 这有助于避免UI jank和stutter。 Dart也有一个“tree shaking”的编译器,其中只包括您的应用程序须要的代码。 即便只须要其中的一个或两个,也可使用大型widgets库。
Flutter最受欢迎的功能之一是其快速,有状态的Hot reload。 您能够在Flutter应用程序运行时对其进行更改,并从新加载已更改的应用程序的代码,并让代码从中止的位置继续,一般不到一秒钟。 若是您的应用程序遇到错误,您一般能够修复错误,而后继续,如同错误从未发生过。 即便你必须作一个完整的重载,速度也很快。
开发人员告诉咱们,这可让他们“绘制”他们的应用程序,一次作出一个更改,而后几乎当即看到结果,而没必要从新启动应用程序。
因为widgets(以及这些widgets的渲染器)是您应用程序的一部分,而不是平台的一部分,所以不须要“兼容库”。您的应用程序不只能够正常工做,并且在最近的操做系统版本(Android Jelly Bean和更新的版本以及iOS 8.0和以上的版本)上也能够发挥一样的做用。这大大减小了在较旧的OS版本上测试应用程序的须要。另外,您的应用极可能会在将来的操做系统版本上运行。 咱们被问到一个潜在的问题。因为Flutter不使用OEM native widgets,当新版本的iOS或Android支持新类型的OEM native widgets或更改现有OEM native widgets的外观或行为时,Flutter widgets 是否须要更新才会更新?
Flutter的简单性使其变得更加快速,可是广泛的可定制性和可扩展性使其变得强大。 Dart有一个软件包的存储库,因此你能够扩展你的应用程序的功能。 例如,有许多软件包能够轻松访问Firebase,所以您能够构建“serverless”应用程序。 外部贡献者已经建立了一个包,容许您访问Redux数据存储。 还有一些名为“plugins”的软件包,能够以独立于操做系统的方式轻松访问平台服务和硬件,如加速度计或摄像头。
固然,Flutter也是开源的,加上Flutter渲染栈是你的应用程序的一部分,意味着你能够自定义几乎任何你想要的一个单独的应用程序。 这个图中的全部绿色均可以定制:
若是有人问你有关Flutter,如今你知道如何回答他们:
你有没有注意到我从这个清单中删除了什么? 当人们谈论Flutter时,这一般是人们首先提到的,但对于我来讲这是Flutter最不感兴趣的事情之一。 事实上,Flutter能够从一个代码库为多个平台构建美丽而快速的应用程序。 固然,这应该是一个给定的! 这是可定制和可扩展性,能够轻松地将Flutter目标锁定到多个平台,而不会放弃性能或功耗。