qq空间的网站,wordpress会影响网速吗,网站建设事宜,一个网站的建设需要什么东西React Native 0.76 现已在 npm 上以全新架构默认发布#xff01;
在 0.76 版本的发布博客中#xff0c;我们分享了此版本包含的一系列重大更改。在本文中#xff0c;我们将概述全新架构以及它如何塑造 React Native 的未来。
全新架构全面支持现代 React 功能#xff0c;…React Native 0.76 现已在 npm 上以全新架构默认发布
在 0.76 版本的发布博客中我们分享了此版本包含的一系列重大更改。在本文中我们将概述全新架构以及它如何塑造 React Native 的未来。
全新架构全面支持现代 React 功能包括 Suspense、Transitions、automatic batching 和 useLayoutEffect。全新架构还包括新的原生模块和原生组件系统使您能够编写类型安全的代码直接访问原生接口无需桥接。
此次发布是自 2018 年以来我们从零开始重写 React Native 的成果我们特别注意使全新架构对于大多数应用来说是一个渐进式迁移过程。2021 年我们成立了全新架构工作组与社区合作确保整个 React 生态系统的升级体验顺利进行。
大多数应用将能够以与其他任何版本相同的努力级别采用 React Native 0.76。最流行的 React Native 库已经支持全新架构。全新架构还包括一个自动互操作层以实现与针对旧架构的库的向后兼容性。
在过去几年的开发过程中我们的团队公开分享了对全新架构的愿景。如果您错过了其中的任何讲座请在以下链接查看
React Native EU 2019 - 新的 React NativeReact Conf 2021 - React 18 主旨演讲App.js 2022 - 将新的 React Native 架构引入开源社区React Conf 2024 - 第二天主旨演讲
新架构是什么
新架构是对支撑 React Native 的主要系统的全面重写包括组件的渲染方式、JavaScript 抽象与原生抽象的通信方式以及跨不同线程的工作调度方式。尽管大多数用户无需了解这些系统的具体工作原理但这些变化带来了性能提升和新的功能。
在旧架构中React Native 使用异步桥接与原生平台通信。为了渲染一个组件或调用一个原生函数React Native 需要将原生函数调用序列化并通过桥接队列化这些调用将被异步处理。这种架构的好处是主线程不会因渲染更新或处理原生模块函数调用而被阻塞因为所有工作都在后台线程完成。
然而用户期望与交互的即时反馈使应用能够像原生应用一样响应。这意味着某些更新需要在用户输入后同步渲染可能会中断任何正在进行的渲染。由于旧架构仅支持异步我们需要重写它以同时支持异步和同步的更新。
此外在旧架构中通过桥接序列化函数调用很快成为一个瓶颈尤其是在频繁更新或处理大型对象时。这使得应用难以稳定地达到 60 帧每秒FPS。同时也存在同步问题当 JavaScript 层和原生层不同步时无法同步地调和它们导致诸如列表显示空白帧和因中间状态渲染导致的视觉 UI 跳跃等错误。
最后由于旧架构使用原生层次结构保持单一的 UI 复制并在原地修改该复制布局只能在单一线程上计算。这使得处理诸如用户输入等紧急更新变得不可能且布局无法同步读取例如在布局效果中读取以更新工具提示的位置。
所有这些问题意味着无法正确支持 React 的并发特性。为了解决这些问题新架构包括四个主要部分
新的原生模块系统新的渲染器事件循环移除桥接
新的原生模块系统允许 React Native 渲染器同步访问原生层这使其能够异步和同步地处理事件、调度更新以及读取布局。新的原生模块默认采用懒加载显著提升了应用的性能。
新的渲染器能够在多个线程上处理多个进行中的树这使得 React 能够处理多个并发的更新优先级无论是在主线程还是后台线程。它还支持同步或异步地从多个线程读取布局以支持更响应的用户界面而不会出现卡顿。
新的事件循环能够按照明确定义的顺序在 JavaScript 线程上处理任务。这使得 React 能够中断渲染以处理事件从而使紧急的用户事件能够优先于较低优先级的 UI 过渡。事件循环还与 Web 规范保持一致因此我们可以支持浏览器特性如微任务microtasks、MutationObserver 和 IntersectionObserver。
最后移除桥接允许更快的启动速度和 JavaScript 与原生运行时之间的直接通信从而最小化工作切换的成本。这也使得错误报告和调试更加完善减少了因未定义行为导致的崩溃。
新架构现已准备好用于生产环境。它已在 Meta 的 Facebook 应用和其他产品中大规模使用。我们在为 Quest 设备开发的 Facebook 和 Instagram 应用中成功使用了 React Native 和新架构。
我们的合作伙伴已经在生产环境中使用新架构数月了请查看 Expensify 和 Kraken 的成功案例并尝试 BlueSky 的新版本。
新的原生模块
新的原生模块系统是 JavaScript 与原生平台通信方式的重大重写。它完全使用 C 编写解锁了许多新功能
与原生运行时的同步访问JavaScript 与原生代码之间的类型安全跨平台的代码共享默认的懒加载模块
在新的原生模块系统中JavaScript 与原生层现在可以通过 JavaScript 接口JSI进行同步通信无需使用异步桥接。这意味着您的自定义原生模块现在可以同步调用一个函数返回一个值并将该值传递回另一个原生模块函数。
在旧架构中为了处理来自原生函数调用的响应您需要提供一个回调函数并且返回的值需要是可序列化的
// ❌ Sync callback from Native Module
nativeModule.getValue(value {// ❌ value cannot reference a native objectnativeModule.doSomething(value);
});在新架构中您可以对原生函数进行同步调用
// ✅ Sync response from Native Module
const value nativeModule.getValue();// ✅ value can be a reference to a native object
nativeModule.doSomething(value);有了新架构您终于可以利用 C 原生实现的全部能力同时仍然可以通过 JavaScript/TypeScript API 访问它。新的模块系统支持用 C 编写的模块因此您可以编写一次模块它可以在所有平台上工作包括 Android、iOS、Windows 和 macOS。用 C 实现模块允许更细粒度的内存管理和性能优化。
此外借助 Codegen您的模块可以在 JavaScript 层和原生层之间定义强类型的契约。根据我们的经验跨边界的类型错误是跨平台应用程序崩溃最常见的原因之一。Codegen 让您能够克服这些问题同时为您生成样板代码。
最后模块现在是懒加载的它们只有在实际需要时才加载到内存中而不是在启动时加载。这减少了应用程序的启动时间并在应用复杂性增加时保持较低的启动时间。
像 react-native-mmkv 这样的流行库已经从迁移到新的原生模块中受益 “新的原生模块极大地简化了 react-native-mmkv 的设置、自动链接和初始化。多亏了新架构react-native-mkv 现在是一个纯 C 原生模块这使它能够在任何平台上工作。新的 Codegen 使 MMKV 完全类型安全通过强制 null 安全性修复了长期存在的 NullPointerReference 问题并且能够同步调用原生模块函数使我们能够用新的原生模块 API 替换自定义的 JSI 访问。” 新的渲染器
我们还完全重写了原生渲染器带来了几个好处
更新可以在不同的线程上以不同的优先级进行渲染。布局可以同步读取并跨不同的线程进行。渲染器使用 C 编写并在所有平台上共享。
更新后的原生渲染器现在将视图层次结构存储在不可变的树结构中。这意味着 UI 以一种无法直接更改的方式存储允许线程安全地处理更新。这使得它能够处理多个进行中的树每个树代表用户界面的不同版本。因此更新可以在后台渲染而不会阻塞 UI例如在过渡期间或主线程响应用户输入。
通过支持多线程React 可以中断低优先级的更新来渲染紧急更新例如用户输入生成的更新然后根据需要恢复低优先级的更新。新的渲染器还可以同步地跨不同的线程读取布局信息。这使得低优先级的更新可以在后台计算并在需要时进行同步读取例如重新定位工具提示。
最后用 C 重写渲染器使其能够在所有平台上共享。这确保了相同的代码可以在 iOS、Android、Windows、macOS 以及任何其他 React Native 支持的平台上运行提供一致的渲染能力而无需为每个平台重新实现。
这是实现我们多平台愿景的重要一步。例如View Flattening 是一种仅用于 Android 的优化以避免深层次的布局树。新的渲染器采用共享的 C 核心将这一功能带到了 iOS。这种优化是自动的不需要设置随着共享渲染器一起免费提供。
通过这些更改React Native 现在完全支持并发 React 功能如 Suspense 和 Transitions使构建复杂的用户界面变得更加容易这些界面能够快速响应用户输入而不会出现卡顿、延迟或视觉跳跃。未来我们将利用这些新功能为内置组件如 FlatList 和 TextInput 带来更多改进。
像 Reanimated 这样流行的库已经开始利用新的渲染器 “Reanimated 4目前正在开发中引入了一个与新的渲染器直接协作的新动画引擎允许其在不同线程上处理动画和管理布局。新的渲染器的设计真正使这些功能能够在不依赖众多变通方法的情况下构建。此外由于它是用 C 实现并在所有平台上共享Reanimated 的大部分代码可以一次编写减少了平台特定的问题最小化了代码库并简化了对非树内平台的采用。” 事件循环
新架构使我们能够实现一个明确定义的事件循环处理模型如本 RFC 中所述。该 RFC 遵循 HTML 标准中描述的规范并描述了 React Native 如何在 JavaScript 线程上执行任务。
实现一个明确定义的事件循环弥合了 React DOM 和 React Native 之间的差距React Native 应用程序的行为现在更接近于 React DOM 应用程序的行为使其更易于一次性学习和在任何地方编写。
事件循环为 React Native 带来了许多好处
中断渲染以处理事件和任务的能力与 Web 规范更紧密的对齐为更多浏览器功能打下基础
借助事件循环React 能够可预测地排序更新和事件。这允许 React 用紧急的用户事件中断低优先级的更新而新的渲染器使我们能够独立渲染这些更新。
事件循环还使事件和任务如定时器的行为与 Web 规范保持一致这意味着 React Native 的工作方式更像用户在 Web 中熟悉的方式并且允许 React DOM 和 React Native 之间更好的代码共享。
它还允许实现更多符合规范的浏览器功能如微任务microtasks、MutationObserver 和 IntersectionObserver。这些功能在 React Native 中尚未准备好使用但我们正在努力在未来为您提供这些功能。
最后事件循环和新的渲染器的更改支持同步读取布局使 React Native 能够为 useLayoutEffect 提供适当的支持以同步读取布局信息并在同一帧中更新 UI。这使您能够在元素显示给用户之前正确定位它们。
有关更多详细信息请参阅 useLayoutEffect。
移除桥接
在新架构中我们还彻底移除了 React Native 对桥接的依赖改为使用 JSIJavaScript 接口进行 JavaScript 和原生代码之间的直接、高效通信 移除桥接通过避免桥接初始化来提升启动时间。例如在旧架构中为了向 JavaScript 提供全局方法我们需要在启动时在 JavaScript 中初始化一个模块这会导致应用启动时间略有延迟
// ❌ Slow initialization
import {NativeTimingModule} from NativeTimingModule;
global.setTimeout timer {NativeTimingModule.setTimeout(timer);
};// App.js
setTimeout(() {}, 100);在新架构中我们可以直接从 C 绑定方法
// ✅ Initialize directly in C
runtime.global().setProperty(runtime, setTimeout, createTimer);// App.js
setTimeout(() {}, 100);重写还改善了错误报告特别是在启动时的 JavaScript 崩溃并减少了因未定义行为导致的崩溃。如果发生崩溃新的 React Native 开发工具简化了调试过程并支持新架构。为了向后兼容桥接仍然保留以支持逐步迁移到新架构。未来我们将完全移除桥接代码。
渐进式迁移
我们预计大多数应用可以以与其他版本相同的努力程度升级到 0.76。
当您升级到 0.76 时新架构和 React 18 将默认启用。然而为了使用并发特性并充分利用新架构的所有优点您的应用和库需要逐步迁移以完全支持新架构。
在首次升级时您的应用将运行在新架构上并与旧架构通过自动互操作层进行交互。对于大多数应用来说这无需任何更改即可正常工作但互操作层存在已知的限制因为它不支持访问自定义 Shadow Nodes 或并发特性。
要使用并发特性应用还需要通过遵循 React 规则来更新以支持并发 React。要将您的 JavaScript 代码迁移到 React 18 及其语义请参阅 React 18 升级指南。
总体策略是让您的应用在不破坏现有代码的情况下运行在新架构上。然后您可以以自己的节奏逐步迁移应用。对于已将所有模块迁移到新架构的新界面您可以立即开始使用并发特性。对于现有界面您可能需要先解决一些问题并迁移模块然后再添加并发特性。
我们已与最流行的 React Native 库合作以确保对新架构的支持。超过 850 个库已兼容新架构包括所有每周下载量超过 20 万次的库约占下载库的 10%。您可以在 reactnative.directory 网站上检查库与新架构的兼容性 有关升级的更多详细信息请参阅下方的《如何升级》。
新功能
新架构全面支持 React 18、并发特性以及 React Native 中的 useLayoutEffect。有关 React 18 功能的完整列表请参阅 React 18 博客文章。
过渡Transitions
过渡是 React 18 中的一个新概念用于区分紧急更新和非紧急更新。
紧急更新反映了直接的交互如输入和点击。过渡更新则是将 UI 从一个视图过渡到另一个视图。
紧急更新需要立即响应以符合我们对物理对象行为的直觉。然而过渡更新则不同因为用户不期望在屏幕上看到每一个中间值。在新架构中React Native 能够分别支持渲染紧急更新和过渡更新。
通常为了获得最佳的用户体验单一的用户输入应导致一个紧急更新和一个非紧急更新。类似于 ReactDOM诸如点击press或更改change等事件被视为紧急的并立即渲染。您可以在输入事件中使用 startTransition API 来告知 React 哪些更新是“过渡”并且可以延迟到后台处理
import {startTransition} from react;// Urgent: Show the slider value
setCount(input);// Mark any state updates inside as transitions
startTransition(() {// Transition: Show the resultssetNumberOfTiles(input);
});将紧急事件与过渡分离可以实现更具响应性的用户界面以及更直观的用户体验。
以下是没有过渡的旧架构上与有过渡的新架构下的对比 有关更多信息请参阅《支持并发渲染器和功能》。
自动批处理
升级到新架构后您将受益于 React 18 中的自动批处理。自动批处理允许 React 在渲染时将更多的状态更新批量处理以避免渲染中间状态。这使得 React Native 更加快速并且不易出现卡顿而无需开发者编写任何额外代码。 在旧架构左侧中会渲染更多的中间状态即使滑块停止移动UI 仍会持续更新。新架构右侧由于自动批处理更新渲染的中间状态更少渲染完成得更快。
有关更多信息请参阅《支持并发渲染器和功能》。
useLayoutEffect
基于事件循环和同步读取布局的能力在新架构中我们为 React Native 增加了对 useLayoutEffect 的正确支持。
在旧架构中您需要使用异步的 onLayout 事件来读取视图的布局信息这也是异步的。因此至少会有一帧的布局是错误的直到布局被读取和更新这会导致工具提示等元素被放置在错误的位置例如
// ❌ async onLayout after commit
const onLayout React.useCallback(event {// ❌ async callback to read layoutref.current?.measureInWindow((x, y, width, height) {setPosition({x, y, width, height});});
}, []);// ...
ViewWithTooltiponLayout{onLayout}ref{ref}position{position}
/;新架构通过允许在 useLayoutEffect 中同步访问布局信息来解决这个问题
// ✅ sync layout effect during commit
useLayoutEffect(() {// ✅ sync call to read layoutconst rect ref.current?.getBoundingClientRect();setPosition(rect);
}, []);// ...
ViewWithTooltip ref{ref} position{position} /;这个更改允许您同步读取布局信息并在同一帧内更新 UI从而在元素显示给用户之前正确定位它们 有关更多信息请参阅《同步布局和效果》文档。
完整支持 Suspense
Suspense 允许您声明性地为组件树的一部分指定加载状态当该部分尚未准备好显示时可以显示一个备用内容
Suspense fallback{Spinner /}Comments /
/Suspense我们在几年前引入了有限版本的 Suspense而 React 18 则增加了对其的完整支持。直到现在React Native 尚未能够支持 Suspense 的并发渲染。
新架构包括 React 18 中引入的对 Suspense 的全面支持。这意味着您现在可以在 React Native 中使用 Suspense 来处理组件的加载状态并且被挂起的内容将在后台渲染而加载状态将被显示从而为可见内容的用户输入赋予更高的优先级。
更多信息请参阅 React 18 中的 Suspense RFC。
如何升级
要升级到 0.76请按照发布公告中的步骤进行。由于此版本也升级到了 React 18您还需要遵循 React 18 升级指南。
这些步骤对于大多数应用来说已经足够感谢新架构与旧架构之间的互操作层可以顺利升级到新架构。然而为了充分利用新架构并开始使用并发特性您需要迁移自定义的原生模块和原生组件以支持新的原生模块和原生组件 API。
如果不迁移自定义的原生模块您将无法享受到共享 C、同步方法调用或来自 Codegen 的类型安全的优势。如果不迁移原生组件您将无法使用并发特性。我们建议尽快将所有原生组件和原生模块迁移到新架构。
应用程序
如果您是应用开发者为了完全支持新架构您需要升级您的库、自定义原生组件和自定义原生模块以全面支持新架构。
我们已经与最流行的 React Native 库合作确保对新架构的支持。您可以在 reactnative.directory 网站上检查库与新架构的兼容性。
如果您的应用依赖的任何库尚未兼容您可以
在该库的仓库中提交一个 issue要求作者迁移到新架构。如果该库不再维护考虑使用具有相同功能的替代库。在这些库迁移期间选择不使用新架构。
如果您的应用有自定义的原生模块或自定义的原生组件感谢我们的互操作层我们预计它们可以正常工作。然而我们建议将它们升级到新的原生模块和原生组件 API以全面支持新架构并采用并发特性。
请按照以下指南将您的模块和组件迁移到新架构
原生模块原生组件
库
如果您是库的维护者请首先测试您的库是否与互操作层兼容。如果不兼容请在新架构工作组中提交一个 issue。
为了全面支持新架构我们建议尽快将您的库迁移到新的原生模块Native Module和原生组件Native ComponentAPI。这将使您的库的用户能够充分利用新架构并支持并发特性。
您可以参考以下指南将您的模块和组件迁移到新架构
原生模块原生组件
选择退出
如果由于任何原因新架构在您的应用中表现不正常您始终可以选择退出直到您准备好再次启用它。
要选择退出新架构
在 Android 上修改 android/gradle.properties 文件并关闭 newArchEnabled 标志
-newArchEnabledtrue
newArchEnabledfalse在 iOS 上您可以通过运行以下命令重新安装依赖
RCT_NEW_ARCH_ENABLED0 bundle exec pod install感谢
将新架构交付给开源社区是一项巨大的努力经过我们多年的研究和开发。我们想花一点时间感谢所有现任和曾经的 React 团队成员他们帮助我们实现了这一成果。
我们也非常感谢所有与我们合作的合作伙伴使这一切成为可能。具体来说我们要特别感谢
Expo感谢其早期采用新架构并支持迁移最流行库的工作。Software Mansion感谢其维护生态系统中的关键库早期将其迁移到新架构并在调查和修复各种问题上提供的帮助。Callstack感谢其维护生态系统中的关键库早期将其迁移到新架构并支持社区 CLI 的工作。微软感谢其为 react-native-windows 和 react-native-macos 以及其他多个开发工具添加新架构的实现。Expensify、Kraken、BlueSky 和 Brigad感谢它们在采用新架构方面的先锋作用并报告各种问题使我们能够为其他人修复这些问题。所有独立的库维护者和开发者感谢他们通过测试新架构、修复一些问题并就不明确的事项提出问题为我们澄清问题作出的贡献。