React Router v7 已发布。 查看文档
惰性路由发现
本页内容

延迟路由发现(又名“战争迷雾”)

Remix 引入了对延迟路由发现(又名“战争迷雾”)的支持(RFC),该功能通过 future.unstable_lazyRouteDiscovery 未来标志v2.10.0 版本中启用(后来在 v2.13.0 版本中稳定为 future.v3_lazyRouteDiscovery)。这允许你选择启用此行为,该行为将成为 Remix 下一个主要版本(即 React Router v7)中的默认行为(1, 2)。有关此功能的更多信息,请查看博客文章

当前行为

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

新行为

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

请注意,这**不是**一种向最终用户“隐藏”你的任何应用程序 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/边缘缓存层,则 /__manifest 路由接受 2 个查询字符串参数,你可能需要在缓存键中包含它们:versionp
    • ⚠️ 这被认为是内部实现细节,不应由应用程序代码请求
文档和示例根据以下许可: MIT