▐ Flutter2.0
整场活动中,最令人激动的就是Flutter2.0的发布了。那么Flutter2.0主要带来了哪些新的特性呢?
一句话总结,Flutter2.0最大的变化是除了之前已经处于stable渠道的移动设备支持外,桌面和Web支持也正式宣布进入stable渠道。
▐ Dart2.12
独一无二的应用构建能力集合
可移植性
Dart的高效编译器可以生成针对x86&ARM的机器码,以及针对Web优化过的JS。其广泛支持了各种目标: 移动设备、桌面PC、后端应用以及更多。
高开发效率
Dart提供的HotReload特性,支持快速的,可交互的开发体验,不论是原生设备还是Web应用均如此。Dart也提供丰富的对象用于应用开发,包括Isolate模型,async/await并发处理,以及事件驱动的开发模式。
健壮
Dart的健全空安全类型系统可以在编译期捕获错误,这一切高度可伸缩可信赖,并被用于支持大量的应用,如高度重要的Google Ads,Google Assistant,运行长达长达十年以上
健全的空安全
健全的空安全是自从Dart2.0引入健全类型系统后,Dart语言的一大改进。空安全进一步增强了类型系统,使得开发者可以去捕获空错误,这也是应用崩溃的一大常见原因。通过引入空安全机制,开发者可以在开发期捕获空错误,避免线上崩溃。
以下是健全空安全的几大原则
默认非空: 对于类型系统的根本性变化
默认使用non-nullable
增量迁移到空安全
针对以下代码,空安全将带来显著的机器码减小:
int age = 0;
}
int getAge(Animal a) {
return a.age;
}
持续改善已有功能
GooglePay包大小通过针对Flutter的优化大小降低了14%
针对不同的输入,UTF8Decoder最快可以加速20x
用于集成Dart和C的FFI
Dart FFI使得你可以利用已有的C库代码,这样不仅提高了可移植性,也可以在性能敏感的场景下充分利用高度调优的C代码。Dart2.12中,FFI已经脱离beta阶段,被认为是stable,可线上使用。并新增了以下特性。
按值传递结构体
结构体嵌套
自动生成FFI绑定
Dart语言的下一步
类型别名
三相移位操作符
通用元信息注解
静态元编程
▐ Web
FlutterWeb正式进入stable渠道。随着这一初始stable的发布,已有Flutter代码Web平台支持将进入一个新的阶段,换句话说,当你使用Flutter2.0创建App时,Web只是一个新增的设备目标。
借助Web平台的诸多能力,Flutter构建了可用于富交互Web应用的基础。Flutter For Web(FFW)主要聚焦于高性能及高保真的渲染性能。除过HTML渲染后端外,FFW也新增了一个CanvasKit的渲染后端。以及诸多针对Web的特性,比如Link Widget,使得你的应用在浏览器中的运行可以真的感觉是一个Web应用。
在这一阶段,FFW主要聚焦以下应用场景:
Progressive Web Apps(PWA)
Single Page apps(SPA)
将已有Flutter移动应用扩展到Web侧
架构设计
整个框架使用Dart编写,总计约70w行的Flutter框架核心代码针对所有平台是一致的,不论是mobile,desktop还是现在的web.你既可以使用dartdevc或者dart2js将代码编译成javascript,进而运行在服务器上。
鉴于Dart本身可以将整个Flutter框架编译成JS,将Flutter运行在Web上的核心问题就是将移动应用的底层C++渲染引擎替换成对应的Web平台API。Flutter并不是简单地将Widget编译成对应的HTML元素。相反,其Web引擎提供了两种渲染后端选择,HTML后端用于降低包大小,并提供广泛的兼容度。
CanvasKit后端使用了WebAssembly和WebGL来在浏览器Canvas上渲染Skia绘图指令, 具有更高的性能和组件密度,但增加了大约2M的下载包大小。你可以通过以下命令来指定渲染后端。
--web-renderer html
--web-render canvaskit
稳定的Web支持
Showcase
Rive
Rive, 是一个用于创建自定义动画的工具,使用Flutter For Web来重构其代码,并已经beta可用。
https://rive.app
Flutter Plasma
Flutter Plasma展示了一个运行在Safari, Firefox, Edge和Chrome上的Flutter Demo。
https://flutterplasma.dev
iRobot
iRobot教育使用Flutter开发了iRobot Coding App,通过将其在Web可用,提供了随处可用的针对任何人的代码学习体验。
Mobi
Moi Mobiili, 一个现代移动虚拟网络运营商,近期使用Flutter发布了他们的Web应用。
https://www.moi.fi
Web的相关特性
自定义URL策略
新的Link Widget
基于Canvas的文本度量和渲染
文本交互(选择,拷贝,粘贴等)
支持桌面表单因子
展望
CanvasKit的进一步支持,比如CORS图片
PWA的全离线支持
文本渲染以及功能
插件生态系统的完善
▐ 桌面支持
Flutter Desktop也正式进入stable渠道,即初始发布状态。
Canonical正在同Flutter合作以将Flutter引入桌面,工程师们正在开发代码并且将其部署到Linux上。对其而言,各种各样的硬件配置下提供稳定可靠并且优美的体验是至关重要的。再往后看,Flutter将是后续Canonical桌面以及移动应用开发的默认选择。
- 文本编辑体验
- 鼠标输入体验
- Scrollbar
- IME支持
- 桌面额外功能支持
- 更新的文档支持以将应用发布到特定应用商店
▐ 折叠设备支持
微软在持续扩大其对于Flutter的支持。除了在Flutter Engine中持续贡献高质量的Windows支持外,微软正在增加对于新的可折叠Android设备的引擎支持。这些设备引入了新的设计模型,App既可扩展其内容,也可充分利用多屏特性提供side-by-side的体验。
此外,gskinner开发的Folio App,很好地诠释了Flutter在多平台上的运行。通过一套代码,不论是在小,中等还是大的屏幕上,Flutter均可处理好触摸,键盘和鼠标输入,并同平台的特性适应良好(比如Web上的链接以及桌面上的菜单)。
▐ 嵌入式设备支持
丰田公司,宣布了他们计划提供市场上最好的机动车上的数字体验,通过使用Flutter来构建娱乐信息系统。使用Flutter标志着同以前车载软件完全不同的开发体验。Toyota之所以使用Flutter,是因为以下的原因:
高性能和AOT一致性
智能手机层的触摸机制
人类工程学
从客户反馈中快速迭代
▐ 工具链
FlutterFix
如今有超过50w的Flutter开发者,我们所面临的的设备平台也越来越多。当框架变得成熟,越来越大的时候,我们越来越需要去避免对于框架的修改,不要去破坏愈发庞大的代码库。然而,为了持续改善Flutter,我们也需要能够去对API做Breaking修改,问题来了,如何去持续改善FlutterAPI而不阻断开发者体验呢?我们提供了FlutterFix。
Flutter Fix包含了以下特性:
dart fix——新提供的命令行选项dart fix可用于查找哪些API已经被废弃,如何去更新这些API。
提供可供fix的选项
IDE插件集成从而可以通过选择完成修改
DevTools
IDE插件可帮助开发者清零问题,即便是DevTools还未启动。
通过点击按钮,即可快速找到引发问题的Widget。目前仅支持Layout Overflow异常,但DevTools团队计划去涵盖所有的常见类型异常。
轻易发现高分辨率的图片,跟踪降低过度的包大小与内存使用
Inspector新增对于固定Layout的展示能力
内存视图更快,小,易于使用
日志Tab增加搜索与过滤功能
在DevTools启动前即可跟踪日志
▐ 社区与生态数据
Flutter1.0发布至今已经两年有余,Flutter共计关闭了24541个Issue,合并了来自765个贡献者的17039个PR。目前共计有50w+的Flutter开发者,超过15w的Flutter应用。
目前有15k的针对Flutter和Dart的Package,这其中包括了亚马逊,微软,Adobe,阿里巴巴,eBay,Square等公司,也要报关键包诸如Lottie, Sentry, SVG,以及Flutter Favorite推荐的sign_in_with_apple, google_fonts, geolocator和sqlite.
▐ 其他
Add2App中的多引擎实例
过去,额外的Flutter引擎创建会造成同第一个实例同样的内存开销。在Flutter2.0上,我们将这一内存开销减少到了每个实例180KB,降低了99%之多。由此,我们推荐在你的原生App中去使用多个Flutter引擎实例。
DartPad升级到支持Flutter2.0
▐ AskFlutter圆桌
参与这场圆桌的成员有:Andrew Brogdon(主持人)、Eric Seidel(Flutter负责人)、Ian Hickson(Flutter技术负责人)、 Mariam Hasnany(FlutterForWeb PM)、Frank van Puffelen(开发者项目工程师)。
以下针对一些重要的问题做了摘录:
- 主持人
什么时候FlutterWeb可以供生产环境使用?
- M
好消息是,今天Flutter Web正式在stable渠道可用。你无需enable任何flags,即可将Web作为Flutter应用的目标设备。也就意味着,对于任何已经有Flutter Web App的开发者,你现在可以用stable渠道来构建你的应用,如果你是要新开发Flutter Web Apps,快来检出把。
- 主持人
什么是Flutter Web的理想用户场景呢?
- M
这真的是一个好问题,随着这次标志性的发布,我们已经聚焦在构建富交互Web应用的基础。如果你已经有一个Flutter移动应用,你现在可以使用同样的代码来构建其Web版本,然后把你的用户群基础扩展到整个Web应用。不仅如此,这对于构建PWA或者SPAde应用来说也是一个额外的优势。这些应用通常使用大量的动态内容,交互UI,我们通常认为这三种是最适合的。当然为了支持文档为中心的页面我们还需要很多工作去做。比如,传统的HTML页面有很多的文本,静态的内容。所以我想现在我们的确已经很适合来开发Web应用。
- 主持人
目前在Github上有超过8200个Open Issues、Flutter似乎有些人手不足,有没有计划加以改善这种问题或者你们的优先级是什么?
- I
是的,我们的确有这么多,正如Netlinx(提问者)问道的,我们有8000多处于Open状态的Issues, 但重要的是我们正在尽力去解决他们,比如去年我们在Github上收到了15000多Issues,我们也关闭了15000issues。我们对修复和解决bug的比例还是很高兴的。这一数字表征了我们有多少用户。越多人使用,就有越多的bug提出。我们解决issue的数字是一个贡献者多少的指标,我们很多贡献者。在Github的Flutter Hacker组里,我们有超过200人。一半以上是谷歌员工,大部分贡献者并不是。事实上,部分Flutter Team的人是来自开源项目的,他们可能是微软或者Canonical,或者是使用自己时间的志愿者。不同的人投入的时间不同,他们都给这个项目做出了共享,希望我们可以解决更多的问题,让Netlinx高兴。
- 主持人
Flutter Web什么时候会废弃URL中的#?
- M
这是一个很好的问题。让我们从为什么它的存在开始,今天我们有时候要使用hash URL策略,这是当我们初始这个Web引擎的时候决定的。也就是说当你有Flutter具名路由的时候,我们基本上是初始化这些路由作为hash的一部分,添加到URL上。随着今天Stable的发布,我们有了新的办法来自定义URL,从URL中丢弃hash。这样你就可以按照自己的方式来构建URL,配置其余的子URL,实现deep link或者说同朋友来一起分享。社区中也有一个叫做URL Strategy的插件,它实现了我们在文档中的指南,以一种很简单的方式。
- 主持人
Flutter依然有很多Mac M1上的兼容性问题,你们是否在加以解决还是说我需要买一个旧的Intel Mac?
- E
我想说你不需要买一个新电脑,我建议你今天再试试。Flutter2.0上有很多针对M1的优化。其实我们也是同社区同一时间知道M1新发布的这类信息的。当天我们就订购了一个M1的开发机并用它开始工作。我们将其分为了三个桶,用来运行App, 工具链以及开发工具。据我所知,前两个桶其运行都是良好的。当然随着Flutter2.0的正式发布,如果你遇到了M1或者其他的问题,我们想听到你的反馈。正如Ian所说,我们每天有很多Issues,我们想去尽快去解决他们。因此,快去试试Flutter2.0吧,我想它应该会工作良好的,而且也会持续工作很好,因为我们会做更多代码修改。
- I
M1有意思的是它几乎是一个全新的平台,因为我们以前从来没有用ARM作为host。今天我们发布Web和Desktop,但是,实际上,Apple Silicon是苹果自己的平台,我们要去支持。虽然我们现在已经支持当前release的macOS,但是依然有大量的工作要去做。
- 主持人
Flutter Dart团队是否计划去提供针对App开发的官方指南?类似Android的Jetpack?
- I
我要笑了,因为你把这个问题丢给我似乎你不知道这个答案一样。我们已经讨论了好几个礼拜了,是的,我们有,实际上,我想或者是今天或者是很快,我们会发一个新的模板到Flutter master分支,这个模板基本上就是这个问题的答案。如何去使用最佳实践来创建和应用,状态复原等等?不仅是这个问题的答案。编程的核心在于针对这些问题有很多的差别,不同的App有不同的需要,我们希望这样特定的模板可以真的帮助到大家,我们也希望后续可以有针对不同架构类型的模板。可能你更喜欢redux而不是我们在模板中使用的。这个今天不会随着Flutter2.0发布,但是我想会在未来几个月的stable版本中发出。
- 主持人
空安全是否会破坏已有App? 是否有一些内容需要被迁移?
- E
这个问题是你能够去迁移。甚至有个工具可以使用。我想应该叫做dart fix,你可以在你的代码库上运行它,将会帮助你去将代码改成Null aware.
- I
如果你关注了更早的Keynote,我们有一章是关于他如何工作的。这并不会产生破坏性,你首先要确保你的依赖都已经顺利迁移。如果你的依赖没有迁移,对你来说迁移自己的代码将很困难。这是可能的,但会变的低效。所以,如你所知,如果你有一个包还没有迁移,去让这个包的开发者完成迁移。即便不迁移,也不会有特别的破坏性。正如Keynote提到的,这是为什么我们不把这次发布叫做Dart3.它是向后兼容的。同其他语言一样,Dart空安全里,你可以决定使用哪个版本,Dart2.0或者更高。我们在Flutter Sample仓库里经历过这些,我们观察例子,看看有多少依赖。对他们进行排序,随着Flutter2.0,我们事实上已经处理完了Sample仓库。另一个我们部署空安全方式的好处是,你可以同时编译空安全和非空安全,编译器自己会使用空安全优化。他可以在编译空安全代码的时候知道类型。当到了非空安全代码边界的时候,他会添加判空逻辑。我们称之为非健全空安全。如果我没记错的话,因而你的代码可以在混合模式下执行,也是可以的。
- 主持人
Flutter是否适合3D渲染?
- E
我来回答吧。我们是把Flutter作为2D系统构建的。其实也有很多人用它来做3D工作。我们提供的API可以用来在一个屏幕上绘制2D对象。要支持3D,人们可以自行创建2.5D或者3D对象,然后通过纹理这样的方式嵌入Flutter.有很多人就这么做。
事实上Keynote中,我想就提到了Wallace & Gromit app。
它里面就有2D和3D内容。将二者混在一起是可行的,但是再说一遍,Flutter是针对2D体验设计的。
- 主持人
Flutter对于桌面的支持怎么样?
- I
是的,Flutter Desktop如今已经在stable渠道可用,尽管我们不认为它是完全stable了,我们支持macOS, Windows和Linux现在。还有什么呢?我们还没有提供你可能需要的所有必须特性,例如,我们目前还没有支持多窗口,尽管这已经在开发了。我们还有很多努力。支持基本的单窗口App是非常稳定的。我自己就写了一个数独应用,运行在Mac上,工作很棒。
- E
是的,我想多说一些,我喜欢Flutter Desktop,并且他已经在stable渠道可用,他的开发体验很棒。你只需要打开它,Flutter自己就正常运行了,这种工作体验很棒。试试吧,给我们写反馈,我想说,对于我,Flutter Web和Desktop公共的部分很棒。
- 主持人
什么时候首次打开App动画卡顿的问题可以得到解决?
- E
这是一个普遍的问题,特别是最近几周,我在Reddit上写了很长的帖子,我也正在写一个更长的博客。我想说的是性能一直是Flutter最基础的一个衡量,当我们五六年前讨论这个项目的时候,我们就在说先谈论性能。在我们的任务列表中,性能是排名第一的。这不仅仅是文字,我们通过各种方式去保证这一点。所有的提交都要首先通过各种各样的性能测试,包括所有平台。我们一直在追求性能优化,每天都是如此。尤其当面对首次启动的动画卡顿的问题,我们意识到这个问题已经有一段时间了,尤其是iOS上。过去的一年这个问题在某些场景下愈加恶化。当从OpenGL迁移到Metal的时候,我们不能够在去缓存Shaders,你必须使用GPU去产生这些像素。不论如何,我们已经充分意识到有这样的问题,正在努力去解决,很多人力投入其中。Ian就在攻坚这些问题。
- I
是的,我一直在关注这些卡顿的issues,这是我现在非常关注的问题。你可以看看Github Probject188, 我内心里一直记着这个数字因为我经常打开它。那里有所有相关的问题。你能做到最好的事情就是,如同我们之前讨论的,如果你遇到应用卡顿,请提一个bug,带上复现代码,包括显示卡顿的视频,以及时间线的trace以说明你的应用在视频中具体在干什么。这是目前对于我们来说最有帮助的了,我们可以去研究特定的Case,他们并不都是因为同样的原因造成的。即便是Shaders的原因,也不一定是因为同样的Shaders。所有这些不同的bug将会被以不同的问题加以解决。
- 主持人
谷歌打算如何在内部使用Flutter Web?
- E
我不能,你知道的,谈论其他团队的计划,我能说的是有很多团队正常尝试使用Flutter Web. Flutter Web今天刚刚来到stable渠道,我们也正在给内部团队类似的指引,知道的,我们依然在解决各种问题。所以今天并没有什么能宣布的,但是我可以期待有更多的对于Flutter Web的使用。我致力于这个工程技术,认为这是一种更好的方式来写一次代码,可以运行在各个平台上。我们已经看到很多谷歌团队接受了Flutter的这一策略,我想Flutter会继续来到更多的应用场景的。
- I
我们已经看到内部的很多工具使用Flutter For Web.当这些工具背后没有一个大的团队的时候,他们需要一些有用且可以高效开发的工具。比如,在Flutter团队里,我们使用Flutter Web来开发一些内部工具,用于把公共的Flutter代码迁移到如GooglePay这样的内部仓库中,以及供其他团队使用。这些工具都是使用Flutter写的。
- 主持人
Dart何时支持WebAssembly?
- I
这意味着很多问题,我们实际上已经在Flutter For Web中使用WebAssembly了。Mariam可能可以谈更多,简单来说,我们有其他两部分WebAssembly和Dart相关。一个是是否直接把Dart编译成WebAssembly,另一个是,是否可使用已经编译成WebAssembly的代码并且将其同Dart链接。对于第二问题而言,把WebAssembly连接到Dart,我想有一个包已经可以做到这一点。虽然不是最方便的方式,但是是可行的。至于将Dart编译成WebAssembly,目前还是不可行的。这需要WebAssembly去实现一些尚不成熟的特性,WebAssembly GC,多线程等等。我们对此很感兴趣,我想WebAssembly有潜力在未来几年真的成为一种统一的互操作语言。
- M
Flutter Web目前有两个渲染后端,我们默认使用HTML。HTML+DOM+CSS后端这种方式来渲染应用,但我们也在尝试使用CanvasKit来进行渲染。今天我们已经稳定下来,你可以使用CanvasKit,它采用了WebAssembly和WebGLS来渲染App,以在浏览器中替代Skia.针对这两个不同的渲染后端,我们也有一些叫做auto的内容。他可以针对不同的环境来选择渲染器,在桌面中使用CanvasKit,在移动浏览器中使用HTML,以便充分采用两者的优点。
- 主持人
同React,Angular相比你怎么看Flutter Web?
- E
我首先想到的是,Flutter Web,我们只是在Canvas中绘制,我们认为是直通GPU/CPU,我想这是同React和Angular很大的不同。
- I
我总是很犹豫去把Flutter同别的技术去做对比,因为每一个都有有效的用户场景。我不想去提React说,React这里好,那里不好。这完全取决于React,我们很高兴能沟通这些其他技术并存,我们也希望整个社区作为一个整体可以写出指南说,你知道什么样的场景下Flutter很适合,什么场景下Flutter For Web很适合,什么样的场景下React很适合等等。
- 主持人
你认为我们应该使用哪个渠道?
- I
Stage主要的区别是,stable同其他渠道的差别,我们会把fix pick到stable channel。因此你可以看到stable channel每次更新变化都很小。这一点不会发生在dev分支上。我们不会检查dev渠道,如果dev出了问题,他会被在trunk上修掉,然后我们重新会在未来几天生成一次dev.这也不会发生在主线上因为我们一直在主线开发。这里就有风险,越近的代码,越容易有我们没有捕获i的问题。当然,他们最终都会被修复,这是一个权衡。
▐ 结论
这是个令人振奋的发布,至此我们可以说Flutter真正做到了以应用为中心,全平台的支持。不论是面向移动,还是面向桌面,或者是Web,Flutter都做到了产品级可用。面对日趋激烈的业务竞争,其可显著降低开发成本与人员不足/不均衡的问题,提供更稳定一致的用户体验。
但从另一个方面讲,国内市场普遍面临的Legacy System的问题,目前看从官方渠道并没有一个解决方案。尤其是对于桌面端的问题,Windows XP,Win32这样的应用场景下,以及FlutterWeb性能体验兼容度的问题,业务方还是需要一定的备选方案。其他的诸如移动设备性能,包大小,动态性,浏览器兼容度,目前原理上本身已经不是问题,只是为了性能,大小,体验考虑,还是需要做更多的深入细致的优化工作。
▐ 结论参考资料
What’s New in Flutter 2.0
Announcing Dart 2.12
Flutter web support hits the stable milestone
Language design funnel
Flutter design doc
Flutter Engage Youtube
Flutter Folio
Announcing Flutter support for foldable devices