Categories
程式開發

西瓜视频落地 Flutter,给你的避坑指南


Flutter 是目前最火的跨平台技术,在提供极好的用户体验的同时能解决多端一致性的问题,而且还能有效地降低人力成本。在谷歌正式发布 Flutter 之后,各大厂纷纷布局并逐步落地,国内大厂像阿里巴巴、字节跳动、美团等已经走在了 Flutter 队伍的前列,比起怎么引入 Flutter,现在大家更关心的是 Flutter 的进展和踩坑经历。

在将于 11 月 24-25 日 GMTC 全球大前端技术大会上,字节跳动资深工程师、西瓜视频 Flutter 团队负责人徐东老师将分享《西瓜视频 Flutter 落地经验》,InfoQ 在会前采访了徐东老师。在近百人的研发团队落地这样一个”颠覆性”的技术,西瓜视频在落地 Flutter 的过程中有哪些踩坑经验?Flutter 未来有会有怎样的发展?我们一起来看看。

以下为采访正文:

InfoQ:请介绍下你自己。

徐东: 我在 2011 年的时候加入了一家创业公司做 Android 开发,第二年,公司唯一的 iOS 工程师离开了,所以我又开始做 iOS 开发,曾经有大半年时间我一个人同时负责 Android 和 iOS 开发,这家公司和产品名字都叫下厨房,现在应该是国内美食领域最受人欢迎的应用了。在下厨房大部分时间都在负责两端的整体开发工作,所以整个开发流程的上上下下都接触到了,比如打包、提审、审核申诉甚至申请邓白氏码、和应用商店谈首发这种事情都要自己想办法搞。在小团队待过的人应该会有这种体验,在创业公司虽然做的事情很杂,但也养成了一个工作习惯:站在团队角度看问题,什么能够帮助团队就去做什么。

2015 年的时候,我加入了字节跳动,参与的第一个项目是时光相册,不知道大家还记不记得 2016 年底“你的名字”同款滤镜?那个就是时光相册团队做的,后来到 2017 年 9 月调到西瓜视频业务负责 iOS 客户端团队,当时西瓜团队还打造了一个爆款产品:百万英雄。再后来,到 2019 年我开始关注 Flutter 技术,非常认可这项技术未来在端上的潜力,所以现在专门组建了一个团队在全职推动 Flutter 技术在西瓜视频以及全公司范围的落地。

InfoQ:西瓜视频是在什么契机下,引入 Flutter 的?

徐东: 我第一次听说 Flutter 是在 2018 年,当时只是简单的了解了一下原理,并没有太深入其中,后来我们团队内部在做年度计划的时候,有个话题是如何提升客户端开发效率,当时了解到我司基础技术团队已经在头条落地了一些 Flutter 页面,效果还不错,效率确实有提升,另外 Flutter 选择了自带渲染引擎的方案,这在性能和多端一致性上确实是个非常大的优势。

跨端技术选型要注意

InfoQ:你认为跨端技术选型应该思考哪些点?

徐东: 在一个规模比较大的团队选择跨端技术还是要谨慎些,尤其是在你希望团队大规模应用的情况下,其实是很颠覆现有开发模式的,我觉得以下几点还是需要好好思考一下:

1.这个技术的理论上限是否和原生足够接近?

一个跨端技术如果仅仅只是能够跨端,性能很一般、开发体验很一般,那么很有可能没法落地,因为跨端技术想落地对团队现有工作方式冲击还是很大的,这也是一个不可忽视的成本,除非性能几乎和原生一样,能够让人感觉“真香”,否则真的很难有人买账。

2.团队技术储备是否能铺平道路、抵御风险?

Android 和 iOS 原生开发已经发展了十多年了。整个生态和基础都比较成熟,而各种跨端技术相对来讲还都比较年轻,有很多不完善的地方,团队需要有足够的技术储备来解决各种问题,否则可能不仅没提升效率,还拖慢了效率。

3.团队希望在多大范围内使用跨端技术?

如果你的产品人员偏向于将 Android 和 iOS 客户端体验设计成两种 UI,或者你的应用大部分都是图像和视频编辑之类的功能,那恐怕只能思考一下底层逻辑能不能用 C/C++ 跨端了。但如果你的应用是偏展示型的,则非常适合选择一些 UI 跨端的技术,像 Flutter 之类的。

Flutter 落地中遇到的问题

西瓜视频在引入 Flutter 的过程中发现了很多问题,如:Android 系统字体问题、iOS 原生手势和 Flutter 内部手势冲突问题,以及状态管理,在遇到这些问题之后沉淀了一些自己的解决方案。

InfoQ:在引入 Flutter 的过程中遇到了哪些问题?又是如何去解决的?

徐东:Android 系统字体问题:很多系统厂家支持用户自定义字体,但是 Flutter 默认没法加载用户自定义字体,这会导致原生页面和 Flutter 页面使用的字体不一致,降低用户体验,这方面西瓜已经有了解决方案,会在 GMTC 上和大家分享。

iOS 原生手势和 Flutter 内部手势冲突问题:iOS 原生手势处理的优先级比 Flutter 的手势高,所以一旦在 FlutterViewController 上添加了 iOS 手势,那么就可能会导致 Flutter 内的手势失效。为了解决这个问题,我们开发了一个 FlutterView 代理手势识别器,他可以“平等地”和 iOS 原生手势沟通协作,这样我们就能够利用 iOS 原生手势系统的规则,来解决 Flutter 和 iOS 的手势冲突问题。

