天天看点

准备好了吗?It's time for Flutter!

Flutter 是当下移动端领域非常热门的跨端框架,各个大厂都在积极探索这项技术,并在主营业务上实现落地。

在 Google Trends 上对比 Flutter 和 React Native 的热度,可以看到 Flutter 已完全超过 React Native,成为当下最热门的移动端跨端技术方案。

准备好了吗?It's time for Flutter!

1

Why Flutter?

为什么选择这项技术?

Flutter 到底具备什么魅力,让这些大厂如此着迷?

我想这是每个移动端从业者都好奇的问题。Flutter 作为一门前沿技术,当前尚未在行业内全面普及,也许有的开发者已经看到机会,想要展现自己才华,那么该如何快速入门 Flutter 技术呢?

而技术管理者可能更想知道 Flutter 这门新技术存在哪些“坑”,自己的团队是否能够驾驭,能够更好地创造业务价值。

这些问题在本文中都会得到解答。笔者目前就职于某一线互联网公司,担任某商业项目的 Flutter 负责人,在业务中大量落地 Flutter 技术,并取得了良好的业务收益,将在本文中跟大家分享他的心路历程。

在 Flutter 诞生之前,业界已有大量移动端跨端技术,其中比较知名的有 React Native、Weex、小程序等。为什么有了这么多解决方案,Flutter 的推出仍会让大家如此兴奋呢?

衡量一项跨端技术的好坏可以从以下维度入手。

跨端一致性:一套代码在多端得到一致的展示效果,这是跨端方案的基本要求。

运行效率:跨端代码运行效率也是一个跨端方案的重要考量因素,运行效率直接影响到能否落地核心业务。

开发效率:许多人会混淆运行效率与开发效率,两者实则是不同的概念。运行效率高指的是这个框架“跑得快”,从而能够胜任更多复杂页面。开发效率高指的是“开发速度快”,决定了研发效率的高低。

原生能力导出:对于跨端框架来说,如何整合两个系统能力也是一个难点。优秀的跨端框架能够形成一个扩展开源生态,提供了多种多样的扩展库,供开发者快速接入。

动态性:原生开发采用应用商店发版升级的模式,必须经过应用商店审核、用户下载的发布流程,导致无法随时更新,这是移动端开发的固有限制。很多跨端项目因为基于脚本引擎,能够实现动态下发,绕过这一限制,不过同时也面临着审核风险。

包体积:用户对应用的安装包体积也是比较敏感的。如果安装包较小,用户在使用流量上网时也更加愿意下载安装,从而有利于积累用户。

目前市面上的跨端技术主要分为以下几类。

基于网页的跨端方案:常用的WebView或者小程序都属于这一类。这类技术的优点是技术栈成熟,开发效率高,并且天然具备动态性,是目前采用最广泛的跨端形式。缺点是执行效率远低于原生应用,尤其在性能较低的手机上,这导致一些复杂的交互效果不够流畅,或出现卡顿掉帧的情况。

端渲染方案:如 React Native、Weex,它们将渲染流程桥接到原生,因此执行效率大大提升。同时依然复用前端技术栈,保证了高开发效率。这类方案的最大缺点是跨端一致性问题,由于最终渲染出来的还是 Android、iOS的原生视图,双端对原生视图的实现原理不同,因此总有一些细微之处是难以对齐的。另外,因为使用 JavaScript 脚本引擎,所以运行效率仍低于原生开发。

这些维度之间此消彼长,很难实现兼顾。Flutter 针对现有框架存在的问题进行专门改进,在各个维度上都进行了突破。

准备好了吗?It's time for Flutter!

Flutter的优势具体可以梳理为以下几个方面:​

像素级别的双端一致性:Flutter自带Skia图形绘制引擎,采用自绘制方式,不论在 Android 还是iOS上,Flutter应用的渲染都不走系统原生,都统一走 Flutter 的Skia引擎进行绘制。因此两端渲染过程是完全一致的,能够实现像素级别双端一致性。

接近原生的执行效率:Flutter 实现了接近原生的执行效率,远远超出同类框架。首先在编程语言上,Flutter 采用 Dart 语言,这是一种非常先进的编程语言,支持多种编译方式,既能够以 JIT 方式编译,也能够以 AOT 方式编译。第二点在绘制引擎上,Flutter 采用集成Skia引擎自渲染,实现了从执行到渲染的闭环,没有跨层带来的性能损耗。

高度双端代码复用:在 Flutter 中,由于采用自渲染方案,两端从运行时环境到底层渲染都完全一致,因此可以实现最大化的双端复用。在实际工作中,基本 90% 的代码能够实现双端复用,剩下的 10% 即两端差异化适配代码。

更高的开发效率:Flutter 选用 Dart 语言进行开发,Dart 语言是一门容易上手、功能强大的语言。Flutter 借鉴 React 设计了一套自己的组件声明式框架。组件声明式框架是前端开发效率高于传统原生的一个重要因素。同时 Flutter 支持 Hot Reload 特性,代码更改可以直接应用到设备中,实现“亚秒级”的效果实时展示,大幅提高了开发效率。

