阿里、蚂蚁、晟腾、中科加禾精彩分享 AI 基础设施洞见,现购票可享受 9 折优惠 |AICon 了解详情
写点什么

耗时三年,向 React 迁移的利与弊

  • 2020-08-14
  • 本文字数:2916 字

    阅读完需:约 10 分钟

耗时三年,向React迁移的利与弊

2017 年,可汗学院( https://blog.khanacademy.org)开始在 iOS 和 Android 应用中使用 React Native。到了今年,这一迁移工程终于来到了终点,可汗学院应用中的所有页面都转到了 React Native 上。


2017 年,可汗学院之所以开始这一实验,主要是基于以下考虑:


  • iOS 和 Android 应用的设计几乎是一致的,交互设计、功能和内容都没什么区别。

  • 维护两个代码库是很困难的事情,尤其是这两个代码库还具有不同的数据设计、错误和开发新功能时的考虑要素。

  • 学院的移动开发团队很小,因此迁移工作不会涉及大批工程师。

  • 学院的网站已经在使用 React 了,因此学院的开发团队具备相应的专业知识,以及帮助迁移的概念和工具。


下面具体讲一下维护两个代码库所要面临的挑战。


  • 不同的平台上会出现不同的错误。当然,React Native 也会有这种情况,但是出现概率就小得多了。

  • 开发新功能需要针对两个平台分别考虑设计、工程和测试工作。这意味着你至少需要两名工程师(iOS 和 Android),并且他们最好共同工作——对于像可汗学院这样小规模的团队来说这是很大的负担。

  • 功能和设计一旦构建好后就很难调整,因为每次调整都需要在两个平台上各来一次。

  • 平台之间的架构差异很大。可汗学院的 iOS 代码库比 Android 代码库大四岁。iOS 有 Swift、ReactiveCocoa、Cartography 和 CoreData。Android 则有自己的一组依赖项和数据流设计。这些差异累加起来,让平台之间的功能复用变得很复杂,对比两个平台的代码也不容易,于是团队相当于被平台分割成了两部分。

开始迁移

整个迁移过程基本上分为三个阶段:探索、跨越和灭绝。


在探索阶段(2017 年初),团队开始在原生代码和 Javascript 代码之间架起桥梁,并开始使用 React Native 构建一些页面。几乎所有的网络、数据、业务逻辑和所有“客户端后端”内容都是通过桥梁传递的。这一阶段的工作涉及很多样板,因此非常繁琐。


跨越阶段(2017 年中至 2018 年中)自然是最困难的。学院团队正式决定转向 React Native,但离终点还有很远的距离。这时候,团队需要考虑三件事:原生 iOS、原生 Android 和 React 原生代码。工程师要做出一项更改时需要考虑两个(或更多)范式,并且有很多东西要学习!


灭绝阶段(2018 年中至 2020 年中)从学院的“流主题树”项目开始,该项目历时数月,将内容数据库(学院的许多课程、视频、文章和练习内容)从大型原生数据库(例如 CoreData)完全迁移到了轻量级 、 用 Javascript 编写的缓存库。至此,学院的客户端内容数据库转入了 React Native,于是不需要在构建的桥梁上传递那么多内容了,并且可以开始删除许多原生代码。到今年的 v7.0 版本,应用的最后一个原生页面也会升级到 React Native,同时统一了手机和平板电脑的导航设计。

原生和 React Native 的混合体

开发团队将 React Native 用于“页面内容”,而将原生代码用于这些页面的导航用途。这是为了物尽其用,并让应用尽量提供原生级的体验。


应用的绝大多数“业务逻辑”都存在于页面内容中(例如“首页”标签中卡片的内容,或“书签”标签中的下载规则)。相比之下,标签栏或导航栏的内容在很大程度上不依赖业务逻辑。


但是,用 React Native 编写的导航栏和导航控制器和原生版本还是有一些差异,这些差异加起来还是很可观的。原生导航控制器提供了正确的滑动后退手势,以及用于推/弹出动画的正确动画 timing。原生导航栏可轻松处理带刘海的 iPhone。在原生 UIViewController 中包装的页面也更符合开发习惯。(有很多库试图模仿系统的标准导航栏,但它们都无法满足可汗学院团队的需求。)


这个迁移项目的一条原则是迁移后的应用依旧要有原生级的体验,当然小问题总是会有的,但以此为代价,团队在许多方面为应用带来了明显的改进。

国际化和本地化

移动应用的翻译工作主要有两部分组成:内容文本和平台文本。前者来自学院的内容管理系统,包括互动练习中的问题、视频的内容和字幕或文章中的文字。(许多内容文本是前面提到的“流主题树”的一部分。)平台文本是在移动应用的代码库中定义的,如“注册”按钮中的文字、标签栏项目的标题或“设置”页面中显示的文字。


可汗学院有一些优秀的自制基础架构来维护平台文本。在 JavaScript 中定义一个字符串,然后就可以使用开发团队编写的,将字符串复制到原生 iOS 和 Android 字符串的脚本。这个工具很好用,团队可以轻松地在原生和 React Native 上重用字符串,这在“跨越”迁移阶段有很大帮助。


从 2015 年至 2019 年,可汗学院的应用仅支持六个语言版本,但现在已达到了 19 个!共享的 iOS 和 Android 实现帮助团队构建了流主题树,这意味着添加其他语言不会让应用的体积大幅增加。此外,团队能够在 React Native 中设计轻松处理非拉丁字符的组件。应用的语言版本数量不再有技术瓶颈,而只取决于学院有多少翻译库可用。这极大地鼓舞了学院的国际倡导者,让他们更好地为世界各地的用户宣传可汗学院。

React Native 的体验

迁移到 React Native 并不是一帆风顺的,途中有很多坎坷,例如学习新语言、新的组件生命周期等。“跨越”时期尤其具有挑战性。原生代码和 React Native 代码之间的桥梁有很多烦人的样板代码。


团队成员很想念 Swift 的关联值枚举、方便的初始化器、命名参数以及轻松向结构和类添加函数和变量的特性。


但 React Native 也有很多好处。


  • React Native 比 UIKit 更具延展性。调整和重构代码的体验很不错。例如,为 UICollectionView 编写的代码与 UITableView 和 UIStackView 是不一样的,但是在 React Native 中并不用操心这一点?在大多数情况下,你可以在重构时剪切并粘贴代码,将某些内容从网格更改为列表是非常简单的。

  • 开发工具非常好用。方便的 VSCode 插件、linter 和自动修复器,大大减轻了开发人员和代码审核人员的负担。

  • 就算开发人员并不怎么熟悉 Android 应用开发,也可以使用 React Native 编写 Android 应用。

  • 熟悉 React Native 后,应用开发团队也有信心参与 Web 前端的开发工作了。

现在的成果

可汗学院的 iOS 和 Android 应用现在共享一个代码库,开发团队可以专注于应用的功能开发,用不着关心平台的差异。这意味着随着时间的推移,应用的功能质量会越来越好,并且团队可以对功能进行渐进式改进了。


  • 共享的基础架构使团队更容易迁移到 GraphQL,从而简化了服务端向 Go 的迁移工作。

  • 应用的体积明显缩小了。从大型内容库数据库切换到流式数据库,极大地减少了应用体积。

  • 应用的开发团队与网站团队联系更紧密,两边的设计和功能也得以互通,整个组织的协作水平得到了提升。

  • 应用中仍然有一些原生代码,必要时团队可以继续使用 Xcode 或 Android Studio 实现特定于平台的功能,例如 iPad 多任务处理。

  • 团队创建了强大的设计系统,可帮助可汗学院的设计师和工程师快速协调产品的改进方案。

下一步计划

可汗学院目前的主要工程项目是Goliath,内容是将后端重新设计为一系列 Go 服务。统一的移动基础架构在这一迁移过程中起到了作用:虽然移动团队只有六名成员,也还是能继续构建新功能和修复程序。团队改善应用的功能、本地化、质量和性能的能力比以前强了很多。


本文最初发布于 khanacademy.org 网站,经网站授权由 InfoQ 中文站翻译并分享。


原文链接: https://blog.khanacademy.org/our-transition-to-react-native/


2020-08-14 14:003522
用户头像
蔡芳芳 InfoQ主编

发布了 781 篇内容, 共 493.9 次阅读, 收获喜欢 2748 次。

关注

评论

发布
暂无评论
发现更多内容

【刷题记录】4. 寻找两个正序数组的中位数

WangNing

7月月更

初识Linkerd项目

阿泽🧸

Linkerd 7月月更

Cgroup devices子系统

总想做点什么

区块链技术带来司法“加速度”

CECBC

Redis stream性能测试实践【Java版】

FunTester

解读《深入理解计算机系统(CSAPP)》第4章处理器体系结构

小明Java问道之路

编译原理 编译器 指令集 7月月更 ISA

Cgroup Cpuset子系统

总想做点什么

需求量最大的6个区块链工作

CECBC

C++算法题中对于字符串的一些妙手

KEY.L

7月月更

App Store 的 App 迁移

贾献华

7月月更

值得学习的Python GUI 库 - pyQt5快速入门及精美界面设计体验

迷彩

PyQt5 Qt Designer 7月月更

自动生成API工具——Swagger3

Java学术趴

7月月更

C语言入门(一)

逝缘~

c 7月月更

前端与HTML

小恺

7月月更

Java多线程案例之线程池

未见花闻

7月月更

想要治好水,龙王也要拜拜这朵云

白洞计划

Nginx Http模块是如何处理请求的?

Ethan

ngnix

禅道与PingCode 大对比

PingCode

PingCode 项目管理软件 禅道

❤️❤️❤️爱了爱了!这样的文字动画让你爱不释手!

岛上码农

flutter ios 前端 安卓开发 7月月更

应用性能管理与链路追踪的关系

穿过生命散发芬芳

链路追踪 7月月更

【愚公系列】2022年7月 Go教学课程 007-计算机进制和变量命名规范

愚公搬代码

7月月更

正则表达式(二)

Jason199

正则表达式 js 7月月更

融云入选优秀厂商!|《2022中国信创生态市场研究及选型评估报告》(附下载)发布

融云 RongCloud

传统企业要为 Web3 和去中心化做的 11 个准备

CECBC

DelayQueue源码分析-特点与新增

zarmnosaj

7月月更

解读《深入理解计算机系统(CSAPP)》第5章优化程序性能

小明Java问道之路

优化逻辑 优化 优化技巧 程序优化 7月月更

NumPy 与 Python 内置列表计算标准差的区别

宇宙之一粟

Numpy 7月月更

2000字教你如何玩转Linux man命令,隐藏技能非常nice

wljslmz

Linux 运维 man 7月月更

Binder通信过程

北洋

Andriod 7月月更

TSDB与Blockchain

CnosDB

IoT 时序数据库 开源社区 CnosDB infra

鸿蒙 eTS 开发方式 Image 组件详解【续】

坚果

HarmonyOS OpenHarmony 7月月更

耗时三年,向React迁移的利与弊_语言 & 开发_Bryan Clark_InfoQ精选文章