注册

一兜糖 APP :用 Flutter 链接关于家的一切

一兜糖家居,成立于2009年,2015年获得腾讯系战略投资,截至2020年平台已累积3000万装修用户、5万设计师和10万经销商。自成立以来,我们通过「找灵感——学知识——做决策」全路径的优质内容输出,帮助用户提高消费决策的效率;通过门店线上化、口碑线上化和获客线上化,帮助品牌全面种草;通过内容、社群及用户资源,全面释放设计师价值,帮助设计师提高选品及获客效率。通过链接关于家的一切,我们希望让家变得有温度。



说重点


一兜糖 APP 在 2020 年开始尝试使用 Flutter 重构 iOS / Android 应用,使用 4 个月时间逐步迁移至 Flutter 工作流上。然后又使用一个月的时间,将 H5 以及微信小程序迁移到 MPFlutter 上。\


在重构完成后,一兜糖仅使用一套代码,便完成了在 iOS / Android / H5 / 微信小程序四端的部署,提升近四倍开发效率。


本文将与您分享一兜糖在重构过程中遇到的问题和解决方案。


一兜糖 APP 重构前的问题


2015 年,一兜糖家居开始发行 Android / iOS 两个平台的 APP,经过五年多的打磨,APP 内容日渐丰富,风格也越来越贴近用户使用习惯。直至 2020 年 4 月份,一兜糖家居 APP 均采用原生(Swift / Java)开发的方式进行,随着业务的快速增长以及五年多的技术迭代,面临的问题也越来越多。



  • Android / iOS 两个平台开发进度不统一,实现效果差异性较大,随着业务需求的累积,差异越来越大。
  • 项目日常维护开发所需人力越来越多,开发成本越来越高,Android / iOS 需要开发人员分别进行开发,同一个功能需要双倍的工作量来完成,如果把 H5 / 小程序涵括在内,同一个功能甚至需要四倍的工作量。
  • 将近五年的技术变更,冗余代码越来越多,导致项目的编译时长越来越长,往往一个小小的变动,都要经过漫长的等待时间后才能看到改动后的效果。

为了解决以上问题,2020 年 4 月,一兜糖 APP 开发团队决定对 APP 进行重构,希望重构能够实现快速开发,减少两个平台的差异等问题。而此时,市面上 APP 开发方案除了原生开发,跨平台方案也已经相对成熟,使用哪种技术重构 APP 成为一兜糖移动团队需要面临的第一个抉择。


原生 VS 跨平台


原生开发的方式,两个平台的开发人员分别进行开发,可以以一种很高效的方式调度系统资源,性能更加优秀。缺点也很明显:



  • 同一个业务却需要对两个平台分别进行开发,增加开发成本,业务代码无法在两个平台上复用。
  • 重构时间只有短短的两个月,如果要以原生的方式对 APP 进行整体重构,不现实,人力不足也会增加重构失败的风险。
  • 两个平台的差异性大,无法给不同平台的用户提供一致的使用体验。
  • 原生开发的方式,需要分别开发相应的需求,后续的测试流程,也需要测试人员分别对相应平台进行测试,增加测试成本。

而跨平台方案则完美解决了以上问题,一兜糖 APP 开发团队尝试使用 Flutter 跨平台方案重构 APP。


为什么选择 Flutter


市面上跨平方技术方案除 Flutter 之外,还有多种其他技术,为何最终定型 Flutter 呢?团队主要从以下几点考虑。


节省人力


跨平台方案能够有效减少适配多个平台所带来的工作量,提高业务代码的复用率,原本需要两个平台开发人员一起开发的工作,现在只需要投入一半的人力即可完成需求。同样是跨平台方案,React Native 则需要投入更多的精力用于 UI 兼容等琐碎的事项。


性能上限


相比其他跨平台方案,Flutter 通过 Skia 引擎渲染 UI 视图,这种渲染方式其性能上限非常接近原生。也因为 Flutter 的自绘引擎设计,跨平台 UI 一致性得以保证,因 iOS / Android 系统升级而导致的适配问题更少,可维护性更高,开发人员也可以更专注于业务开发而无需担心平台兼容问题。


声明式 UI


有别于命令式编程,Flutter 使用声明式 UI 设计。使用声明式 UI,开发人员只需要描述当前的 UI 状态,无须关注不同 UI 状态之间的转换,状态转换的相关逻辑则交由 Flutter 框架处理。这无疑提高了开发人员的效率,开发人员可以更加专注于页面的结构。


热重载


在调试模式下,Flutter 支持运行时编译即热重载功能。热重载模块首先扫描工程中发生改动的文件,接着将发生变化的 Dart 代码编译转化为 Dart Kernel 文件,然后将增量的 Dart Kernel 文件发送给 Dart VM,Dart VM 则将接收到的增量文件与原本的 Dart Kernel 文件合并,重新加载合并后的 Dart Kernel 文件,最后在确认 Dart VM 资源加载成功后,重置 UI 线程,完成 Widget 的重建工作。


热重载对于页面的改动,无需重新启动 APP 即可呈现。可以保存页面的视图状态,对于一些在页面栈很深情况,无需为恢复视图栈而重复大量调试步骤,节省调试复杂交互界面的时间。


Flutter 生态


Flutter 开发社区生态活跃,开发中遇到的问题基本都可以在开发社区上找到解决方案。


开工大吉


我们按照以下步骤重构应用



  1. 统一中心思想,做好全员培训工作。
  2. 设计应用架构,以渐进式的方式过渡到 Flutter 工作流。
  3. 逐步重构,有计划地重构。
  4. 拆除旧有代码。

全员培训工作


在重构工作开始时,除 TL 外,团队成员均无 Flutter / Dart 开发经验。