跨端动画效果:Flutter 由于自建绘制引擎,在动画的性能上有先天优势,能够实现接近原生的执行效率,这是超越同类跨端框架的。在开发效率上,Flutter 提供了一套功能强大、简单易用的动画框架,能够方便地实现各种动画效果。同时 Flutter 的动画效果也是双端像素级别对齐的,实现了真正的动画代码双端复用。

先进的应用架构理念:Flutter 虽然没有直接采用前端 JavaScript 生态,但它在设计中大量借鉴了前端架构理念,不论是组件化框架还是全局状态管理器均有 Dart 下的实现。前端流行的架构模式在 Flutter 下均有对应实现,同时 Flutter 开源生态中也发展出了带有 Flutter 特色的新架构模式。通过这些架构模式,Flutter具备开发复杂的商业项目的架构基础。

未来发展潜力巨大:Flutter 的技术特点使其跨端能力极强,不仅能够跨移动端,也能够运行在 Web 端以及桌面平台。更广泛的跨端能力是 Flutter 当下发展的重点。在 Google 的规划中,Flutter 已不仅是一个移动端跨端框架,而是要成为一个跨 Web、桌面、移动端的全覆盖跨端框架。对于学习者来说,学习 Flutter 投入回报非常高。

2

纯 Flutter 应用 or 混合开发

既然 Flutter 有这么多优势,我们怎么把它用起来呢?在落地 Flutter 时通常有两种实现形式:纯 Flutter 应用和混合开发。

准备好了吗?It's time for Flutter!

纯Flutter应用

纯 Flutter 应用指整个工程是一个标准的 Flutter Application,并且主要逻辑都由 Flutter 实现。

纯 Flutter 应用不是说不能使用 Native 技术,但大多数场景都需要使用 Native 技术来扩展 Flutter 的能力。主要有以下方式。

● 在 Flutter Application 下同时包含Android、iOS原生工程,这些工程都是传统的原生工程,可以按照原生思路进行开发,比如导入原生 SDK 进行初始化操作等。

● Native 与 Flutter 间可以通过 Channel 机制实现通信,Channel支持双向通信。

● 通过 Flutter Plugin 扩展,可以直接实现原生能力快速接入。

总结来说,纯 Flutter 应用是以 Flutter 代码为主体,以 Native 功能为扩展的开发方式。通过与下文的混合开发做比对,能够更好地理解两者的差异。

纯 Flutter 应用是 Google Flutter 官方所支持的开发方式,能够做到开箱即用,稳定性也最有保障。

当立项一个新项目的时候,如果该项目对显存的 Native 项目代码依赖比较少,或者现有 Native 项目可以方便地封装为 Flutter Plugin 进行扩展,建议选用纯 Flutter 方式开发,能够具备远高于原生的开发效率。

混合开发

对于大多数已有的商业项目,大量业务和基础设施都由 Native 实现,全部迁移 Flutter 成本过高,此时会选择进行混合开发。

在混合开发中,Native 业务为主体,Flutter 业务更类似于”WebView“,作为相对独立的二级子模块使用。

混合开发就需要一个像“WebView”一样的 Flutter 容器进行承载。Flutter 官方对混合开发的支持力度较弱,无法满足复杂的业务场景。

业界推出了多种混合路由框架来填补这一短板,比较知名的是咸鱼推出的 Flutter Boost 框架。混合路由框架通过对 Flutter 容器栈和 Flutter Navigator 页面栈的统一维护,打通了原生应用与 Flutter 模块间的混合跳转路径,使得开发者可以像WebView一样使用 Flutter 容器。

即便有了混合路由,在混合场景下进行开发的难度相较于纯 Flutter 应用开发也要难一些,尤其是在大型的商业项目中。难点主要体现在与现有 Native 架构融合,以及性能稳定性优化方面,这部分会在下文讲 Flutter 的“坑”中进行介绍。

总结来说,对于已有的商业项目想要落地 Flutter,只能选择混合开发的方式。混合开发需要引入或者研发混合路由框架,会对 Flutter 的 Embedder层原有逻辑做一些调整,因此适配难度会加大。

3

Flutter的“坑”

笔者在最近一年里负责完成了一系列大型商业项目混合开发的从 0 到 1,并负责搭建了部门的 Flutter 技术体系,从最初试水到现在大规模业务落地,这期间积累了大量经验,也摸清了 Flutter 的“脾气”。

对于技术管理者来说,对 Flutter 这门技术的先进性大家普遍都是认可的,最担心的还是它的落地风险。

对于一门新技术,其风险来自几个方面。

能否创造商业价值:在商业项目中,技术不是越新越好,而是要能够产出商业价值,为业务服务。由于 Android 和iOS生态差异性,同一个功能需要多次开发,开发效率问题长久以来都是移动端开发的痛点。经过笔者探索和验证,纯移动端背景的同学首次上手 Flutter 就能够带来开发效率提升,并且熟练度和后续低维护成本也有助于提升开发效率。

