2018 年 React Native 的现状
我们很久没有发布关于 React Native 的状态更新了。
在 Facebook,我们比以往任何时候都更多地使用 React Native,并将其用于许多重要项目。我们最受欢迎的产品之一是 Marketplace,它是我们应用中的顶级标签之一,每月有 8 亿人使用。自 2015 年创建以来,整个 Marketplace 都是用 React Native 构建的,包括应用不同部分中超过一百个全屏视图。
我们还将 React Native 用于应用的许多新部分。如果您观看了上个月的 F8 主题演讲,您会认出“献血”、“危机响应”、“隐私快捷方式”和“健康检查”——所有这些都是最近用 React Native 构建的功能。Facebook 主应用之外的项目也在使用 React Native。新的 Oculus Go VR 头显包含一个完全用 React Native 构建的配套移动应用,更不用说 React VR 驱动了头显本身中的许多体验。
当然,我们也使用许多其他技术来构建我们的应用。Litho 和 ComponentKit 是我们在应用中广泛使用的两个库;两者都提供了类似 React 的组件 API 来构建原生屏幕。React Native 的目标从来都不是取代所有其他技术——我们专注于让 React Native 本身变得更好,但我们很高兴看到其他团队借鉴 React Native 的想法,例如将即时重载带到非 JavaScript 代码中。
架构
当我们在 2013 年启动 React Native 项目时,我们将其设计为在 JavaScript 和原生代码之间只有一个“桥接”,它是异步的、可序列化的和批处理的。就像 React DOM 将 React 状态更新转换为对 DOM API(如 document.createElement(attrs)
和 .appendChild()
)的命令式、可变调用一样,React Native 的设计目的是返回一个包含要执行的修改列表的单个 JSON 消息,例如 [["createView", attrs], ["manageChildren", ...]]
。我们设计整个系统是为了不依赖于获取同步响应,并确保该列表中的所有内容都可以完全序列化为 JSON 并反序列化。我们这样做是为了它提供的灵活性:在此架构之上,我们能够构建诸如Chrome 调试之类的工具,它通过 WebSocket 连接异步运行所有 JavaScript 代码。
在过去的 5 年里,我们发现这些最初的原则使得构建某些功能变得更加困难。异步桥接意味着您无法将 JavaScript 逻辑直接与许多期望同步响应的原生 API 集成。批处理桥接将原生调用排队,这意味着 React Native 应用更难调用原生实现的功能。而可序列化桥接意味着不必要的复制,而不是直接在两个世界之间共享内存。对于完全用 React Native 构建的应用,这些限制通常是可以忍受的。但对于 React Native 和现有应用代码之间集成复杂的应用来说,这些限制令人沮丧。
我们正在对 React Native 进行大规模的重新架构,以使框架更灵活,并更好地与混合 JavaScript/原生应用中的原生基础设施集成。通过这个项目,我们将应用过去 5 年所学到的知识,逐步将我们的架构提升到更现代的水平。我们正在重写 React Native 的许多内部组件,但大多数更改都在幕后:现有的 React Native 应用将继续运行,几乎不需要或根本不需要更改。
为了使 React Native 更轻量级并更好地融入现有的原生应用,这次重新架构有三个主要的内部变化。首先,我们正在改变线程模型。每个 UI 更新不再需要在三个不同的线程上执行工作,而是可以在任何线程上同步调用 JavaScript 进行高优先级更新,同时将低优先级工作从主线程中分离出来,以保持响应性。其次,我们正在将异步渲染功能整合到 React Native 中,以允许不同的渲染优先级并简化异步数据处理。最后,我们正在简化我们的桥接,使其更快、更轻量;原生和 JavaScript 之间的直接调用效率更高,这将使构建像跨语言堆栈跟踪这样的调试工具变得更容易。
一旦这些更改完成,更紧密的集成将成为可能。目前,如果不进行复杂的修改,无法集成原生导航和手势处理,也无法集成 UICollectionView 和 RecyclerView 等原生组件。在我们的线程模型更改后,构建此类功能将变得简单明了。
我们将在今年晚些时候,这项工作接近完成时,发布更多细节。
社区
除了 Facebook 内部的社区,我们很高兴在 Facebook 之外也有一个蓬勃发展的 React Native 用户和贡献者群体。我们希望通过更好地服务 React Native 用户和使项目更容易贡献来更多地支持 React Native 社区。
正如我们的架构更改将帮助 React Native 更干净地与其它原生基础设施互操作一样,React Native 在 JavaScript 方面也应该更轻量,以便更好地适应 JavaScript 生态系统,这包括使 VM 和打包器可互换。我们知道破坏性更改的速度可能难以跟上,因此我们希望找到减少主要版本发布的方法。最后,我们知道有些团队正在寻找关于启动优化等主题的更全面文档,这方面我们的专业知识尚未被记录下来。预计在未来一年内会看到这些变化。
如果您正在使用 React Native,您就是我们社区的一部分;请继续告诉我们如何才能让 React Native 为您做得更好。
React Native 只是移动开发者工具箱中的一个工具,但我们坚信它的潜力——我们每天都在让它变得更好,在过去一年中,来自 500 多名贡献者的提交超过 2500 次。