本页还没有译文
本页 52 段还没译成简体中文,下面显示的是英文原文。Preloading
还没翻译译自英文(tanstack.com)本页 52 段都还没译
要点(模型写的)
- TanStack Router 支持三种预加载策略:intent、viewport 可见性和 render,每种策略在不同的 Link 事件上触发。
- 预加载的 loader 结果默认保持新鲜 30 秒,未使用的条目在修剪前保留 5 分钟。
- intent 的聚焦/悬停和 viewport 预加载默认等待 50ms,触摸 intent 会立即预加载;设置 defaultPreloadDelay 或 preloadDelay 可更改此行为。
- 新鲜度和保留期是分开的:preloadStaleTime 控制无需再次调用 loader 即可复用,而 preloadGcTime 使未使用的结果在下一次协调时符合修剪条件。
- 将 defaultPreloadStaleTime 或 preloadStaleTime 设置为 0,以便由 React Query 等外部缓存决定新鲜度,同时保留期仍遵循 preloadGcTime。
模型写的
背景主张方法设置结果分析局限
Preloading in TanStack Router is a way to load a route before the user actually navigates to it. This is useful for routes that are likely to be visited by the user next. For example, if you have a list of posts and the user is likely to click on one of them, you can preload the post route so that it's ready to go when the user clicks on it.Preloading in TanStack Router is a way to load a route before the user actually navigates to it. This is useful for routes that are likely to be visited by the user next.预加载会在用户导航到路由之前提前加载该路由 它提前准备好用户可能访问的路由,例如文章页,点击时即可使用预加载会在用户导航到路由之前提前加载该路由预加载
Supported Preloading Strategies
意图、视口和渲染三种策略用于预加载路由
- Intent
- Preloading by "intent" works by using hover and touch start events on
<Link>components to preload the dependencies for the destination route.Preloading by "intent" works by using hover and touch start events on <Link> components to preload the dependencies for the destination route.意图预加载使用 Link 上的悬停和触摸开始事件 这些事件表明用户打算接下来访问目标路由意图预加载使用 Link 上的悬停和触摸开始事件意图预加载 - This strategy is useful for preloading routes that the user is likely to visit next.This strategy is useful for preloading routes that the user is likely to visit next.意图预加载适合用户接下来可能访问的路由 它以悬停时的小量加载换取点击时的即时导航意图预加载适合用户接下来可能访问的路由意图预加载
- Viewport Visibility
- Preloading by "viewport" works by using the Intersection Observer API to preload the dependencies for the destination route when the
<Link>component is in the viewport.Preloading by "viewport" works by using the Intersection Observer API to preload the dependencies for the destination route when the <Link> component is in the viewport.视口预加载使用 Link 上的 Intersection Observer API 当 Link 组件进入视口时,它便加载目标路由的依赖视口预加载使用 Link 上的 Intersection Observer API视口预加载 - This strategy is useful for preloading routes that are below the fold or off-screen.This strategy is useful for preloading routes that are below the fold or off-screen.视口预加载适合首屏以下或屏幕外的路由 用户滚动接近这些链接时,它们才会出现在视口中视口预加载适合首屏以下或屏幕外的路由视口预加载
- Render
- Preloading by "render" works by preloading the dependencies for the destination route as soon as the
<Link>component is rendered in the DOM.Preloading by "render" works by preloading the dependencies for the destination route as soon as the <Link> component is rendered in the DOM.渲染预加载在 Link 渲染到 DOM 时立即加载依赖 它无需用户交互,因此依赖会立即开始加载渲染预加载在 Link 渲染到 DOM 时立即加载依赖渲染预加载 - This strategy is useful for preloading routes that are always needed.This strategy is useful for preloading routes that are always needed.渲染预加载适合始终需要的路由 确定会被访问的路由值得在任何交互之前就加载渲染预加载适合始终需要的路由渲染预加载
How long does preloaded data stay in memory?
预加载数据默认新鲜 30 秒、保留 5 分钟
Successful preloaded loader results can enter the router's in-memory cache with two independent policies:Successful preloaded loader results can enter the router's in-memory cache with two independent policies:预加载的 loader 结果按两种策略进入内存缓存 新鲜度和未使用保留期是分别独立配置的预加载的 loader 结果按两种策略进入内存缓存缓存策略
- Freshness defaults to 30 seconds. Configure it with
defaultPreloadStaleTimeor a route'spreloadStaleTime.Freshness defaults to 30 seconds. Configure it with defaultPreloadStaleTime or a route's preloadStaleTime.预加载新鲜度默认 30 秒 可通过 defaultPreloadStaleTime 或路由的 preloadStaleTime 设置预加载新鲜度默认 30 秒预加载新鲜度 - The unused retention window defaults to 5 minutes. Configure it with
defaultPreloadGcTimeor a route'spreloadGcTime. Older unused entries are eligible for pruning during a later cache reconciliation.The unused retention window defaults to 5 minutes. Configure it with defaultPreloadGcTime or a route's preloadGcTime. Older unused entries are eligible for pruning during a later cache reconciliation.未使用的预加载保留期默认 5 分钟 更旧的未使用条目会在后续缓存清理时有资格被修剪未使用的预加载保留期默认 5 分钟预加载保留期 - The speculative lane is never promoted into router state. Navigation creates its own presentation and runs its own
beforeLoadchain. It can reuse cached loader data or join a loader that is still in flight.The speculative lane is never promoted into router state. Navigation creates its own presentation and runs its own beforeLoad chain. It can reuse cached loader data or join a loader that is still in flight.推测车道永远不会被提升为 router 状态 导航会运行自己的 beforeLoad 和呈现,但可复用已缓存的 loader 数据推测车道永远不会被提升为 router 状态推测车道
If you need more control over preloading, caching and/or garbage collection of preloaded data, you should use an external caching library like TanStack Query.If you need more control over preloading, caching and/or garbage collection of preloaded data, you should use an external caching library like TanStack Query.需要更多缓存控制时使用 TanStack Query 等外部缓存库 它提供对预加载、缓存和垃圾回收更精细的控制需要更多缓存控制时使用 TanStack Query 等外部缓存库TanStack Query
The simplest way to preload routes for your application is to set the defaultPreload option to intent for your entire router:The simplest way to preload routes for your application is to set the defaultPreload option to intent for your entire router:在 router 上将 defaultPreload 设为 intent 即可全局启用预加载 这是为整个应用预加载路由最简单的方式在 router 上将 defaultPreload 设为 intent 即可全局启用预加载defaultPreload
import { createRouter } from '@tanstack/react-router'
const router = createRouter({
// ...
defaultPreload: 'intent',
})This will turn on intent preloading by default for all <Link> components in your application. You can also set the preload prop on individual <Link> components to override the default behavior.This will turn on intent preloading by default for all <Link> components in your application. You can also set the preload prop on individual <Link> components to override the default behavior.defaultPreload 为所有 Link 组件启用意图预加载 各个 Link 组件上的 preload 属性可以覆盖该默认行为defaultPreload 为所有 Link 组件启用意图预加载意图预加载
Preload Delay
意图和视口预加载默认延迟 50ms 后启动
By default, intent focus/hover and viewport preloading start after 50ms. Pending preloads are cancelled if focus or hover ends, or the link leaves the viewport. Touch intent preloads immediately. You can change this delay by setting the defaultPreloadDelay option on your router:By default, intent focus/hover and viewport preloading start after 50ms. Pending preloads are cancelled if focus or hover ends, or the link leaves the viewport. Touch intent preloads immediately.意图和视口预加载默认延迟 50ms 后启动 悬停或聚焦结束时取消待处理预加载,但触摸会立即预加载意图和视口预加载默认延迟 50ms 后启动预加载延迟
import { createRouter } from '@tanstack/react-router'
const router = createRouter({
// ...
defaultPreloadDelay: 100,
})You can also set the preloadDelay prop on individual <Link> components to override the default behavior on a per-link basis.You can also set the preloadDelay prop on individual <Link> components to override the default behavior on a per-link basis.preloadDelay 属性可按链接覆盖默认延迟 它让每个 Link 组件设置自己的预加载延迟preloadDelay 属性可按链接覆盖默认延迟preloadDelay
Built-in Preloading, Freshness, and Retention
preloadStaleTime 控制新鲜度,preloadGcTime 控制保留,两者独立
If you're using the built-in loaders, you can control how long preloaded data is considered fresh by setting either routerOptions.defaultPreloadStaleTime or routeOptions.preloadStaleTime to a number of milliseconds. By default, preloaded data is considered fresh for 30 seconds.If you're using the built-in loaders, you can control how long preloaded data is considered fresh by setting either routerOptions.defaultPreloadStaleTime or routeOptions.preloadStaleTime to a number of milliseconds. By default, preloaded data is considered fresh for 30 seconds.预加载数据默认新鲜 30 秒 可通过以毫秒计的 defaultPreloadStaleTime 或 preloadStaleTime 修改预加载数据默认新鲜 30 秒预加载数据
Freshness and retention are separate. preloadStaleTime controls whether the
retained loader result can be reused without another loader call.
preloadGcTime (or defaultPreloadGcTime) controls when an unused preload
result becomes eligible for pruning during a later cache reconciliation; it
does not schedule a timer to evict the result at that exact moment. Both preload
GC options default to 5 minutes.Freshness and retention are separate. preloadStaleTime controls whether the
retained loader result can be reused without another loader call. preloadGcTime (or defaultPreloadGcTime) controls when an unused preload
result becomes eligible for pruning during a later cache reconciliation; it
does not schedule a timer to evict the result at that exact moment.新鲜度与保留期分离;两个预加载 GC 选项默认均为 5 分钟 preloadGcTime 只让结果有资格被修剪,并不安排定时器新鲜度与保留期分离;两个预加载 GC 选项默认均为 5 分钟保留期
To change this, you can set the defaultPreloadStaleTime option on your router:To change this, you can set the defaultPreloadStaleTime option on your router:在 router 上设置 defaultPreloadStaleTime 可改变新鲜度 示例中将其设为 10_000 毫秒在 router 上设置 defaultPreloadStaleTime 可改变新鲜度defaultPreloadStaleTime
import { createRouter } from '@tanstack/react-router'
const router = createRouter({
// ...
defaultPreloadStaleTime: 10_000,
})Or, you can use the routeOptions.preloadStaleTime option on individual routes:Or, you can use the routeOptions.preloadStaleTime option on individual routes:routeOptions.preloadStaleTime 可覆盖单个路由的新鲜度 示例中预加载数据超过 10 秒后就会重新加载routeOptions.preloadStaleTime 可覆盖单个路由的新鲜度preloadStaleTime
// src/routes/posts.$postId.tsx
export const Route = createFileRoute('/posts/$postId')({
loader: async ({ params }) => fetchPost(params.postId),
// Reload preloaded data when it is more than 10 seconds old
preloadStaleTime: 10_000,
})Client-side preloading runs each route's beforeLoad with preload: true.
Every later preload or navigation runs its own beforeLoad chain, so a
navigation observes preload: false even when an identical preload is still
active. A later lane can reuse successful settled loader data or join loader
work that is still in flight, but it never reuses beforeLoad context or an
already-settled redirect, error, or not-found result. If joined loader work
later produces a terminal outcome, all current consumers of that flight observe
it. The shouldReload option remains loader-only.Client-side preloading runs each route's beforeLoad with preload: true. Every later preload or navigation runs its own beforeLoad chain, so a
navigation observes preload: false even when an identical preload is still
active. A later lane can reuse successful settled loader data or join loader
work that is still in flight, but it never reuses beforeLoad context or an
already-settled redirect, error, or not-found result.每次预加载或导航都运行自己的 beforeLoad 链 只有 loader 数据可共享,beforeLoad 上下文和已定的错误或重定向从不共享每次预加载或导航都运行自己的 beforeLoad 链beforeLoad 链
If a route has preload: false, its speculative lane still runs beforeLoad,
but skips that route's loader. Navigation runs beforeLoad again and performs
the skipped loader work.If a route has preload: false, its speculative lane still runs beforeLoad,
but skips that route's loader. Navigation runs beforeLoad again and performs
the skipped loader work.设置 preload 为 false 时,推测车道跳过该路由的 loader 导航会再次运行 beforeLoad 并执行被跳过的 loader 工作设置 preload 为 false 时,推测车道跳过该路由的 loaderpreload false
Preloading with External Libraries
将 preloadStaleTime 设为 0,让外部缓存决定新鲜度
When integrating external caching libraries like React Query, which have their own mechanisms for determining stale data, you may want to override the default preloading and stale-while-revalidate logic of TanStack Router. These libraries often use options like staleTime to control the freshness of data.When integrating external caching libraries like React Query, which have their own mechanisms for determining stale data, you may want to override the default preloading and stale-while-revalidate logic of TanStack Router. These libraries often use options like staleTime to control the freshness of data.外部缓存库有自己的过期数据判定机制 它们通常使用 staleTime 之类的选项来控制数据新鲜度外部缓存库有自己的过期数据判定机制过期数据
To let an external cache make the freshness decision, set
routerOptions.defaultPreloadStaleTime or routeOptions.preloadStaleTime to
0. Settled preload data then becomes immediately stale in the Router, while
retention still follows preloadGcTime. Overlapping preload or navigation
consumers can still share in-flight loader work, and shouldReload can still
suppress a loader call.To let an external cache make the freshness decision, set
routerOptions.defaultPreloadStaleTime or routeOptions.preloadStaleTime to
0. Settled preload data then becomes immediately stale in the Router, while
retention still follows preloadGcTime. Overlapping preload or navigation
consumers can still share in-flight loader work, and shouldReload can still
suppress a loader call.将 preloadStaleTime 设为 0,让外部缓存决定新鲜度 已完成的预加载数据立即过期,保留期仍遵循 preloadGcTime将 preloadStaleTime 设为 0,让外部缓存决定新鲜度preloadStaleTime
For example:
import { createRouter } from '@tanstack/react-router'
const router = createRouter({
// ...
defaultPreloadStaleTime: 0,
})This would then allow you, for instance, to use an option like React Query's staleTime to control the freshness of your preloads.This would then allow you, for instance, to use an option like React Query's staleTime to control the freshness of your preloads.这样 React Query 的 staleTime 就能控制预加载新鲜度 外部库自己的新鲜度设置接管了这一决定这样 React Query 的 staleTime 就能控制预加载新鲜度staleTime
Preloading Manually
使用 preloadRoute 或 loadRouteChunk 手动预加载
If you need to manually preload a route, use the router's preloadRoute method.
It accepts a standard TanStack NavigateOptions object and returns the
speculative match lane. An ordinary error or not-found thrown while loading is
represented in that returned lane; cancellation or control flow that produces
no reusable lane can return undefined.If you need to manually preload a route, use the router's preloadRoute method. It accepts a standard TanStack NavigateOptions object and returns the
speculative match lane. An ordinary error or not-found thrown while loading is
represented in that returned lane; cancellation or control flow that produces
no reusable lane can return undefined.router.preloadRoute 手动预加载路由并返回推测匹配车道 它接受 NavigateOptions;错误体现在车道中,取消可能返回 undefinedrouter.preloadRoute 手动预加载路由并返回推测匹配车道preloadRoute
import { isNotFound } from '@tanstack/react-router'
function Component() {
const router = useRouter()
useEffect(() => {
async function preload() {
const matches = await router.preloadRoute({
to: postRoute,
params: { id: 1 },
})
const routeFailure = matches?.find(
(match) =>
match.status === 'error' ||
match.status === 'notFound' ||
isNotFound(match.error),
)
if (routeFailure) {
// Inspect routeFailure.error
}
}
preload()
}, [router])
return <div />
}If you need to preload only the JS chunk of a route, you can use the router's loadRouteChunk method. It accepts a route object and returns a promise that resolves when the route chunk is loaded.If you need to preload only the JS chunk of a route, you can use the router's loadRouteChunk method. It accepts a route object and returns a promise that resolves when the route chunk is loaded.router.loadRouteChunk 只预加载路由的 JS chunk 它接受路由对象,并在该 chunk 加载完成后解析router.loadRouteChunk 只预加载路由的 JS chunkloadRouteChunk
function Component() {
const router = useRouter()
useEffect(() => {
async function preloadRouteChunks() {
try {
const postsRoute = router.routesByPath['/posts']
await Promise.all([
router.loadRouteChunk(router.routesByPath['/']),
router.loadRouteChunk(postsRoute),
router.loadRouteChunk(postsRoute.parentRoute),
])
} catch (err) {
// Failed to preload route chunk
}
}
preloadRouteChunks()
}, [router])
return <div />
}