2天时间,聊今年最热的 Agent、上下文工程、AI 产品创新等话题。2025 年最后一场~ 了解详情
写点什么

耗时三年,向 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:004076
用户头像
蔡芳芳 InfoQ 总编辑

发布了 819 篇内容, 共 620.2 次阅读, 收获喜欢 2823 次。

关注

评论

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

大数据开发之通过 Spark 来扩展 Presto

@零度

大数据 spark

TDSQL | 将企业级分布式数据库做到极致

腾讯云数据库

tdsql 国产数据库

虎符研究院深入解读Web3.0未来趋势 盘点代表性项目

区块链前沿News

Web Hoo虎符 虎符研究院 虎符平台 3.0

知识库进化论 | 华创资本对话 ONES & 为知笔记创始人

万事ONES

使用php-amqplib实现RabbitMq

Owen Zhang

php RabbitMQ php-amqplib

组件通信、硬件池化,这些创新技术你get了吗?|HDC2021技术分论坛

HarmonyOS开发者

HarmonyOS

我以订披萨为例,给女朋友详细讲了Java设计模式的3种工厂模式

华为云开发者联盟

Java 工厂模式 工厂方法模式 简单工厂模式 抽象工厂模式

MySQL分区表简介

soap said

:MySQL 数据库

前端使用 zx 库在 Node 中编写 Shell 脚本

devpoint

node.js Shell 1月月更 zx.js

Jetpack—LiveData组件的缺陷以及应对策略

vivo互联网技术

android livedata JetPack 移动应用开发

1月月更|推荐学java——Spring之AOP

逆锋起笔

spring SSM框架 spring aop 依赖注入 面向切面编程

Hive SQL底层执行原理

五分钟学大数据

Hive SQL 1月月更

Chrome插件:摸鱼倒计时、每日摸鱼时间统计,奋斗逼、卷王必备,用于减少摸鱼时间和频率

OBKoro1

效率 开源 效率工具 chrome扩展 高效率

ONES CTO 冯斌|如何低成本地做出高质量决策

万事ONES

ReactNative进阶(二十三):Javascript 严格模式详解

No Silver Bullet

React Native 1月月更

Serverless 背景下,一部分“前端工程师”会转变为“应用交付工程师”

杨成功

Serverless 架构 前端

线上流量对比应用实践

得物技术

架构 数据 流量 实践 流量回放

GIS :元宇宙未来发展的有力技术支撑

华为云开发者联盟

AI GIS 虚拟世界 数字孪生 云宇宙

TDSQL PG版企业级分布式数据库技术创新实践

腾讯云数据库

tdsql 国产数据库

创业老兵李峻的新征程|ONES 人物

万事ONES

我相信:没有解不开的难题|ONES 人物

万事ONES

前端开发之JQuery的综合应用

@零度

jquery 前端开发

龙蜥社区一周动态 | 1.10-1.14

OpenAnolis小助手

Linux 开源 社群

Linux之diff命令

入门小站

Linux

2021 OceanBase 开源半年度报告 | 不忘初心,感恩同行

OceanBase 数据库

开发者 报告 OceanBase 开源 OceanBase 社区版

Hadoop小文件问题产生及解决方案

五分钟学大数据

hadoop 1月月更

Scrum Master需要具备哪些能力和经验

华为云开发者联盟

Scrum 敏捷 团队 教练 Scrum Master

java开发之Redis的使用规范

@零度

redis JAVA开发

CSS 自适应内容宽度的输入框

编程江湖

TDSQL-C for PostgreSQL 主从架构详解

腾讯云数据库

tdsql 国产数据库

Android技术分享| 自定义View实现使用更方便的SeekBar

anyRTC开发者

android 音视频 移动开发 白板 SeekBar

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