重构工作的关键在于人,我们通过数次重要的会议,告知团队成员目前面临的困境,以及使用  Flutter 重构能为团队带来的收益,并鼓励团队成员尽快学习 Flutter / Dart,让成员感知该技术的便利性。


通过2~3周的学习,团队成员均已上手 Flutter,具备重构条件。


渐进式地过渡到 Flutter


一兜糖家居 APP 已经迭代了五年多,使用 Flutter 重构 APP 的时候,会面临另一个抉择:是以原生为主,Flutter 为辅还是以 Flutter 为主,原生为辅?


市面上大部分 APP 使用 Flutter 的过程中,都是小范围使用 Flutter,绝大部分功能以原生的方式实现,新功能则尝试使用 Flutter 进行开发。这样对 APP 的改动及影响会保持在一个很小的范围,然而这对于开发人员来说却不够友好,调试的时候,需要在原生模块和 Flutter 模块来回切换,比较麻烦;原生项目唤起 Flutter 页面时,也需要大量的资源支持,这同样不利于提升 APP 的性能。因此,一兜糖移动团队决定以 Flutter 为主,原生为辅 的方式重构 APP。


而对于 Android/iOS 这两个已经迭代了五年的原生项目,一下子舍弃原有的代码显然不太现实,我们先创建一个新的 Flutter 项目(ydt_flutter),将原本的两个原生项目(iOS / Android)迁移到新建的 ydt_flutter 项目目录下。


合并仓库 合并构建流程


完成这一步后,即可开始将功能从原生往 Flutter 的方向迁移了。但如果直接在 lib 目录下开发的话,会有以下几个问题:


开发阶段编译项目的时候,会将原生冗余的代码也编译进去,造成第一次编译项目时需要经过漫长的等待。


不利于项目的迁移,原本高度耦合的项目代码会对重构中的 Flutter 项目造成干扰,也导致调试链的增长。


因此,在将两个原生项目迁移到 ydt_flutter 下后,在该目录下又创建了一个 common 模块(纯 Flutter 项目),后续重构的工作全部放在该模块下进行。这样做的好处是可以区分出 Flutter 重构后的项目和原本的原生项目,还可以简化调试工作,降低了两个项目的耦合度。后续相应的业务模块完成后,返回原生项目将相关的业务代码移除即可,一步步的将项目迁移到 Flutter 上。



逐步重构,有计划地重构。


接下来,是开发团队使用 4 个月的时间,逐步以模块为单位,重构应用。\


我们的应用是内容平台应用,在重构的过程中也同时顺带地配合设计组的同事重新整理了 APP 的 UI 风格,统一整理出 ListItemWidget(列表类型的组件) & WaterfallItem(瀑布流类型的组件)。该 APP 最核心的场景是各类列表与内容详情页,我们可以通过 CustomScrollView 的方式,以搭积木的方法,拼接出所有页面。



CustomScrollView + ListItem + WaterfallItem


通过这种方式,配合 GraphQL 下发的数据,我们拼接出了一个完整的内容应用。在这个过程中,Flutter 的一切皆 Widget 的思想,为重构提供了非常大的便利。


拆除旧有代码


在完成重构以后,便是将原有的原生代码删除,直至拆除上面提到的渐进式架构。


收益


重构对开发团队来说是一件高风险高收益的事,重构过程需要对旧业务进行整理,不仅要填上遗留的暗坑,同时还要避免新坑出现。好处也显而易见,可以解决绝大部分原本令人头痛的问题。


借助 Flutter 的诸多优秀特性,四个月时间,一兜糖家居 APP 重构成功。经过将近一年的线上运营,APP 总体使用和用户反馈良好。借助 CustomScrollView + ListItem + Waterfall,有一些小需求甚至无需发版即可将新改动呈现在用户面前。


重构后的 APP 中 Flutter 覆盖场景超过 90%。Dart 语法对比原生开发所使用的开发语言,语法更加简洁,如 await & async 可以有效的避免原生开发中处处可见的回调地狱,代码逻辑更加清晰。这些新特性,帮助开发人员减少 40% 的日常业务开发时间,所需的人力成本也降为原来的一半,开发效率提升 50%。


因为 Flutter 跨平台的优越性,不仅可以缩短开发周期,后续的测试周期也可以相应缩短,只需编写一次 Flutter 的自动化测试用例,而无需分别对 Android/iOS 编写测试用例,测试效率提升的同时降低测试成本。不仅如此,APP 交付给 UI 设计师阶段,也可以大大节省设计师 UI 走查的时间,走查效率提升 50%。


使用 Flutter 开发后,各开发相关的流程所需成本都显著降低,流程也同步简化了不少。接下来,一兜糖移动开发团队将会致力于将 Flutter 覆盖 APP 中 95% 以上的场景。


额外收获


对于 H5 和 微信小程序,一兜糖团队也尝试使用 MPFlutter 进行重构、迁移。


MPFlutter 是一个跨平台的 Flutter 开发框架,致力于推广 Flutter 至官方未能涉足的领域,如微信小程序。


借助 MPFlutter,一兜糖只用了一个月时间,简单修改一些关键的节点代码,便将应用部署到 H5 和微信小程序中。


体验一兜糖应用


如果您对一兜糖的成果感兴趣,不妨现在就通过以下方式体验。



  • 在 AppStore 或各大安卓应用商店,搜索『一兜糖』下载应用。
  • 在微信搜索『一兜糖』体验小程序。
  • 点击 h5.yidoutang.com/v6/ ,体验一兜糖 H5 网站。

如果您正考虑如何装修新房,或者想知道屋主们的生活状态,欢迎持续使用一兜糖 APP。


作者:PonyCui
链接:https://juejin.cn/post/7039588712597946381
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录注册