Shopify:用React Native打造移动应用开发的未来

Shopify开发原生移动应用多年之后,我们决定完全转向React Native来构建所有新的移动应用。做出这个决定并非易事,下面我会做具体解释。

无论是哪个季度,大多数消费者都是在移动设备上下单的(去年第三季度,我们有71%的顾客通过移动设备下单)。黑色星期五(Black Friday)和电商星期一(Cyber Monday)(两者以下合称BFCM)是Shopify平台商家一年中最繁忙的日子,这期间消费活动最为活跃。在今年的BFCM中,Shopify商家在移动设备上的购买量又增加了3%,​​平均占销售额的69%

那么为什么要切换到React Native?为什么现在切换?这一变化是如何融入我们的原生移动开发流程的?答案很复杂,我在回答这些问题之前需要先交代一些背景情况。

Shopify在2019年之前的移动开发情况

Shopify的工程文化之一,是押注某些早期技术来帮助我们快速发展。

总体而言,我们更喜欢选择少数技术打造工程基础。这为我们提供了很多好处:

  • 我们在少数几种深度技术中建立了非常突出的专业能力(我们经常成为核心贡献者);
  • 每种技术选择都有其怪癖,但我们都能深度了解这些怪癖;
  • 非早期团队成员也能贡献、传递和维护他人编写的代码;
  • 新人上手更快。

与此同时,新技术层出不穷,为我们提供了逐渐提升生产力或能力的机会。我们做了很多尝试,找机会获得大幅度的改进——但到头来,我们在核心工程中很少采用这些改进。

当我们采用这些处于早期阶段的语言或框架时,我们就是在下经过计算的赌注。我们没有逃避风险,而是根据自身的一系列条件来精心研究、探索和评估此类风险。新技术的风险往往是隐藏其中的,与此类似,许多未开发的机遇也需要我们去探索。我们考虑的是该如何减轻这些风险的威胁:

  • 如果某项技术不再被其核心团队支持怎么办?
  • 如果遇到无法修复的错误该怎么办?
  • 如果产品的发展方向与我们的利益冲突怎么办?

当Tobi(我们的首席执行官)于2004年成为Ruby on Rails的核心贡献者时,Ruby on Rails还是一个年轻且难用的框架。过去很多年,Ruby on Rails都被视为一种不够严肃且性能不佳的语言。尽管它不是一种主流的技术选择,但早期阶段投下的赌注使Shopify拥有了超越竞争对手的能量。选择Ruby on Rails后,团队就可以使用比传统编程语言和框架更现代、更抽象的工具来更快地构建软件,并吸引众多不同领域的人才。Paul Graham也谈到了他决定使用Lisp构建Viaweb的决策,这一决策产生了类似的效果;另外,当今10家最有价值的Y Combinator孵化企业中有6家都在使用Ruby on Rails(不过要再说一遍,它还是很不受欢迎)。相比之下,前十大最有价值的Y Combinator孵化企业中没有一家在使用Java,而Java被广泛认为是久经沙场的企业级语言。

两年前Shopify又做出了类似的选择,决定转向Google Cloud。对于在2019年美国排行第三大的电子商务零售网站来说,这又是一项令人恐惧的提案——从我们自己的数据中心迁移到云已经是艰难的决定,而选择一家处于早期阶段的云提供商则同样危险。当时我们看到了产业价值链中的技术发展趋势,所以开始专注自己所擅长的工作——也就是发扬企业家精神来改进业务,而让其他人(在这里指的是Google Cloud)负责维护物理硬件、电力、安全性和操作系统更新等同质化的繁重劳动。

React Native是什么?

2015年,Facebook发布并开源了React Native,当时它已经在FB内部被用于移动工程了。React Native是使用React构建原生移动应用程序的框架。这意味着你可以使用一流的JavaScript库(React)来构建自己的原生移动用户界面。

