转载请注明出处。请前往 Tiga on Tech 查看原文以及更多有趣的技术文章。
原文链接:https://medium.com/airbnb-engineering/building-a-cross-platform-mobile-team-3e1837b40a88
我们将在这个系列的 5 篇文章里,讲述 Airbnb 使用 React Native 进行移动端开发的历程,以及在放弃 React Native 之后的计划。这是这个系列文章的第 3 篇。
This is the third in a series of blog posts in which we outline our experience with React Native and what is next for mobile at Airbnb.
除了 React Native 在技术层面数不清的优缺点,我们也学到了很多 React Native 对于一个工程师团队组织的意义。相比在一个现在的平台上添加一个新的库或编码模式,采用 React Native 相对要复杂很多。这么做带来了很多团队组织上的挑战。和技术上的挑战不一样,技术问题通常能被解决,组织上的挑战更难被发现、纠正和恢复。庆幸的是,我们移动开发的文化很健康,但是在考虑使用 React Native 的时候,很多事情还是要注意的。
In addition to the countless technical pros and cons of React Native, we learned a ton about what React Native means for an engineering organization. Adopting it is much more complex than adding a new library or pattern to an existing platform. Doing so brought to light a number of organizational challenges. Unlike technical challenges which can often be solved or effectively worked around, organizational challenges can be harder to detect, correct for, and recover from. Thankfully, our mobile culture is healthy but there are a number of things to be aware of when considering React Native.
对 React Native 的态度两极分化
React Native is Polarizing
在我们的经验里,工程师们对 React Native 有很多不同的意见,从期待它成为统一 Android、iOS 和 web 的灵丹妙药,到极力反对在自己的团队里使用 React Native。同样的情况也发生在使用 React Native 之后。一些团队有极佳的使用体验,另一些团队后悔使用它,并且又转回使用原生开发。
In our experience, engineers approached React Native with wildly different opinions varying from praising it as a silver bullet that united Android, iOS, and web to being wholly against any use of React Native on their team. The same situation occurred after using it as well. Some teams had an incredible experience while others regretted it and reverted back to native.
问题的归因
Root Cause Attribution
在使用React Native时,不可避免地会存在错误、完善和性能问题。但是,也有很多进步的地方:
- React Native 本身发展迅速。
- 我们同时做基础架构和产品功能开发。
- 工程师们一起学习 React Native,并且它对任何人而言都是相对新的。
- 我们关于开发和线上调试的文档和指引有时会不一致,也可能会造成混淆。While working on React Native, there were inevitable bugs, polish, and performance issues. However, there were many moving pieces:
React Native itself moves quickly. We were doing simultaneous infrastructure and feature development. Engineers were learning React Native together and it was relatively new for everybody. Our documentation and guidance for debugging in development and production was inconsistent at times and could be confusing.
结果是,找到一个问题的根本原因很困难。有时候,一个问题应该归因给哪个团队、或者这个问题是不是 React Native 固有的不是很清晰。
As a result, it was often difficult to find the root cause of a problem. Sometimes, it wasn’t clear which team an issue should be attributed or whether the issue was inherent to React Native.
React Native 终究还是原生的
React Native is Still Native
对 React Native 一个普遍的误解是,它可以让你完全避免写原生代码。然而,现实并不是这样的。React Native 的原生框架有时候还是会出现一些问题。比如,每个平台上文本的渲染略有不同,键盘的事件的处理也不一样,Android 上的 Activity 在屏幕旋转时会默认被重建。高质量的 React Native 体验要求在两个平台上有很好的平衡。再加上要平衡三个平台的问题,使得保持一个高质量的开发体验变得很困难。
A common misconception is that React Native allows you to move away from writing native code entirely. However, that is not the current state of the world. The native foundation of React Native still rears its head at times. For example, text is rendered slightly differently on each platform, keyboards are handled differently, and Activities are recreated on rotation by default on Android. A high-quality React Native experience requires a careful balance of both worlds. This, paired with the difficulty of having balanced expertise on all three platforms makes shipping a consistently high-quality experience difficult.
跨平台调试
Debugging Across Platforms
大部分工程师都只精通一个或两个平台。要想同时胜任 Android、iOS 和 React 是很困难的。在一个成熟的 React Native 坏境下,尽管大部分的开发工作都是通过 JavaScript 和 React 完成的,但在构建或 debug 的时候,有时候仍然需要深挖到原生系统里。这种情况会导致工程师在一个他们从没使用过的平台上调试一个问题的时候陷入困境。甚至有的时候,假如问题的根本原因很难归因的时候,工程师根本不知道看哪里去找问题,问题就更糟了。
Most engineers are proficient at one or two platforms. It is exceedingly rare for somebody to be highly competent in Android, iOS, and React. Even though the vast majority of work in a mature React Native environment is done with JavaScript and React, there are times when building or debugging something requires digging into native. These situations can lead to engineers getting stuck way out of their expertise trying to debug an issue on a platform they have never used. This is made worse when an engineer isn’t even sure where to look due to the difficulty of root cause attribution.
App 混合开发很难
Hybrid Apps Are Hard
一个 100% 原生或 100% React Native 的 App 发展之路是相对直接明了的。然而,一旦你的代码里同时混合了两者,很多新的问题就出现了。你怎样拆分你的团队呢?团队之间如何合作呢?你怎样在 App 之间共享状态呢?你怎样保证开发出来的东西被测试了呢?工程师们如何高效地在三个不同平台之间调试呢?开发一个新 feature 的时候,你怎样决定使用哪种技术呢?在整个组织之间,你怎样招聘人才和分配资源呢?假如你继续深入走混合开发的道路,这些问题都是不可避免的,而且解决起来也不是容易的。
The path of a world that is 100% native or 100% React Native is relatively straightforward. However, once you have a mix within your codebase, many new issues arise. How do you split up your teams? How do teams collaborate? How do you share state across your app? How do you ensure that things get tested? How do engineers effectively debug across three platforms? How do you decide what platform to use for a new feature? How do you hire and allocate resources across your organization? These are all problems with non-trivial solutions that will inevitably arise if you go down this path.
三个开发环境
Three Development Environments
为了成为一个高效的 React Native 工程师,拥有稳定且保持更新的 React Native、Android 和 iOS 开发环境是很重要的。对于一个像 Airbnb 这样庞大的公司,每个平台的环境都需要很多的时间去配置、学习和保持更新。离开几个星期后再回来,通常意味着需要花费几个小时去把环境更新到最新。
In order to be an effective React Native engineer, it is important to have a stable and up-to-date React Native, Android, and iOS environment. For an organization as large as Airbnb, each platform requires a significant amount of time to set up, learn, and keep up to date. Returning after just a few weeks often meant spending several hours getting everything back up to date.
平衡原生和 React Native
Balancing Native vs React Native
很多情况下,问题的最佳解决方案是跨原生和 React Native 的。比如,页面之间的导航重度使用了 Android 的 Activities 和 iOS 的 ViewControllers,这部分代码很多是平台原生的。很多时候,代码应该写成原生的或者 React Native 的是很不清晰的。这种时候,工程师可能自然而然地就会选择使他们更舒适的技术去实现,这可能就会导致一个并不理想的实现方案。
There are many situations in which the optimal solution for a problem spans native and React Native. For example, our navigation implementation makes heavy use of Activities and ViewControllers and most of its code is native to each platform. Often times, it is not clear whether code should be written in native or React Native. Naturally, an engineer will often choose the platform that they are more comfortable which can lead to unideal code.
跨平台测试
Cross-Platform Testing
我们发现,为了方便或者舒适,工程师们主要在一个平台上进行开发。他们通常假设代码只要在他们所测试的那个平台上正常运行,在别的平台上就也会没问题。这在大多数情况下是对的,也证明了 React Native 的强大。然而,情况并不总是这样,这就会导致在 QA 测试周期的末期或者在发布后频繁出现问题。
We found that engineers would primarily develop on one platform over the other due to convenience or comfort. Often, they would assume that if it works on the platform they tested on, it would work perfectly on the other. Most of the time, this was true which is a testament to the power of React Native. However, it was untrue often enough that it ended up causing frequent issues late in QA cycles or in production.
团队拆分
Split Teams
同时在原生和 React Native 上进行开发的团队经常会遇到技术和沟通上的挑战。一旦代码把原生代码和 React Native 拆分开,代码就会变得碎片化。共享业务逻辑、数据模型、状态等等,变得很有挑战性,工程师们不再具有在整个流程中工作的专业性。我们一开始就知道这种情况会发生,但我们当时认为可以通过和 Web 段加强合作来平衡。一些团队确实开始在 Web 和移动端共享资源和代码,但很多团队没法意识到这样做的潜在收益。
Teams that worked in native as well as React Native often faced both technical and communication challenges. Once the codebase was split between native and React Native, the code became fragmented. Sharing business logic, models, state, etc. became more challenging and engineers no longer had the expertise to work across the entire flow. We knew that this would happen from the get-go but thought that this might be balanced by an increased collaboration with web. A few teams did start to share resources and code across web and mobile but most weren’t able to realize this potential benefit.
感知的迭代速度
Perceived Iteration Speed
我们使用 React Native 的其中一个定性目标是提高开发的速度。通常来说,React Native 的工作是由一个工程师开发的,而不是每个平台一个。从一个 React Native 工程师的角度来讲,如果使用 React Native 开发一个功能比他们用 Android 或 iOS 要多花 50% 的时间,尽管总体上是少花了时间,但他们也会觉得是多花了时间。
One of our qualitative goals with React Native was to increase development speed. Often, React Native features were written by a single engineer instead of one for each platform. From the perspective of a React Native engineer, if it takes them 50% longer to write their feature than it would on Android or iOS, it feels longer to them even if it takes fewer hours overall.
公共资源和文档
Public Resources and Documentation
Android 和 iOS 已经发展了 10 年以上,并且有数百万工程师贡献很多学习资源,开源项目和在线帮助。我们利用了很多这些资源,比如 CodePath,去帮助大家学习 Android 和 iOS。尽管 React Native 拥有最大的跨平台社区,并且能够利用 React 资源,它相比 Android 和 iOS 还是要小很多。加上我们必须自己构建很多基础设施,这意味着与原生相比,我们在有限的 React Native 资源上投入了过多的培训。
Android and iOS have had ten years and millions of engineers contributing to learning resources, open source, and online help. We leverage many resources such as CodePath to help people learn Android and iOS. Even though React Native has one of the largest cross-platform communities and can leverage React resources, it is still much smaller than Android and iOS. That paired with the fact that we had to build most of our infrastructure in-house meant that our limited React Native resources were over-invested in education and training relative to native.
这是这个系列文章的第三部分,这个系列重点讲述了 React Native 在 Airbnb 的历程,以及 Airbnb 在此后的计划。
This is part three in a series of blog posts highlighting our experiences with React Native and what’s next for mobile at Airbnb.