This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.

异步路由

编辑页面

了解如何通过 Expo Router 中的异步打包来加快开发速度。


Expo Router 可以使用 React Suspense 根据路由文件自动拆分你的 JavaScript bundle。这样可以加快开发速度,因为只有你导航到的路由才会被打包或加载到内存中。这对于减小应用的初始 bundle 大小也很有帮助。

使用 Hermes Engine 的应用不会从 bundle 拆分中获得太多收益,因为字节码已经提前映射到内存中。不过,它会提升你的空中更新、React Server Components 和 Web 支持。

工作原理

所有路由都会被包裹在一个 suspense 边界中,并异步加载。这意味着你第一次导航到某个路由时,加载会稍微慢一些。不过,一旦加载完成,它就会被缓存,后续访问将会立即显示。

加载错误会在父路由中通过 ErrorBoundary 导出项进行处理。

在开发过程中,异步路由无法被静态分析,因此即使文件没有导出默认组件,也会将所有文件视为路由。在组件完成打包并加载后,任何无效路由都会使用一个回退警告界面。

对于熟悉高级打包技术的人来说,异步路由功能由 React Suspense、基于路由的代码拆分 和 懒加载打包(开发中)组成。

设置

在 SDK 58 及更高版本中,异步路由在 Web 平台的开发和生产环境中默认启用。在原生平台上,默认情况下会禁用。在 SDK 57 及更早版本中,异步路由需要在每个平台上显式启用。

在你的应用配置的 Expo Router 配置插件中配置 asyncRoutes。要在 Web 平台上禁用异步路由,请将 asyncRoutes 设置为 { "web": false }。将 asyncRoutes 设置为 false 会在所有平台上禁用此功能:

app.json
{ "expo": { "plugins": [["expo-router", { "asyncRoutes": false }]] } }

你也可以使用 "development" 或 "production",仅在相应模式下启用异步路由;或者使用包含平台专属设置(default、android、ios 或 web)的对象:

  • 显式设置的平台值优先于 default。
  • 设置为 { "default": false } 时,除非通过 web 显式启用,否则会在 Web 平台上禁用异步路由。
  • 在 SDK 58 及更高版本中,仅设置原生平台会保留 Web 平台的默认设置。例如,{ "android": true } 等同于 { "android": true, "web": true }。原生生产构建仍会同步加载路由。

例如,以下配置会在两种模式下于 Web 平台启用异步路由,在开发模式下于 iOS 启用异步路由,同时在 Android 上禁用异步路由。在 SDK 57 及更早版本中,这也可作为显式启用配置:

app.json
{ "expo": { "plugins": [ [ "expo-router", { "origin": "https://acme.com", "asyncRoutes": { "web": true, "android": false, "default": "development" } } ] ] } }

更改此设置后,在启动或导出项目时,使用 --clear 清除 Metro 缓存:

Terminal
- npx expo start --clear

# 或在导出时
- npx expo export --clear
- yarn expo start --clear

# 或在导出时
- yarn expo export --clear
- pnpm expo start --clear

# 或在导出时
- pnpm expo export --clear
- bun expo start --clear

# 或在导出时
- bun expo export --clear

静态渲染

在生产版 Web 应用中,静态渲染通过在 Node.js 中同步渲染所有 Suspense 边界来实现,然后根据某个 HTML 文件所选中的所有路由,将所有异步 chunk 连接到 HTML 中。这可以确保你在服务器导航时不会遇到一连串的加载状态。后续导航会递归加载任何缺失的 chunk。

为了确保首次渲染的一致性,通向某个 URL 的叶子路由之前的所有布局路由都会包含在初始服务器响应中。

所有锚点路由(使用 unstable_settings = { anchor: '...' } 定义)都会包含在初始 HTML 文件中,因为它们是首次渲染所必需的。例如,如果服务器请求的是一个模态页面,那么模态页面下方渲染的屏幕也会包含在内,以确保模态页面能够正确渲染。

注意事项

异步路由存在以下限制:

  • 异步路由尚不支持原生生产应用。
  • 在开发过程中,运行时 JavaScript 会延迟打包,因此你可能会遇到 HTML 与可用 JavaScript 不匹配的情况。
  • 自定义 SuspenseFallback 导出项无法与异步路由配合使用。在 SDK 58 及更高版本中,除非禁用了异步路由,否则 Web 应用会使用默认加载回退界面。若要保留自定义回退界面,请在 expo-router 配置插件中设置 asyncRoutes: { web: false }。应用配置示例请参阅迁移指南。