2019成都写作课

一项改变游戏规则的技术 - Flutter

2019-12-15  本文已影响0人  NANAISNANA

"A fast app is great, but a smooth app is even better."

使用Flutter beta版上线了一个APP的故事

去年的11月底,我第一次打开Flutter的官网,想看看Flutter到底是什么;3个星期后,我们赶在Apple的App Store审核团队圣诞节休假前,提交了第一个使用Flutter开发的App。当然,是iOS和Android双端同时提交。

我们使用Flutter开发的产品是一个图片feed流,作为一个模块嵌入到一个美颜相机里面。

在接下来的2个月内,我们保持着每2个星期发版的频率,成功上线了以下核心功能:

再来看看我们整个Feed流团队有多少人:

以上团队是第一个版本发布后的团队组成,我们的第一个版本期间,开发只有4人(后端,iOS,Android,Web,各1人)。

思绪回到我们决定使用Flutter的那一天,其实我们做了一个冷静之后看起来十分激进和冒险的技术选型,因为我们当时的场景是: Flutter beta版 + Flutter和已有的native混合 + 已有的native是一个相机类App + Flutter开发的功能是一个feed流。这个组合已经是当时能使用Flutter的场景下,非常苛刻的了,接下来我具体解释一下其中的挑战在哪里:

但是,上面的这些挑战,Flutter都很好地消化了。基于我个人的开发体验来讲,是因为Flutter具备以下优点:

看到这里的同学,脑子里面可能一直萦绕着一个问号:你一直在说的Flutter到底是什么?

Flutter是什么?

Flutter - 跨平台

Flutter是谷歌推出的跨平台UI框架,目前已经支持的平台有:mobiledesktopweb。Flutter的目标是以上平台能支持到以下对应的操作系统或平台:

就目前来说,mobile端的支持是最成熟的。desktop端仅支持macOS,web端有beta版可以使用,但是还不是十分成熟。

说到跨平台的技术或者框架,我们可能自然会想到React Native或者Weex(阿里出品的一个跨端框架,我居然还使用过一个月)。那么除了跨平台之外,Flutter具备哪些特性,使得它能脱颖而出呢?

Flutter有什么特性

开发效率高: Flutter拥有hot reload功能,每一次修改代码之后,只需要保存,不论是在模拟器上还是在连接的真机,都可以在秒级的时间内,马上看到效果,而不用再像以前以下需要经历重新的编译,打包,安装。

双端一致的UI:React Native是把JavaScript代码转换为Java或者Swift语言,最终调用平台各自的渲染机制来渲染UI。而Flutter不论是在iOS还是Android端都统一采用Skia(一个二维图形库)来渲染UI,这样就从根源上解决了由于平台不一致带来的UI不一致的问题。

丰富和美丽的UI:Flutter内置的Material Design和Cupertino(iOS风格)组件,能让你的App拥有现代化的漂亮的UI。又因为在上一点提到的,因为采用了Skia,你页面上的每一个像素都是Skia画的,所以你可以对你的组件进行高度的定制化。

媲美Native一般的性能:Flutter使用Dart作为它的编程语言,dart的编译器会把你写的Flutter代码直接编译成机器码,从而带来跟native一样的性能。

现在我们来深入了解一下Dart,因为它对Flutter高效的开发效率,和高性能都是至关重要的。

为什么Futter采用Dart语言

在了解Dart之前,我们先来认识2个概念:AOT和JIT

AOT就是在运行前,已经完全编译好,而JIT则是在运行中会进行分析和编译。AOT的优点是运行速度快,因为它不需要在运行时再进行分析和编译,因为它已经提前编译好了。相对的,JIT的运行速度慢,因为它在运行的过程中会停下来做分析和编。

想一想,在日常开发native app的时候,我们希望代码修改可以以最快的速度被看到,而不用每一次都需要经历编译,打包,安装。相应地,当我在使用一个native app的时候,我希望它能很快响应我的操作,比如滑动的时候,页面很流畅;动画也会不会卡顿。

为了满足以上2种需求,我希望拥有一种结合了JIT和AOT的技术。事实上,Dart正是如此。

在我们开发的时候(debug mode)的时候,Dart采用JIT的模式,我们前面提到的Hot Reload也正是依赖于此。Hot Reload的工作原理是通过把修改后的源代码文件塞给Dart的虚拟机(VM),等虚拟机根据最新的属性和方法更新类文件之后,Flutter会自动重新构建组件树(widget tree),从而你可以迅速地看到你修改的结果。

在打包的时候(release mode)的时候,Dart采用AOT模式。AOT模式的好处是使得用户可以在很短的时间内启动App,在使用App的时候,也会很流畅,因为所有的东西都已经被编译好了。

Dart的线程

