跳转到内容

Lazy Route Discovery

惰性路由发现(又称战争迷雾

Remix 在 v2.10.0 中的 future.unstable_lazyRouteDiscovery Future Flag 后面引入了对 Lazy Route Discovery(又名战争迷雾)(RFC)的支持(后来在 v2.13.0 中稳定为 future.v3_lazyRouteDiscovery)。这允许您选择启用此行为,该行为将成为 Remix 的下一个主要版本(又名 React Router v7(12))中的默认行为。有关此功能的更多信息,请查看 博客文章

当前行为

目前,Remix 在初始加载时将完整的路由清单加载到 JS 文件中(即 /assets/manifest-[hash].js)。清单不包含路由模块实现,而是包含它们的 URL 路径和元信息(路由 JS/CSS 导入、它们是否在服务器上具有 loader/action 等)。预先拥有这个完整的清单允许 Remix 在链接点击时进行同步客户端路由匹配,并立即启动路由模块和数据的加载。对于中小型应用程序,预先加载完整的清单通常并不困难,因为它具有高度可缓存性和相当好的 gzip 压缩能力。然而,我们发现,在规模化时,这个清单可能会变得足够大,从而影响某些性能指标。

新行为

启用战争迷雾后,Remix 将不再在初始加载时发送完整的路由清单。相反,您的 SSR 渲染将仅包含初始清单中的 SSR 路由,并且用户在应用程序中导航时将加载其他路由。随着时间的推移,清单会逐渐增长,以包含用户导航到的应用程序部分。

请注意,这不是向最终用户隐藏任何应用程序 URL 的方法。它最初不会在清单中提供所有 URL,但用于在用户导航时获取新路由的清单端点仍然能够公开您定义的所有应用程序路由 - 尽管只是稍微模糊了一点。

渴望路由发现

一如既往,这种惰性路由发现方式也存在弊端。它缩短了应用程序的初始加载时间,但 Remix 无法再对链接点击执行同步路由匹配,这可能会导致瀑布流。

在当前架构中(不使用 <Link prefetch>),单击链接将如下所示:

click /a
|-- load route module -->
|-- load route data -->
| render /a

在战争迷雾架构中,点击一个链接就会出现瀑布图:

click /a
|-- discover route -->
|-- load route module -->
|-- load route data -->
| render /a

众所周知,Remix 讨厌瀑布,因此战争迷雾功能实施了一项优化,以在大多数情况下避免瀑布。默认情况下,页面上呈现的所有 <Link><NavLink> 组件将被批量处理,并通过向服务器发出请求来急切地发现。此请求将匹配服务器上所有当前链接路径并发回所有必需的路由清单条目。在大多数情况下,此请求应在用户单击任何链接之前完成(因为用户通常不会在最初几百毫秒内单击链接),并且清单将在单击任何链接之前进行修补。然后,当单击链接时,Remix 能够进行同步客户端匹配,就好像战争迷雾行为根本不存在一样。

如果您希望在每个链接的基础上退出此热切的路由发现,您可以通过 discover="none" 属性来实现(默认值为 discover="render")。

显著变化

  • 启用此功能后,window.__remixManifest.routes 中的路由清单将仅包含初始 SSR 上所需的最少路由,并且路由将在用户导航时动态添加到其中
  • Remix 处理程序现在有一个新的内部 /__manifest 端点,它将通过该端点获取清单补丁
  • 您需要确保您的部署架构将所有 /__manifest 请求路由到 Remix 处理程序
  • 如果您有任何 CDN/Edge 缓存层,/__manifest 路由将接受您可能需要包含在缓存键中的 2 个查询字符串参数:versionp
  • ⚠️ 这被视为内部实现细节,不打算由应用程序代码请求