首页指南参考教程

异步路由

了解如何在 Expo Router 中使用异步打包来加速开发。


异步路由是一项实验性功能。

Expo Router 可以使用 反应悬念.5 根据路由文件自动分割你的 JavaScript 包。这可以实现更快的开发,因为只有你导航到的路由才会被打包或加载到内存中。这对于减少应用的初始包大小也很有用。

¥Expo Router can automatically split your JavaScript bundle based on the route files using React Suspense. This enables faster development as only the routes you navigate to will be bundled or loaded into memory. This can also be useful for reducing the initial bundle size for your application.

使用 Hermes 引擎的应用不会从包分割中获益那么多,因为字节码已经提前进行了内存映射。但是,它将改进你的无线更新、React 服务器组件和 Web 支持。

¥Apps using the Hermes Engine will not benefit as much from bundle splitting as the bytecode is already memory mapped ahead of time. However, it will improve your over-the-air updates, React Server Components, and web support.

在原生平台上打包生产时,所有悬念边界将被禁用,并且不会有加载状态。

¥When bundling for production on native platforms, all suspense boundaries will be disabled and there will be no loading states.

工作原理

¥How it works

所有路由都包含在悬念边界内并异步加载。这意味着你第一次导航到路由时,加载时间会稍长一些。但是,一旦加载,就会被缓存,后续访问将是即时的。

¥All Routes are wrapped inside a suspense boundary and are loaded asynchronously. This means that the first time you navigate to a route, it will take a little longer to load. However, once it is loaded, it will be cached and subsequent visits will be instant.

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

¥Loading errors are handled in the parent route, via the ErrorBoundary export.

异步路由在开发过程中无法进行静态分析,因此所有文件都将被视为路由,即使它们不导出默认组件。组件打包并加载后,任何无效的路由都将使用后备警告屏幕。

¥Async routes cannot be statically analyzed during development, so all files will be treated as routes even if they don't export a default component. After the component is bundled and loaded, any invalid route will use a fallback warning screen.

对于熟悉高级打包技术的人来说,异步路由功能由 反应悬念基于路由的打包分割懒惰打包(正在开发中)组成。

¥For those familiar with advanced bundling techniques, the async routes feature is composed of React Suspense, route-based bundle splitting and lazy bundling (in development).

设置

¥Setup

通过在 应用配置 的 Expo Router 配置插件中设置 asyncRoutes 选项来启用该功能:

¥Enable the feature by setting the asyncRoutes option in the Expo Router config plugin of your app config:

SDK 50 及以上版本支持生产包拆分。将 asyncRoutes 设置为 true 以启用它。

¥SDK 50 and above supports production bundle splitting. Set asyncRoutes to true to enable it.

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

你可以使用对象为 asyncRoutes 设置特定于平台的设置(defaultandroidiosweb):

¥You can set platform-specific settings (default, android, ios or web) for asyncRoutes using an object:

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

然后,当你即将启动项目时,可以使用 --clear 标志来清除 Metro 缓存。这将确保路由异步加载:

¥Then, when you are about to start your project, you can use the --clear flag to clear the Metro cache. This will ensure that the routes are loaded asynchronously:

Terminal
npx expo start --clear

# Or when exporting
npx expo export --clear

静态渲染

¥Static rendering

仅 SDK 50 及更高版本支持使用静态渲染进行打包拆分。

¥Bundle splitting with static rendering is only supported in SDK 50 and above.

生产 Web 应用支持静态渲染,方法是在 Node.js 中同步渲染所有 Suspense 边界,然后根据给定 HTML 文件的所有选定路由将 HTML 中的所有异步块链接在一起。这可确保你不会在服务器导航中遇到加载状态瀑布式的情况。后续导航将递归加载任何丢失的块。

¥Static rendering is supported in production web apps by rendering all Suspense boundaries synchronously in Node.js, then linking all of async chunks together in the HTML based on all the selected routes for a given HTML file. This ensures you don't encounter a waterfall of loading states on server navigations. Subsequent navigations will recursively load any missing chunks.

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

¥To ensure a consistent first render, all layout routes leading up to the leaf route for a URL will be included in the initial server response.

使用 unstable_settings = { initialRouteName: '...' } 定义的所有初始路由将包含在初始 HTML 文件中,因为它们是第一次渲染所必需的。例如,如果服务器请求是针对模态的,则还将包括模态下渲染的屏幕,以确保模态正确渲染。

¥All initial routes, defined with unstable_settings = { initialRouteName: '...' } will be included in the initial HTML file as they are required for the first render. For example, if the server request is for a modal, the screen rendered under the modal will also be included to ensure the modal is rendered correctly.

注意事项

¥Caveats

异步路由代表了我们未来计划如何支持 反应服务器组件 的早期预览。因此,有一些注意事项需要注意:

¥Async Routes represents an early preview of how we plan to support React Server Components in the future. As such, there are some caveats to be aware of:

  • 异步路由尚不支持原生生产应用。

    ¥Async Routes do not support native production apps yet.

  • 在开发过程中,运行时 JavaScript 是惰性打包的,因此你可能会遇到 HTML 与可用 JavaScript 不匹配的情况。

    ¥In development, the runtime JavaScript is lazily bundled so you may encounter cases where the HTML doesn't match the available JavaScript.

  • 目前无法自定义加载状态。

    ¥The loading state cannot be customized at this time.

Expo 中文网 - 粤ICP备13048890号