路由懒加载
路由懒加载是一种按需加载组件的策略,只在用户访问对应路由时才加载组件代码,从而减小初始包体积、加快首屏加载速度。
使用 lazy 函数
vitarx-router 使用 vitarx 提供的 lazy 函数实现组件懒加载:
tsx
import { lazy } from 'vitarx'
import { createRouter } from 'vitarx-router'
const router = createRouter({
routes: [
{
path: '/',
component: Home // 同步加载
},
{
path: '/user/{id}',
component: lazy(() => import('./pages/User.tsx')) // 懒加载
}
]
})lazy(() => import(...)) 会将组件代码分离为独立的 chunk,仅在路由被访问时才加载。
命名视图懒加载
命名视图同样支持懒加载,每个视图可以独立配置:
tsx
const router = createRouter({
routes: [
{
path: '/dashboard',
component: {
default: lazy(() => import('./pages/Dashboard.tsx')),
sidebar: lazy(() => import('./pages/DashboardSidebar.tsx'))
}
}
]
})文件路由的导入模式
使用文件路由时,可以通过 importMode 选项控制组件的导入方式:
‘lazy’(默认)
生成懒加载表达式,组件按需加载:
ts
// vite.config.ts
VitarxRouter({ importMode: 'lazy' })
// 生成的代码
const routes = [
{
path: '/about',
component: lazy(() => import('/src/pages/about.tsx'))
}
]‘sync’
生成静态导入语句,组件在初始化时全部加载:
ts
// vite.config.ts
VitarxRouter({ importMode: 'sync' })
// 生成的代码
import About from '/src/pages/about.tsx'
const routes = [
{
path: '/about',
component: About
}
]自定义函数
通过函数自定义导入逻辑,可以实现更灵活的加载策略:
ts
// vite.config.ts
VitarxRouter({
importMode: context => {
// 首页同步加载,其他页面懒加载
if (context.filePath.endsWith('index.tsx')) {
return 'sync'
}
return 'lazy'
}
})自定义函数的 context 参数包含:
ts
interface ImportModeContext {
/** 组件文件路径(已 JSON.stringify) */
importPath: string
/** 组件文件原始路径 */
filePath: string
/** 添加导入语句到生成的代码顶部 */
addImport: (statement: string) => void
}预加载
router.resolveComponents() 方法可以预加载当前路由匹配到的所有异步组件:
ts
// 预加载当前路由的异步组件
await router.resolveComponents()
// 预加载指定路由的异步组件
const route = router.matchRoute({ index: '/user/123' })
if (route) {
await router.resolveComponents(route)
}INFO
resolveComponents 采用 allSettled 策略,即使部分组件加载失败也不会阻断路由导航。组件加载的具体错误应由视图层捕获和处理。
常见的预加载场景是在用户悬停链接时提前加载目标页面:
tsx
function prefetchRoute(path: string) {
const route = router.matchRoute({ index: path })
if (route) {
router.resolveComponents(route)
}
}
// 鼠标悬停时预加载
;<RouterLink to="/user/123" onMouseEnter={() => prefetchRoute('/user/123')}>
用户详情
</RouterLink>完整示例
ts
import { lazy } from 'vitarx'
import { createRouter } from 'vitarx-router'
const router = createRouter({
routes: [
// 首页同步加载
{ path: '/', component: Home },
// 其他页面懒加载
{
path: '/about',
component: lazy(() => import('./pages/About.tsx'))
},
{
path: '/user/{id}',
component: lazy(() => import('./pages/User.tsx'))
},
// 命名视图懒加载
{
path: '/dashboard',
component: {
default: lazy(() => import('./pages/Dashboard.tsx')),
sidebar: lazy(() => import('./pages/DashboardSidebar.tsx'))
}
}
]
})