异步路由
了解如何在 Expo Router 中使用异步打包来加速开发。
重要 异步路由仍处于测试阶段。
Expo Router 可以根据路由文件使用 React Suspense 自动拆分你的 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 服务器组件和网络支持。
🌐 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.
在针对 本地平台 进行生产打包时,所有 suspense 边界 将被禁用,并且不会有加载状态。
工作原理
🌐 How it works
所有路由都被封装在 Suspense 边界内,并且是异步加载的。这意味着第一次导航到某个路由时,加载会稍微慢一些。不过,一旦加载完成,它将被缓存,后续访问将会是即时的。
🌐 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.
/* 目前 Suspense fallback 或加载状态 无法自定义。我们计划在将来通过 route+loading.js 文件添加支持。 */
加载错误在父路由中处理,通过 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.
对于熟悉高级打包技术的人来说,异步路由功能由 React Suspense、基于路由的代码拆分 和 懒加载打包(在开发中)组成。
🌐 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:
将
asyncRoutes设置为true以启用生产环境的包拆分。
{ "expo": { "plugins": [ [ "expo-router", { "origin": "https://acme.com", "asyncRoutes": { "web": true, "default": "development" } } ] ] } }
你可以使用一个对象为 asyncRoutes 设置特定平台的设置(default、android、ios 或 web):
🌐 You can set platform-specific settings (default, android, ios or web) for asyncRoutes using an object:
{ "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:
- npx expo start --clear# Or when exporting- npx expo export --clear静态渲染
🌐 Static rendering
在生产环境的 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
异步路由展示了我们未来如何支持 React 服务器组件 的早期预览。因此,有一些需要注意的事项:
🌐 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:
- 异步路由尚不支持原生生产应用。
- 在开发过程中,运行时 JavaScript 是惰性打包的,因此你可能会遇到 HTML 与可用 JavaScript 不匹配的情况。
- 目前无法自定义加载状态。