状态管理问题: 复杂控件可能有非常多的状态变量和逻辑,如果用单一 StatefullWidget 会导致代码爆炸,拆分多个 StatefullWidget 又会有信息共享难的问题。西瓜目前开发了一套 Redux 库来解决,主要特点是:

  • 通过 source_gen 和 build_runner 自动生成 State/Store,避免了手写 equals、hashCode、constructor 方法。
  • 架构简单,避免过多概念,只包含最基础的 Store、State、Reducer、Action、Listener,我们相信“少即是多”,如果开发者对业务逻辑足够了解,这些简单的组件就足够了。
  • Store 中保存了一棵 State 树,树上的任意一个状态变量都可以单独设置监听器,这样可以避免大面积重绘。

引入 Flutter 后, 人效基本能提升 50%

InfoQ:引入 Flutter 之后的团队现状如何?实现 Flutter 播放器方案需要注意哪些点?

徐东: 目前西瓜 App 内有三十个左右页面使用 Flutter 开发,我们的一个面向作者的业务线基本上都是用 Flutter 开发的,人效基本能提升 50%。

目前看,在 Flutter 环境下实现播放器主要有两个方案:一种是 Platform View,一种是外接纹理的方案。Platform View 方案需要依赖原生 View,两端使用不同的方式实现 UI,我个人认为这就失去了使用 Flutter 的意义,所以西瓜实现的播放器使用的是外接纹理方案:简单来说就是底层使用原生播放器库生成纹理,然后将纹理给 Flutter 引擎渲染。在播放器落地的过程中我们遇到了几个需要注意的细节问题:

  • 目前 Flutter 外接纹理需要原生侧提供 RGBA 的纹理供 Skia 渲染,RGBA 会比 YUV 使用更多的内存,如果你对内存用量非常敏感,那就需要特别注意考虑其他方案了。
  • iOS 外接纹理需要实现 copyPixelbuffer 方法,将 CVPixelbufferRef 引用计数加 1 后传递给 Flutter 引擎,正常情况下引擎会为这个 Pixelbuffer 的引用计数减 1,这就保证了 Pixelbuffer 不会被泄漏,但是如果你的 copyPixelbuffer 连续几次调用返回同一个 Pixelbuffer, 并且每次引用计数都增加了,那么这个 Pixelbuffer 会被泄漏,因为引擎遇到相同的 Pixelbuffer 并不会多次减少引用计数。可以在发现连续生成相同的 Pixelbuffer 时,copyPixelbuffer 应该返回 NULL。

未来,理论上能够做到媲美原生

InfoQ:你怎么看待 Flutter 未来的技术趋势?

徐东: 我个人认为 Flutter 的天花板比较高,理论上能够做到媲美原生,所以我对 Flutter 的未来还是有很高的期待的,当然 Flutter 现在还是有一些问题需要解决的:

  • 一些 UI 细节还是相对原生有差距,比如我们团队就遇到过文字垂直方向经常对不齐、中英文混合省略也有问题、图片视频缩放后的锯齿阶梯感比较明显等不少细节问题,当然这些问题都是能够被解决并且付出一次性成本就可以的。
  • 开发体验还是有待完善,我们的工程师反馈的最多的问题是跨端的调试体验很差,虽然写在这里,但我并不认为这完全是 Flutter 的问题,而是跨端开发这个最核心理念引发的问题。所谓跨端开发我们对它的预期肯定是一个工程师干一份活在两端上线,就像前端工程师一样,这个理念一直以来都是非常吸引移动端工程师的,但是如果你去问实际做开发的工程师开发体验如何,他多半会说:“Flutter 本身写起来挺好挺快的,但是调试不熟悉的那一端实在是太扎心了,我要花比平时多一半甚至一倍的时间才能完成一样的需求”。但是团队管理者说:“一个人花的时间少于两倍,那么在团队效率角度看就是赚的”,所以现在的 Flutter 推广的现状是“对团队有帮助,对个人提高了要求”,现在的工程师必须得同时了解三端才能很顺利地开发 Flutter,如果是混编工程,还要熟悉两端原生工程的内容,这个成本通常也不低。解决这个问题可能有两个方向:一是加强团队成员的基础素质,向着一人熟悉三端的水平前进,这其实也并不是不可能,但确实很难。二是想办法让工程师不需要关心原生工程和技术,比如我司正在做的“Flutterw 套件 + 统一开发流程”屏蔽多端多业务的差异、以及容器化屏蔽底层差异、统一应用侧接口,减少 Platform Channel 开发,还有 Flutter 团队也在尝试的 Pigeon 简化 Channel 开发都是在这个方向努力。

嘉宾介绍

徐东,2011 年加入下厨房科技有限公司,负责客户端团队,2015 年加入字节跳动,先后负责过时光相册 iOS 团队、西瓜视频 iOS 团队,曾带领团队负责 2018 年百万英雄答题活动在字节跳动各个业务线的落地,多年客户端开发老兵,目前专注于西瓜视频 Flutter 技术落地工作,主要研究方向包括 Flutter 视频播放器、客户端团队效率量化。

关于 Flutter 的落地实践与未来趋势,阿里、字节跳动、美团以及快手均将在 GMTC 全球大前端技术大会上给出自己的实践与看法,更多实践案例可以关注大会“Flutter 实战“技术专场。