不久之前,Airbnb 团队刚刚宣布放弃使用React Native,才过不久,Udacity移动团队最近也宣布从App中移除了使用React Native开发的最后一批功能。再加上6月中旬,Facebook宣布将大规模重构RN,这一系列的事件,让不少正在使用React Native的开发者瑟瑟发抖,陷入了恐慌之中。

\\

在本文中,Udacity团队将告诉大家他们使用React Native的历程以及放弃他们的原因,也希望给一些开发者一些参考和启发,看自己是否适合React Native。

\\

以下来自Udacity移动团队的自述:

\\

Udacity移动团队

\\

Udacity的移动团队分为iOS和Android两个团队。

\\

团队规模

\\

在引入React Native时:

\\

  • \\t

    1个iOS开发

    \\t\\t

  • \\t

    2个Android开发者

    \\t\\t

  • \\t

    1个项目经理

    \\t\\t

  • \\t

    1个设计师

    \\t\

现在:

\\

  • \\t

    4个iOS开发者

    \\t\\t

  • \\t

    3个Android开发者

    \\t\\t

  • \\t

    1个项目经理

    \\t\\t

  • \\t

    1个设计师

    \\t\

在使用React Native的18个月中,我们的iOS和Android团队规模都有所增长,整个团队由一名项目经理来领导。

\\

期间,我们还经历了向多设计师和多设计范式转型。

\\

开发背景

\\

在引入React Native时,我们iOS团队唯一的开发人员非常乐于使用React Native,这极大丰富了他之前Javascript和Web的开发经验。两位Android开发人员中的一位对Javascript有丰富的经验,而另一个只有很少的Javascript、React或Web经验。

\\

现在,四个iOS开发人员中至少有三个非常乐于使用Javascript和React Native。后来加入团队的其他Android开发人员也只有很少的Javascript或Web经验。

\\

Udacity的App

\\

用途

\\

Udacity的移动app旨在将Udacity的学习体验带到用户的移动设备上。它支持身份验证、内容发现、程序注册(在某些情况还支持支付),以及消费各种类型的学习资料。

\\

Udacity的App也作为新的实验性功能和旨在提升用户整体学习效果的活动的试验场。

\\

代码库的大小

\\

iOS:97,400行(.swift、.h、.m) 
\Android:93,000行(xml、java、kotlin、gradle)

\\

Udacity为什么以及如何采用React Native?

\\

为什么要引入它?

\\

当时,Udacity正准备推出全新的移动端专用功能。我们希望在两个平台上快速进行实验和验证,因此跨平台具有很大的吸引力。

\\

可以总结为以下几点:

\\

  • \\t

    跨平台解决方案具有更高的可行性

    \\t\\t

  • \\t

    大多数(2/3开发人员)团队成员非常适应Javascript和Web开发

    \\t\\t

  • \\t

    可以提高开发速度

    \\t\\t

  • \\t

    来自公司之外其他团队的成功案例

    \\t\

Udacity是如何引入的?

\\

React Native的初始特性是在一个单独的GitHub代码库中构建的,然后作为git子树分别并入iOS和Android代码库。

\\

这样可以进行非常快的原型设计,并且如果有必要,可以将某些功能作为独立产品发布。

\\

Udacity团队设计了很多原型,最终在React Native代码库中引入了第二个更大的功能。

\\

时间线

\\

  • \\t

    2016年8月:为功能1创建React Native代码库

    \\t\\t

  • \\t

    2016年11月:在Android上发布了功能1

    \\t\\t

  • \\t

    2016年11月:开始开发功能2

    \\t\\t

  • \\t

    2016年12月:设计功能3原型

    \\t\\t

  • \\t

    2017年1月:功能1开发结束

    \\t\\t

  • \\t

    2017年2月:功能2发布

    \\t\\t

  • \\t

    2017年3月:功能3原型设计结束

    \\t\\t

  • \\t

    2017年11月:在Android上更新功能2

    \\t\\t

  • \\t

    2017年12月:功能4原型作为独立app发布。最终由于性能问题取消了对原生的支持

    \\t\\t

  • \\t

    2018年2月:在iOS上更新功能2

    \\t\\t

  • \\t

    2018年4月:从Android中移除功能1

    \\t\\t

  • \\t

    2018年6月:从两个app中移除功能2

    \\t\

为什么要移除React Native?

\\

原因很简单。因为剩下的唯一一个React Native功能已经没有用了,我们不再需要支持它。

\\

或许这样问会更有趣:“为什么我们不继续在React Native上投入,以便获得新功能?”

\\

此时,需要考虑几件事:

\\