在Shopify,这个想法在当时(并且现在仍然)面临许多质疑,但是许多人看到了它的前景。在公司的下一个Hackday中,全公司都抽时间来研究React Native。尽管早期团队看到了这个框架的很多好处,但他们判断我们在2015年无法使用React Native制作出足以让我们自豪的应用来。这主要是因为性能表现不佳和缺少一流的Android支持。而我们当时了解到的事实是,我们的确喜欢响应式编程模型和GraphQL。另外,开始使用React Native之后我们为iOS构建并开源了一个函数式渲染器。在2015年,我们将这些技术加入了自己的原生移动开发技术栈,但没有将React Native用在完整的移动开发工作中。《环球邮报》在介绍我们初代移动应用的深度报道中提到了我们的愿景

到目前为止,Shopify上所有移动开发的标准都是原生移动开发。我们建立了分别专注于iOS和Android的移动工具链和基础团队,以加快我们的开发工作。尽管这些团队和产出的应用程序都取得了成功,但也有人认为如果我们能够做到下列事项,那么团队效率可能会提高:

  • 将JavaScript和Web的力量带入移动开发领域;
  • 在所有客户端应用程序中采用响应式编程模型;
  • 将我们的iOS和Android开发工作整合到一个技术栈中。

React Native的工作机制

React Native提供了一种使用JavaScript构建原生跨平台移动应用程序的方法。React Native与React类似,它允许开发人员在JavaScript中创建声明式用户界面,为此它在内部创建一个UI元素的层次结构树,用React术语来说就是创建一个虚拟DOM。尽管ReactJS的输出以浏览器为目标,但React Native使用平台原生绑定将虚拟DOM转换为移动原生视图,这些平台原生绑定使用JavaScript对接应用程序逻辑。就我们的需求而言,目标平台只有Android和iOS,但是RN社区已努力将React Native引入了其他平台,例如Windows、macOS和Apple tvOS等。

ReactJS的目标是浏览器,而React Native的目标可以是移动API。

在什么情况下我们不会选择React Native?

在某些情况下,React Native并不是Shopify构建移动应用的默认选项。比如说如果我们有以下需求:

  • 在较旧的硬件(CPU <1.5GHz)上部署
  • 复杂的处理过程
  • 超高性能
  • 许多后台线程

提醒一句:包括许多开源SDK在内的底层库还会是纯原生的。需要接近硬件层时,我们都可以创建自己的原生模块。

为什么现在转向React Native?

这三大因素决定了现在是做出这一决策的好时机:

  1. 我们在2018年收购了Tictail(一家移动优先的公司,完全专注于React Native),从中了解到了React Native的发展情况,并在2019年进行了3项深度产品投资;
  2. Shopify在Web端广泛使用React,现在这一部分的知识就可以在移动端利用上了;
  3. 我们看到性能曲线是向上弯曲的(想想现在Google Docs和桌面端Microsoft Office中的能力对比),并且我们可以像在Ruby、Rails、Kubernetes和Rich Media中那样对React Native进行长期投资。

2019年Shopify的移动开发情况

Shopify拥有许多移动平台,供买卖双方通过Web和我们的移动应用进行交互。去年,我们花了一些时间由三支独立的团队在三款应用上针对React Native进行了实验:这三款应用分别是Arrive、Point of Sale和Compass。

从这些实验中我们了解到:

  • 在React Native中重写Arrive应用时,团队认为自己的生产力是使用原生开发时的两倍——即使只在一个移动平台上对比也是如此;
  • 在Android硬件的低功耗配置上测试Point of Sale应用时,我们设置的CPU阈值比之前想象的还要低(1.5GHz对2GHz);
  • 我们之前估计iOS和Android之间约有80%的代码可以共享,结果实践中的超高水平震撼了我们——95%(Arrive)和99%(Compass);

顺便说一句,即使我们决定使用React Native来构建所有新应用,这并不意味着我们会自动开始在React Native中重写那些旧应用。

Arrive

在2018年底,我们决定用React Native重新编写我们最受欢迎的消费类应用之一,Arrive。Arrive是一款评价颇高、表现出色的应用,在iOS上拥有数百万的下载量。它是很好的候选者,因为它之前没有Android版本。这一努力将帮助我们满足所有渴望获得Arrive的Android用户的期待。现在,iOS和Android上的Arrive都是基于React Native开发的,并且共享95%的代码。我们将在以后的博客文章中深入探讨Arrive。

到目前为止,这次重写带来了以下结果:

  • 与原生iOS应用相比,新版本在iOS上的崩溃次数更少;
  • 推出了Android版本;
  • 由移动+非移动开发人员组成的团队。