如果你了解Java,C++,或者Swift等,你知道这些支持多线程并发的语言,采用的是一种叫做抢占式调度(Preemptive scheduling)的机制。抢占式调度,即操作系统给每一个进程都分配一定的CPU占用时间,当进程A的时间已经花完,这时候就该轮到进程B来占用CPU了。但是,当不同的进程或者线程使用了同一个资源(比如同一段内存)就会造成资源竞争(Race condition)

资源竞争可以造成严重的后果,比如让你的App崩溃掉,或者造成数据的丢失。经典地解决资源竞争的办法是加锁,但是加锁本身又能带来别的问题,比如死锁和资源饥饿。

抢占式调度

Dart则采用了另外一种思路。线程到了Dart里面叫做isolate。不同的isolate之间是不共享内存的,也是独立做垃圾回收的。

我们的一个Dart程序执行在一个isolate里面。在一个isolate里面,所有的事件都是通过eventLoop的方式来进行异步处理。

相应地,Dart提供futures,async, await来处理异步请求。这使得我们在渲染UI的同时,可以进行一个HTTP的请求或者读取文件之类的的操作,但是不会造成页面的卡顿。

Dart统一了UI编写
Dart不仅是从语言特性层面为Flutter的性能起到至关重要的作用,在对开发效率的提高上也是十分终于的。前面我们已经提到了Hot Reload功能以来与Dart的JIT编译模式,除此之外Dart统一的UI组件编写方式,也对我们日常的开发效率起到了非常大作用。我们先来看一段使用Dart编写一个Flutter组件的示例:

使用Dart编写一个组件

Dart编写一个组件的方式,和iOS,Android,Web端的方式都不一样。

传统的Web端开发,是把一个组件所需要的HTML,CSS, JavaScript分开到不同的模块里面。假如你需要改动css,你得先跳到css所有的领域(可能是另外一个单独的css文件,或者假如你使用vue,那么就是在这个.vue文件的style模块)。然而,在Dart里面,一个组件的dom,样式,事件处理都是作为一个组件的属性存在,他们都是在一个地方,既不会分开到不同的文件,也不会分开到不同的模块。

我记得我一开始写Flutter的组件的时候,非常地不习惯,甚至产生抗拒心理。因为Flutter的组件结构方式与我写了多年的web端组件写法是完全对立的。但是,当我写了2个星期后(我在网上到讨论,一般大家的过渡期也是2个周),开始觉得这种写法是如此自然又高效, 甚至开始怀疑以前自己写的那些代码:web端那种把HTML, CSS, JavaScritp分开的形式,是不是本身是种错误。也开始反思,为什么我从来没有怀疑过这种既定规则的合理行。

因为我自己没有长期iOS端和Android端开发的经验,我不知道从iOS端的Layout布局和Android端的XML布局转换到Dart,是怎样的心路历程。但是,下面是我从网上找到的一些感想:

客户端开发人员关于使用Dart编写组件的感想

Dart dev tool

Dart提供了一些工具来帮助你日常的开发和调试,其中一个是非常厉害的工具就是Dart dev tool。举一个例子:下图展示的是一个在Flutter里面常见的bug:子元素溢出了。这个时候你打开Dart dev tool,你可以看到这个组件的布局,在这个工具上会显现这个元素相关的一些属性值,给你提供排除bug的思路。比如这个例子里,我们看到flex的值为‘null’,这可能是bug的原因,你可以通过下拉框选择一个flex的值,看是否可以解决这个bug:

使用Dart dev tool尝试修复一个bug

是否推荐项目采用Flutter

前面花了很大的篇幅来介绍我和我实际使用Flutter上线了一个App的故事和感受,也从Skia和Dart层面去分析了为什么Flutter具备有那么多的优点,而不只是官方宣传。那么最后的最后,作为一个还十分年轻的技术,flutter是否适合在项目上使用呢?

没有一个技术是完美的,但是除了一些不可抗力的因素外,我们去做一个技术选型,依据的标准应该是它的优点是否超越它的缺点。不如我们再次来总结一下Flutter比较核心的的优点和缺点:

Flutter的优点:

Flutter目前存在的缺点:

Flutter从2018.02发布beta版,2018.12发布1.0版本,短短2年时间,到现在github上的start数量已经有81.6K。不论是国内还是国外,已经有大量的使用Flutter开发的产品,比如 Realtor.com Real Estate Search, Google Assistant,咸鱼等。

当下,Flutter和Fuchsia(谷歌正在研发的一个新的操作系统)都是谷歌的重心,所以大概率Flutter不会成为一个烂尾的项目。而且,就Flutter目前拥有的成绩证明,它已经足够优秀,何况它还这么年轻。

所以从我自己的角度来说,十分推荐采用Flutter。可能web端和desktop端目前还不那么成熟,但是native端可以大胆尝试。

上一篇 下一篇

猜你喜欢

热点阅读