TL;DR: TanStack Router 支持基于路由的自动代码分割,并提供了多种预加载策略:基于悬停、基于视口以及编程式预加载。本指南将带你了解如何懒加载路由组件、在链接悬停时进行预加载、管理预加载路由的缓存,以及衡量预加载效果的最佳实践。
引言
随着 SaaS 应用的不断扩展,JavaScript 的构建产物(bundle)体积也会随之增大。最原始的方案通常会一次性预先加载所有的路由资源,这严重拖慢了初始页面的加载速度。由于 TanStack Router 支持自动代码分割,每个路由的组件和加载器(loader)代码都会被打包成独立的代码块(chunk),并在需要时才进行加载。
结合预加载技术,你甚至可以在用户实际点击之前,提前开始加载对应路由的代码与数据,从而让导航体验产生近乎瞬间完成的清爽感。
结合懒加载的代码分割
// src/routes/dashboard.tsx
import { createFileRoute, lazyRouteComponent } from '@tanstack/react-router'
export const Route = createFileRoute('/dashboard')({
component: lazyRouteComponent(() => import('./dashboard.component')),
loader: () => import('./dashboard.loader').then(m => m.loadDashboardData),
})
在构建输出中,每个路由文件都会生成一个独立的代码块。TanStack Router 会在底层自动处理所有的加载状态。
基于悬停的预加载策略
import { Link } from '@tanstack/react-router'
function NavLink({ to, children }: { to: string; children: React.ReactNode }) {
const router = useRouter()
return (
<Link
to={to}
onMouseEnter={() => router.preloadRoute({ to })}
onTouchStart={() => router.preloadRoute({ to })}
>
{children}
</Link>
)
}
预加载策略汇总
| 策略 | 触发条件 | 适用场景 | 成本 |
|---|---|---|---|
| 基于悬停 | 鼠标悬停 | 桌面端导航 | 低 |
| 基于视口 | Intersection Observer | 首屏折叠线以下的链接 | 中 |
| 编程式 | 页面加载完成后 | 下一个极可能访问的页面 | 低 |
| 所有路由 | 应用挂载时 | 小型应用 | 高 |
| 预测性 | 基于机器学习的预测 | 大型应用 | 极高 |
衡量预加载的有效性
跟踪已被预加载的路由在实际情况中的访问频率:
router.subscribe('onResolved', (event) => {
if (event.wasPreloaded) {
analytics.track('navigation_preloaded', { to: event.to })
}
})
结论
在 TanStack Router 中采用路由预加载与代码分割技术,能为你带来极速的初始页面加载以及无缝的瞬间导航体验。其中,基于悬停的预加载策略在追求性能提升与平衡带宽成本两方面表现极佳。
如需探索更多的高级路由模式,请参阅 TanStack Router 高阶模式。你还可以将代码分割与 JavaScript 产物分割模式 结合使用,从而实现更细粒度的控制。建议参照 Core Web Vitals 优化指南 来衡量你所取得的改进成果,并运用针对 SaaS 性能预算 的最佳实践,杜绝未来的代码库中出现性能倒退的问题。