1.同时需要在两个平台上构建的功能数量越来越少

\\

2.Android特定需求在增加

\\

3.对长期维护成本感到沮丧

\\

4.Android团队不愿继续使用React Native

\\

用什么来取代React Native?

\\

Udacity移除的React Native功能不再受支持,所以不需要进行任何替换。

\\

初次尝试React Native给我们带来哪些好处?

\\

  • \\t

    使用React Native进行跨平台构建非常容易

    \\t\\t

  • \\t

    可以引入React和Javascript生态系统中的库和工具

    \\t\\t

  • \\t

    能够同时在两个平台上对功能进行原型设计

    \\t\\t

  • \\t

    跨职能团队中的单个开发人员能够同时为两个平台构建大部分功能

    \\t\\t

  • \\t

    团队对React Native的整体理解有所改善

    \\t\

遇到了哪些问题?

\\

在使用React Native期间,我们遇到了很多问,主要在于流程、使用场景,React Native本身的问题。

\\

设计和体验方面的挑战

\\

平台一致的UI/UX

\\

因为要往现有的体验中加入一些新的页面,所以我们希望新的React Native代码能够遵循原生平台模式和现有的样式,这意味着我们不一定能为两个平台使用相同的UI设计。

\\

要在React Native中确保每个平台本身的样式并不困难,但确实需要了解每个代码库的设计范式。至少需要对平台以及每个操作系统的自定义小部件进行检查。

\\

对于我们来说,通常需要与每个平台的开发人员和设计人员沟通,以便了解需求是什么,否则如果两个平台使用同一个样式,有可能会导致在Android平台上的新功能体验与App的其他部分截然不同。

\\

在更复杂的情况下,需要使用一些额外的平台特定代码来自定义App体验。

\\

确保回退图标的行为是正确的就是一个例子。由于需要将新的React Native功能集成到现有的app中,要确保回退图标和后退按钮按的行为是正确的需要对Android原生代码和React Native代码做出特定的修改。

\\

有一次,Android app的导航结构发生了变化,我们不得不修改React Native代码,只是为了要改变原生与React Native之间的集成方式。

\\

React Native不需要有自己的Activity,我们把它们移到Fragment中,并放在带有BottomNavigationView的屏幕中,然后在它和其他原生Fragment之间协调状态。

\\

这种类型的变更需要回到各自的代码库,做出更改,更新集成,并确保新的变更不会对iOS App产生负面影响。

\\

设备特定问题

\\

无论你要把这个叫作“碎片化”还是“多样化”,我们仍然要面对这样的事实:越来越多的Android设备有自己独一无二的配置。

\\

很多时候,我们发现布局无法完美匹配不同尺寸的Android手机,在最新的iPhone或Pixel设备上运行流畅的动画在其他国家(在这些国家Android使用更为广泛)的低端设备上运行不佳。

\\

这些肯定不只是React Native的问题,它们是Android平台开发常见的问题。但随着平台检查方面的工作量以及需要考虑到的因素数量的增加,我们不得不开始考虑,React Native到底可以为我们节省多少时间。

\\

全球性增长

\\

在我们使用React Native期间,国际化成为Android团队的一个焦点。我们的几个国际办事处要求对App进行本地化,并减少apk大小。

\\

React Native的字符串本地化完全可以实现,尽管确实需要做出一些额外的设置。在我们的例子中,我们需要对代码库做出单独的修改。这增加了本地化的复杂性,因为向其他团队寻求本地化帮助并非理想的方式,同时也会降低React Native功能的本地化频率。

\\

我们能够在一段时间内减少apk大小,但是React Native的大小可能会增加,对此我们无能为力。移除最后一个React Native功能后,我们的apk大小减少了约10MB。

\\

集成挑战

\\

与原生组件和导航结构的集成

\\

根据我们的经验,对于独立的功能,将React Native集成到现有应用程序中可能非常简单,但如果要与现有组件紧密集成和交互,则可能会麻烦一些。

\\

我们经常需要大量的桥接代码在原生和React Native组件之间进行通信。在React Native组件与现有导航结构集成的地方,每次发生变更时,都需要进行至少一次的桥接代码更新。

\\

工具/构建问题

\\

集成React Native需要对每个App的构建过程做出变更。我们使用CircleCI来构建项目,因此需要对它进行重新配置,以支持额外的React Native构建步骤。

\\

而在Android方面,它并不像我们所预期的那么简单。

\\

在进行重新配置后,CircleCI的构建时间增加了大约20%。

\\

从代码库中移除最后一个React Native功能后,我们看到了以下改进:

\\

  • \\t

    CircleCI构建时间从15分钟减少到12分钟

    \\t\\t

  • \\t

    发布的apk大小从28.4MB降至18.1MB

    \\t\

Android团队也经常遇到Android/Gradle构建工具与React Native的冲突问题。

\\

iOS团队也面临着相当大的挑战。

\\

配置构建过程是一个很痛苦的事,因为我们的构建文件结构不是标准的。由于我们使用了单独的代码库,我们在srcroot/ReactNative目录中拉取React Native代码库,很多现有构建工具假设使用的是默认的app结构,即/ReactNative/ios/…ios。

\\

此外,我们使用cocoapods进行依赖管理,最初建议用它来管理React Native依赖,但后来被弃用。我们的非标准文件结构也给我们带来了麻烦,我们不得不在Podfile中做一些令人讨厌的侵入性修改,让它从正确的位置读取配置文件。

\\

由于cocoapods不再是标准的React Native依赖管理方式,因此Podfile的更新只能依赖于​​社区,而这些更新通常不太同步。比如css/Yoga已经推出更新,但Podfile引用的却是不正确的版本。最后,我们不得不做出一些侵入性的修改,使用sed和正则表达式来实现版本检查和安装。

\\

iOS项目的CI也是一个痛点。我们现在必须添加一个npm依赖层,并确保在安装其他依赖之前它们是最新的。这给我们的构建步骤带来了额外的时间消耗。

\\

还有一个问题会导致构建崩溃,比如一个版本的npm有package.lock文件,而另一个版本没有,这会导致我们在React Native升级过程中安装了不正确的依赖版本。

\\

来自React Native的挑战

\\

文档

\\

React Native本身发展得很快,但文档却相对缺乏。特别是我们是第一次使用React Native,我们发现特定版本的文档多多少少有点不齐全。

\\

那个时候,用于将React Native与现有项目集成的文档似乎很少,因此,在对CI做出构建配置时,这无疑增加了我们的难度。

\\

随着React Native不断发展,文档和社区得到了改善。如果换到了今天,我们或许会更容易找到一些问题的答案。

\\

导航

\\

我们最初使用的是NavigationExperimental,它不是最容易使用的导航库。React Navigation出现后,迅速在社区中流行开来,在ReactNavigation的功能得到真正的完善之前,我们已经弃用了NavigationExperimental。

\\

不过,如果不把一些东西强行组合在一起(例如在呈现模态流中推送流),有些事情在ReactNavigation中是做不到的。

\\

性能

\\

如前所述,我们也会注意到性能问题。

\\

我们能够制作出一些非常漂亮的动画,这些动画在高配置的iOS和Android设备上看起来很棒,但在一些低配置Android设备上表现不佳。

\\

进入app的React Native部分时,加载时间比我们预期的要长,而且它们看起来不像是无缝的过渡。

\\

在对功能4进行原型设计时,图形渲染性能是一个非常大的问题,我们不得不使用原生体验取代了React Native。

\\

滞后于原生平台

\\

因为它不是与iOS或Android一起构建的,所以React Native有时会滞后于原生平台。在很大程度上,它依赖社区来提供新的原生功能。

\\

其中一个例子就是迫切需要为iPhone X提供安全区域支持。我们最终选择在短时间内不使用SafeArea,因为React Native团队很快就会推出该特性。跨平台开发人员在使用SafeAreaView开发兼容性app时需要特别注意这个特定于平台的特性。

\\

有时候,React Native也会在采用新平台需求方面表现滞后,例如Android app被要求在2018年8月之前采用API Level 26。而在这方面还有几个未解决的问题。

\\

突破性的更新

\\

React Native无法向后兼容,这点非常令人沮丧。比如,在React Native升级了它的底层React库后,PropType就被弃用了。

\\

如果我们不维护自己的分支,很多第三方库就会变得无法使用。

\\

来自维护方面的挑战

\\

有时候,维护React Native代码库对我们来说是一个挑战。如前所述,Android通常需要额外的工作,无论是与现有代码集成还是修复UI问题。这导致iOS和Android使用了不同的React Native代码库分支,这样才能让两个平台之间不互相影响。

\\

由于使用了不同的分支,开始出现代码分歧,并且用于解决冲突的工作流增加了。结果,对一个平台的更新并不会立即被添加到另一个平台中。

\\

React Native的演化速度也给我们带来了挑战。由于可能会出现突破性变更,因此为了获得新功能或修复bug而进行的依赖更新的速度变慢了。

\\