团队还想出了一种很酷的方法来立即测试进行中的拉取请求。你只需从手机上扫描一条自动Github注释中的QR码,JavaScript包就会更新到你的应用中,现在你运行的就是从这个拉取请求中获得的最新代码。我们的首席技术官JML最近在Twitter上分享了这一过程

Point of Sale

在2019年初,我们在自己的旗舰级Point of Sale(POS)应用上展开了为期6周的实验,想要知道它是否适合用React Native重写。我们学到了很多东西,其中包括我们的零售商家期望的POS响应能力几乎是之前的两倍,因为使用这款应用时会养成肌肉记忆,需要边操作应用边同顾客交流。

为了给我们的零售商提供最好的服务,并在实体零售环境中了解React Native的能力,我们决定在iOS上原生构建新版POS,并在Android上使用React Native。

我们选择由两支团队并行推进,主要出于以下原因:

  1. 我们已经有了一支具备iOS专业知识的团队,其中有许多成员参与构建了原始POS应用;
  2. 我们希望能与原生iOS这一黄金标准对比,对React Native的工程速度以及应用性能进行基准测试;
  3. 为了满足商家的高性能需求,我们觉得应该在项目启动前等待Facebook对React Native做完所有架构更新(事实证明,这些更新对我们的性能场景而言并不重要)。在两个平台上拥有两支团队,降低了我们启动项目时面临的风险。

我们在Unite 2019上宣布了开始对POS做全面重构。预计原生iOS和React Native Android应用都将在2020年发布!

Compass

Shopify Start团队的任务是帮助创业新人。在公司做出全面决策,准备在React Native中编写所有移动应用之前,这支团队深入研究了原生、Flutter和React Native这些可能的技术选项。他们最后选择了React Native,并在应用商店中上线了iOSAndroid应用(测试版)。

Compass的第一批版本(iOS和Android)只用了不到3个月就发布了,iOS和Android版本之间共享约99%的代码。

Shopify在2020年之后的移动开发规划

我们在2020年有很多计划。

我们会重写那些原生应用吗?不,这是需要由每个应用团队独立做出的决定。

我们会继续雇用原生开发工程师吗?是的,需要很多!

我们希望为React Native内核做出贡献,构建平台特定的组件,并继续了解每个平台的精妙之处。这需要深厚的原生专业知识。

合作与开源

我们认为构建软件是一项团队运动。我们认同开放Web、开放源码和开放标准。

我们正在赞助Software Mansion和Krzysztof Magiera(Android 版React Native的共同创始人),支持他们围绕React Native进行开源工作。

我们正在与William Candillon(Can It Be Done in React Native的主持人)合作进行架构审查和性能改进。

我们将与Facebook的React Native团队紧密合作,研究自动化、第三方库以及通过Lean Core管理某些模块主题。

我们正在与Discord合作,以加快FastList for React Native(一个仅渲染视口中列表项的库)的开源进程,并针对Android进行优化。

React Native的开发工具链和基础

当你下注一项技术并深入研究它时,你希望从这一选择中获得最大的效用。为了使我们快速构建并获得最大效用,我们设置了两种类型的团队来帮助Shopify的其他团队快速构建。第一个类型是工具链团队,可以帮助他人进行工程设置、集成和部署。第二个类型是基础团队,专注于SDK、代码重用和开源。进入2020年,我们已经开始让这两支队伍都转变方向,专注于React Native。

Shopify Ping应用仅在iOS平台上就处理了数十万次客户对话。2020年,我们将在旧金山办公室使用React Native构建它的Android版本,目前正在为此招聘人员)。

在2019年,Twitter使用称为React Native Web的东西发布了他们的桌面和移动Web应用。虽然这项技术有点令人困惑,不过它允许你为Web应用使用相同的React Native技术栈。Facebook为该项目聘请了首席工程师Nicolas Gallager。在Shopify,我们将在2020年进行一些React Native Web的实验。

作者介绍:

Farhan Thawar是Shopify的渠道和移动业务副总裁。

原文链接

https://engineering.shopify.com/blogs/engineering/react-native-future-mobile-shopify

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/RhlZeSyVSSkxmxeqxrSO
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券