什么是路由懒加载?
在 React 单页应用(SPA)中,通常会有多个页面(组件)通过路由切换。默认情况下,所有页面组件会被一次性打包进主 bundle 文件,导致首屏加载慢。路由懒加载就是让每个页面组件只在用户访问到对应路由时才被异步加载,从而减小首屏包体积,提高加载速度。
SPA可见往期文章:你不知道的前端路由实现方式与单页应用(SPA)架构模式详解
React 路由懒加载的实现方式
关键 API
React.lazy():用于定义懒加载组件。Suspense:用于包裹懒加载组件,提供加载时的占位内容。
基本用法
假设有两个页面组件:Home 和 About。
1)普通写法(未懒加载)
import Home from './pages/Home';
import About from './pages/About';
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
这样会把 Home 和 About 都打包进主 bundle。
2)懒加载写法
import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
// 懒加载组件
const Home = lazy(() => import('./pages/Home'));
const About = lazy(() => import('./pages/About'));
function App() {
return (
<Router>
<Suspense fallback={<div>页面加载中...</div>}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</Suspense>
</Router>
);
}
lazy(() => import('./pages/Home')):只有访问到该路由时,才会异步加载 Home 组件。Suspense的fallback属性用于设置加载时的占位内容。
原理解析
import()是 ES 提案的动态导入语法,Webpack/Vite 等打包工具会自动将其分割为独立的 chunk 文件。- 当用户访问某个路由时,对应的 chunk 文件才会被下载和执行。
进阶用法
路由嵌套懒加载
对于多级路由,也可以使用同样的方式进行懒加载。
结合 Error Boundary 处理加载失败
懒加载组件有可能因为网络等原因加载失败,建议配合错误边界组件:
class ErrorBoundary extends React.Component {
state = { hasError: false };
static getDerivedStateFromError(error) {
return { hasError: true };
}
render() {
if (this.state.hasError) {
return <div>页面加载失败,请重试。</div>;
}
return this.props.children;
}
}
// 使用
<ErrorBoundary>
<Suspense fallback={<div>加载中...</div>}>
{/* 路由内容 */}
</Suspense>
</ErrorBoundary>
预加载(可选)
对于用户高概率访问的页面,可以在用户即将访问前提前加载:
// 例如鼠标悬停时预加载
const preloadAbout = () => import('./pages/About');
最佳实践
- 只对路由级组件懒加载,不要对小型、频繁使用的组件懒加载。
- 合理设置 loading 占位符,提升用户体验。
- 处理加载失败,给出友好提示。
- 分析打包结果,确保 chunk 分割合理。
常见问题解析
- 懒加载后页面白屏?
检查是否正确使用了Suspense,并设置了合适的fallback。 - SEO 问题?
SPA 本身对 SEO 不友好,懒加载无明显影响。需配合 SSR 或预渲染优化。
总结
React 路由懒加载是提升大型应用性能的有效手段。只需配合 React.lazy 和 Suspense,即可实现按需加载页面组件,显著优化首屏体验。实际开发中应结合项目实际情况,合理拆分和优化。