另外,有时这会导致摩擦力增加,从而降低了代码的维护速度。由于团队规模小,带宽有限,如果不是简单的、可以快速修复的问题,那么问题就不太可能很快得到解决,因为这可能需要额外的开发工作量。

\\

因为引入了React Native,所以我们并不总能清楚地知道bug处于什么级别。它是否存在于两个平台中?还是只在一个平台上出现?如果只在一个平台上出现,是在原生代码中还是在React Native代码中?这些问题所带来的复杂性有时候会减慢QA过程。

\\

当需要修复React Native代码库中的问题时,我们现在必须同时考虑iOS和Android,并且可能需要使用3个开发栈,而不是1个。

\\

此外,不是所有人都觉得React Native效率很高,能够迅速上手并修复问题的开发人员的数量也减少了。

\\

我们本该可以做哪些不一样的事情?

\\

我相信,我们遇到的一些问题是我们的场景所固有的,但是我们其实可以做些不一样的事情来缓解其中的一些问题。

\\

减少代码分歧

\\

我们本可以更好地让React Native代码库中的变更与每个平台的App保持同步。我相信保持这些更新同步将有助于增强我们的跨平台开发意识。

\\

多在设备上进行测试,特别是在Android上,可能可以在早期就发现更多的UI和性能问题,并在发布之前修复它们。在开发新功能之前解决旧问题,可以减少代码分歧的数量。

\\

更一致的设计

\\

如果从一开始就设计更具体方案可能有助于改善功能的原生外观。比如使用与原生App一致的文本和边值,而不是使用新值,并在两个平台上使用它们。

\\

团队成员需要学习

\\

对React Native不太熟悉的团队成员可以更努力地尝试融入新的开发栈,这样就会有更多的人能够快速解决问题。

\\

有没有适合使用React Native的场景?

\\

我相信,我们团队中没有人会认为React Native一无是处。我当然相信React Native有它适合的场景。

\\

  • \\t

    你是否需要在两个平台上从头开始快速地构建新app?

    \\t\\t

  • \\t

    你是否正在开发一个App或功能,要求在不同的平台上具有相同的外观和行为?

    \\t\\t

  • \\t

    你的Javascript开发人员是不是有多余的时间可用于开发移动应用?

    \\t\

如果对这些问题中的任何一个答案“是”,那么React Native很可能适合你。

\\

特别是如果你有Javascript和React经验,并且正在寻找一个不需要太多原生代码就能构建的应用程序,那么React Native是一个非常有吸引力的选择。这样你就能够马上开始开发,而无需去学习2种不同的技术栈。

\\

对于新开发的完全跨平台的app,React Native也是一个很好的选择。

\\

我们会再次使用React Native吗?

\\

iOS和Android团队有不同的意见。

\\

iOS

\\

有可能。iOS团队通常很乐意使用React Native,并考虑使用它开发新功能。此外,在产品方面,我们的PM对在iOS上运行React Native比对Android更有信心。

\\

Android

\\

不会。理想情况下,Android团队将来不会继续在React Native上投入。我们发现与React Native组件集成的过程很麻烦,并且在Android设备上的体验达不到预期。

\\

此外,还有一种倾向,坚持使用单一的开发栈,而不是在Android框架之上添加新的抽象层,或引入可能的错误。

\\

我们的印象是,使用React Native开发Android新功能的速度更快,但长期来看,新功能从早期阶段到能够完美发布需要更长的时间。

\\

我们会再次使用另一种跨平台解决方案吗?

\\

从团队方面来看,在不久的将来,我们可能不会在跨平台开发上继续投入。iOS团队可以使用React Native构建一些特定于iOS的东西,因为他们通常更喜欢这种体验。

\\

就个人而言,团队的成员将继续关注React Native和Flutter。随着React Native和Flutter等解决方案的不断发展,我们也将继续对它们做出评估。

\\

我们对React Native是否适合我们的团队和路线图有了更好的理解。在进行技术选型时,我们可以利用这些信息做出更加明智的决策。

\\

我们看到了React Native的优点以及局限性。我们能否明确地给出React Native是否适合你的定论?

\\

不能。

\\

但是,在评估React Native是否可用在你们的项目中时,希望我们的经验可以作为参考。

\\

查看英文原文:https://engineering.udacity.com/react-native-a-retrospective-from-the-mobile-engineering-team-at-udacity-89975d6a8102

\\

感谢覃云对本文的审校。

