美团做 React Native 性能优化的三个关键点
在移动开发领域,React Native 无疑是一个非常热门的开发框架,其相比 Native 开发最大的差距体现在性能上,尤其在打开页面时会明显感到加载速度变慢。搭载 React Native 框架就不得不面对性能调优的问题,这也是令大多数开发者头疼的地方。
React Native 页面加载性能优化的最佳路径有哪些?有哪些“坑点”需要注意?跨平台开发流行的当下,技术框架选型上有哪些注意事项?带着这些问题,InfoQ 采访到美团移动端技术专家吴卓,他将分享团队在 React Native 性能优化实践层面的一些经验,以及对于技术框架选型的一些建议。此外,在 5 月 29-31 日 QCon 全球软件开发大会(北京站)2021 会议上,他也将分享相关的实践案例,为使用 React Native 的开发人员,提供相关的经验做参考。
以下为正文:
吴卓: 相比原生开发性能,React Native 最直观的差距体现在页面加载速度上,这也是我们一直在研究的重点。性能优化一般包括以下 3 个阶段:
建立衡量指标
提供优化手段
运营推动治理
在加载性能指标方面,我们重点关注秒开率、页面加载时长两个指标,其中秒开率是用户视角下的结果指标,而页面加载时长是框架层面优化下的重要过程指标。在优化手段方面,我们侧重于从 Native 侧进行优化,提供优化的手段多达二十余种,在业务层、框架层、React Native 层、引擎层均有优化工作。在运营推动方面,因为框架团队和业务团队分属不同部门,框架团队不可能直接给业务团队下指标去完成任务,这时候更多靠运营手段进行推动,包括建立标准值、跨业务横向对比,以此敦促业务去做性能优化。
吴卓: 我们在技术层面和非技术层面都遇到了不少挑战,下面从这两个角度出发列举两条:
技术层面的挑战: 最开始我们从框架层以操作前置为主要思路进行优化,将很多耗时的操作放在进入页面前执行,但是最终呈现出来的效果却有限。后来我们不断深入进行 React Native 及 JS 引擎底层研发,由此研究出了一些帮助业务进一步提升页面加载性能的“黑科技”,这部分我将会在 【QCon 全球软件开发大会(北京站)2021- 移动新生态趋势下的应用实践】 专场上给大家分享。
非技术层面的挑战: 除了技术上的难点,业务间的协同和管控也是个令人头疼的问题。美团 App 上有很多业务都在使用 React Native,但我们可提供的一些优化方案需要占用额外资源,比如:启动时下载、引擎保活池等,所以我们设计了很多规范标准,根据页面流量、效果收益去分配这些公共资源;同时,我们还通过架构设计、检测工具去感知业务的使用情况,避免业务不合理地使用某些优化手段。
吴卓: 印象最深刻的还是我们第一次进行 React Native 大版本升级——横跨了 6 个 React Native 的大版本。因为美团上有大量业务在使用 React Native,所以我们需要推动所有业务共计几百个 React Native 的页面配合做升级适配,其中难度可想而知。现在回想起来,确实做了件轰动全公司的事情,当时心里还是很慌的,团队都做好了低绩效的准备。不过,皇天不负有心人,最终推动完成了升级,取得了一个胜利。后来我们也研究出了兼容升级的方案,让业务能够平滑升级。
吴卓:我们一直在关注 React Native 大重构的进展,包括 TurboModules 和 Fabric,相信等到 React Native 完成重构后性能可以再上一个台阶。到时候,React Native 的大版本升级又是个难题,这需要提前布局做准备。
如果其他团队也想实践,首先可以给大家一些信心,App、流程、页面级别的 React Native 化,我们已经有稳定的实践,可放心使用;再者,使用优化手段的技术实现,是很容易复制的。但是对于大型项目而言,还是需要根据各自的业务场景、以及公司环境状况制定合适的落地推进计划。
吴卓:框架的技术选型源于业务背景。 回到 2018 年立项之初,美团 App 包大小治理已经迫在眉睫,由于业务不断增长,从客户端层面出发的传统优化手段(如:资源压缩、重复代码清理等)已经赶不上业务增加的代码速度,必须采用动态化的方案进行解决。
React Native 的开源社区最为广泛,且业内已经有较多成熟的实践,在需要大规模使用的前提下我们预判使用 React Native 的成功性最大,当然数年之后的结果确实印证了当时选择的正确性。
而 Flutter 在 2018 年刚推出,在 iOS 侧还并不具备动态化能力,并且业内大规模使用的验证较少,所以不会贸然去选择 Flutter。当然,目前 Flutter 框架在公司内也有团队在使用,我们也在密切关注 Flutter 的发展。
吴卓: 这些对比抽象来看,更多从开发者的角度出发对框架的易用性进行的对比。不得不承认,Flutter 作为后进者很多方面做的不错,但我认为这些优劣还不足以决定技术选型。
我们在使用这些开源框架时,一定是对应去解决业务上遇到的问题和挑战。当这些开源框架进入公司里应用并落地时,还需要根据业务的实际情况,基于开源的工具做进一步的建设和调整。一个选型方法论就是,在公司应用落地时,优先考虑的应是框架能否解决实际问题,其次才是框架的成熟度、应用情况、技术天花板是否值得长期押注在这个框架上。
吴卓: 开发框架的选型最终还是要回归到业务场景上。跨平台开发框架的常见收益点包括:动态化能力、跨平台复用提效、技术栈统一等方面。我列举两个例子:
为了协调不同业务的开发,美团 App 划定了发版窗口,对业务而言发布效率成了业务的痛点,因此就有了动态化的诉求;倘若是一个自行掌控的 App,能够随时提审随时发布,动态化的诉求可能没那么高。
再比如公司内有些手持 PDA 设备,属于特别低端的 Android 机器。有的团队不考虑跨平台框架,一是没有 iOS 端的需求,二是设备性能较差,三是设备自带的更新机制比现有 React Native 基建的动态化效果更好。但有的团队仍然选择了跨平台框架,原因是短期内技术栈储备不够,只能先用团队最熟悉的 JS 进行需求开发,等人力补充到位后再视情况调整。
所以,在做技术选型时,还是从业务场景的现状决定,没有绝对好或者不好的框架。
吴卓: 我认为不会。因为技术有最佳实践,但是没有银弹。从原理上跨平台做得好,一定是在其他方面有取舍,比如性能、动态化能力、开发语言难度等等。从业务场景出发,都会有各自最适合的框架。我并没有期待大一统的局面,更希望的是各个框架在各自场景下都能发展到极致。
吴卓:React Native 框架在业内使用较为频繁,下面列举几条必做的事情:
第一,虽然 React Native 使用前端语言开发,但是如果想让 React Native 发挥出更好的效用,则 需要客户端的同学一并参与维护。先前我们遇到的很多问题连调,光从前端 JS 层入手无法解决,需要深入到 Native 层进行排查。
第二,React Native 在 Android 侧健壮性稍差,直接使用 Crash 率会比较高,需要自行修改源码,增加异常处理、特殊系统适配等操作。
第三,Android 侧 JSC 引擎性能不太好,改善方法是 尽可能升级到新的 React Native 版本(0.60+),然后将默认的引擎替换掉。
吴卓: 我想这个问题每个人都有各自的见解,下面仅谈点个人经验。技术上的学习其实是个“T”型,中间的竖线代表深度,横线代表广度。我们需要优先专注于一个方向深入学习,比如:iOS、Android、FE 等等;当一个事情研究到足够深入的过程中,你会发现还有更多不知道的东西,需要你不断学习新的知识、拓宽看问题的广度。在前端、客户端领域,变化非常快,新框架层出不穷,个人建议是专注于某个方向做到足够深入,同时也需要保持对其他方向的持续学习和关注。
嘉宾介绍: 吴卓,美团移动端技术专家。2014 年加入美团,负责过酒店、机票、火⻋票业务客户端团队;目前是美团 React Native 项目负责人,负责美团内基于 React Native 的基础建设。
5 月 29-31 日,QCon 全球软件开发大会(北京站)2021——【移动新生态趋势下的应用实践】专题下的《美团 React Native 页面加载性能优化实践》将进一步解读 React Native 性能优化的更多实践内容。此外,本专题下还有快手 OOM 治理实践,网易有道、58 本地服务的 Flutter 落地实践探索跨端技术带来的新的可能性,以及便利蜂 React Native 多版本共存的平滑升级实践,更多移动端的精彩演讲可以点击 【阅读原文】查看。