上手难度:Flutter 开发方式与移动端开发不同,如何能够快速上手 Flutter 呢?Flutter 自成一套体系,尽管采用易于学习的 Dart 语言和组件声明式框架,但仍具备一定的学习成本。笔者编写的《Flutter 开发实例解析》一书,就是根据笔者长期以来的 Flutter 商业项目实战经验总结而成,其特色是不仅讲基础,也讲如何对 Flutter 项目进行高质量的架构设计,精选了大家最需要的部分,同时辅以大量完整实例项目,手把手带领读者进行实践,实现快速上手。

稳定性:稳定性是管理者最关心的方面,即使技术再好,如果上线不稳定,也会造成一种骑虎难下的困境。稳定性又可以细分为两个方面。

技术自身成熟度:Flutter经过多年发展,自身已经十分成熟。对于纯 Flutter 应用开发来说,Flutter 可以作为开箱即用的方案,稳定性是有保障的。对于混合开发来说,知名的混合路由框架经过多年打磨,也已比较完善。但是混合开发由于其自身的复杂性,稳定性也取决于原生架构与 Flutter 引擎、混合路由框架的融合程度。同时对于混合开发来说,由于原生业务已经有一定的性能、内存开销,引入 Flutter 后会提高内存水位,需要经过打磨、调优才能达到最佳状态。

技术团队底层架构能力:对于纯 Flutter 应用开发来说,基于 Flutter 团队成熟的技术方案,一般只需要关注业务开发即可。但对于混合开发来说,Flutter 不是一个开箱即用的方案,需要团队对 Flutter 的底层原理、混合路由原理、外接纹理,以及自身 Native 业务框架都了解透彻,才能够进行较好融合。如果融合不好,会遇到一些 Crash、OOM 等问题。因此,混合开发更加考验技术团队的底层架构能力。

尽管混合开发有一定难度,但还是可行的,从各个大厂都已经大规模落地实践中就能够证明。同时笔者负责的多个商业项目都采用混合开发,并且大规模全量落地,在稳定性和体验上与之前能够保持持平。

未来发展:每年都有大量的新技术诞生,作为有经验的管理者,在采用新技术时都比较慎重,会考虑其未来的发展潜力。

项目的生命周期:很多项目官方推出时声势浩大,可没过一两年就不维护了,进入一种“弃坑”状态,Flutter 会不会弃坑呢?从目前 Google 对 Flutter 的定位和火热程度上来看,概率是极低的。Flutter 是作为 Fuchsia 的 GUI 开发框架被提出的,Fuchsia 则是 Google 开发中的下一代操作系统。不论是 Flutter 在移动端提前开花结果,Fuchsia 的稳步推进,还是 Flutter 对 Web、Desktop 的泛跨端支持,都表明这项技术还处在早期的蓬勃发展阶段,在未来的 3~5 年内都会保持高速发展。

等一等会不会有更好的?Flutter 是吸取前人的经验的基础上进行了突破,会不会再有新框架吸取 Flutter 进行突破呢?如果有,再等一等岂不是更好?回答这个需要回顾前问对 Flutter 的介绍,Flutter为了实现综合突破,引入了 Dart 语言、Skia渲染引擎,并自研了一套类 React 组件声明式框架,同时还包括一整套完善的开发、调试环境。这种强大的工程能力不是一般公司能够比拟的。笔者之前也作为核心作者自研了一套跨端框架,深知其中的难度。Flutter 将跨端技术推向了一个新的高度,不排除全球互联网巨头会推出更先进的框架,但难度已经越来越大。

4

It's time for Flutter

准备好了吗?It's time for Flutter!

今年随着 Flutter 2.0 的推出,Flutter正式迈向成熟。在 Flutter 2.2 中又推出了新的多引擎概念,新增一个引擎内存开销只有 180KB,可谓消除了混合开发中最大的难点。

在 Flutter 1.x 时代,运行 Flutter 还需要饱受框架 Bug 的折磨,比如一个著名的梗是说 Flutter 的官方 Repo 里有 1w 个 issue 没有关。对于混合开发来说,最为头疼的是多个 Flutter 容器如何复用底层一个Window,通过 Flutter Surface 残影的方式实现两个 Flutter 容器间的过场切换。

这些问题,在 Flutter 2.0 之后都得到了极大的改善。

同时,在 Flutter 1.x 时代落地的商业项目,所采用的老版本反而成了技术包袱。正所谓船大难掉头,好不容易落地 Flutter,大家目前都处于拿去商业收益的阶段,没有精力也没有动力升级 Flutter 2.0。而新落地的项目则没有这个负担,可以享受到更强、更稳定的 Flutter 引擎带来的好处。

Flutter for Web Release 发布,是 Flutter 2.0 的推出的一个亮点。在《Flutter开发实例解析》一书中,笔者为大家演示了如何一行代码都不修改,就能将一个原生应用跑在 Web 端和桌面端,并且具备完全一致的展示效果和使用体验。笔者在写作时使用的还是 Flutter 1.x,那时 Flutter for Web 仍处于Beta,就已经提供了良好的体验,在 Release 版中这项新特性真正具备了可落地的商业价值。