Udacity也弃用React Native了 !相关推荐

  1. Airbnb 宣布弃用 React Native!

    web前端教程 用大白话,来讲编程 作为 React Native 框架的先行者和倡导者,Airbnb 公司今日发布通告,决定放弃使用 React Native 技术,重新投入资源和精力到原生开发当中 ...

  2. 为什么 React Native 连遭 Airbnb、Udacity 抛弃?

    投稿 | 亦枫 责编 | 唐小引 Udacity 移动端团队最近删除了 App 中使用 React Native 语言开发的相关功能. 我们收到大量有关我们用法或 React Native 的问题以及 ...

  3. Airbnb 弃用之后,我们还应该用 React Native 吗?

    点击上方"CSDN",选择"置顶公众号" 关键时刻,第一时间送达! 在过去几年,当人们谈到 React Native 时,都会马上联想到 Airbnb 在这方面 ...

  4. React Native 0.59.0 发布,使用 React 编写原生应用

    React Native 0.59.0 发布了.React Native 使开发者只使用 JavaScript 也能编写原生移动应用. 新版更新亮点: React Hooks React Native ...

  5. React Native开发之必备React基础

    为了帮助大家快速上手React Native开发,在这本节中将向大家介绍开发React Native所需要的一些React必备基础知识. 概述 本节课将从React的特点.如何使用React.JSX语 ...

  6. React Native基础入门教程:初步使用Flexbox布局

    一.长度的单位 在开始任何布局之前,让我们来首先需要知道,在写React Native组件样式时,长度的不带单位的,它表示"与设备像素密度无关的逻辑像素点". 这个怎么理解呢? 我 ...

  7. 苹果收购英特尔手机芯片业务;西门子将在华建立 5G 研发中心;React Native 0.60.4 发布 | 极客头条...

    快来收听极客头条音频版吧,智能播报由标贝科技提供技术支持. 「CSDN 极客头条」,是从 CSDN 网站延伸至官方微信公众号的特别栏目,专注于一天业界事报道.风里雨里,我们将每天为朋友们,播报最新鲜有 ...

  8. React native大版本迭代信息记录

    记录react native,版本迭代中的重大变化 v0.60.x 1.AndroidX支持 2.精益核心减除(WebView和NetInfo之前被提取到单独的存储库中)(react-native-w ...

  9. 比较 React Native 与 Vue 和 Capacitor

    随着可用移动应用程序开发框架数量的增加,2018 年引入的 Vue Native 使开发人员能够使用 Vue.js 代码创建 React Native 移动应用程序. 然而,Vue Native 团队 ...

  10. Hybrid App 和 React Native 开发那点事

    版权声明:本文为博主原创文章,未经博主允许不得转载. 简介:Hybrid App(混合模式移动应用)开发是指介于Web-app.Native-App这两者之间的一种开发模式,兼具「Native App ...

最新文章

  1. linux服务器后台运行程序
  2. 分布式系统——向zabbix中添加监控项, 以nginx和mysql为例
  3. K8S创建role命令示例
  4. 单点登录Redis存储Session及Cookie场景介绍
  5. CodeForces - 1313B Different Rules(数学+思维)
  6. java控制台输出百分比进度条示例
  7. python是什么类型的编程语言-Python是个什么语言?
  8. 第一期_内存管理单元MMU
  9. DL for Scratch 读书笔记
  10. Jmeter 中的BeanShell使用
  11. 联想计算机怎么改为光驱启动,联想笔记本光驱启动设置方法
  12. 在2022年如何将整个维基百科下载到U盘中
  13. java 批量生成条形码,打包zip(springboot)
  14. 许可协议html,许可协议
  15. SuperMap三维专题之倾斜摄影——WebGL加载倾斜摄影数据篇
  16. windows server2012软路由
  17. 基于 WeDataSphere Prophecis 与 KubeSphere 构建云原生机器学习平台
  18. 笔记本电脑外接屏幕步骤
  19. 网站服务器怎么屏蔽ip段,iis屏蔽ip段,网站禁止ip访问
  20. Pygame学习笔记13:Dungeon角色扮演游戏

热门文章

  1. oracle11g和10的区别,同平台升级 oracle 10 到 oracle11g的一些考虑和实际操作
  2. 不同运营商链路聚合_聚合路由器在视频直播应用中的优势
  3. 栈-剑指 Offer 30. 包含min函数的栈
  4. LeetCode Array 最长回文子串-数组和string题目
  5. 115.不同的子序列
  6. 随机梯度下降法(SGD)
  7. ajax每次只加载3张图片,使用加载图片解决在Ajax数据加载中页面出现短暂空白的问题(推荐)...
  8. python爬知识星球付费数据_Python 爬取知识星球数据
  9. c语言 异或_C语言位逻辑运算符的四种逻辑:取反,并,或,异或
  10. python中去除列表重复元素的方法汇总