2026-05-21 03:27:43
在React中,可通过官方API(React.Lazy + React.Suspense)实现分屏加载,优先渲染首屏内容,后续内容按需加载,从而提升首屏速度。 具体实现方案如下:
一、核心API与原理使用React.Lazy定义懒加载组件将非首屏组件改为动态导入,例如:
const LazyComponent = React.lazy(() => import('./LazyComponent'));动态导入的模块需为默认导出(default export)。
路径需为静态字符串,不可动态拼接(如import('./' + name)会报错)。
用Suspense包裹懒加载组件在父组件中通过<Suspense>指定加载状态:
function App() { return ( <div> <h1>首屏内容</h1> <Suspense fallback={<div>加载中...</div>}> <LazyComponent /> </Suspense> </div> );}fallback属性支持任意React节点(如文本、组件),用于显示加载过程。
路由级懒加载(推荐)结合React Router实现路由级分屏,例如:
import { BrowserRouter, Routes, Route } from 'react-router-dom';const Home = React.lazy(() => import('./Home'));const About = React.lazy(() => import('./About'));function App() { return ( <BrowserRouter> <Suspense fallback={<div>加载中...</div>}> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> </Routes> </Suspense> </BrowserRouter> );}每个路由对应独立模块,访问时才加载对应代码。
基于滚动位置的按需加载通过监听滚动事件或使用Intersection Observer API,在用户滚动到接近非首屏区域时触发加载。例如:
function LazySection() { const [isVisible, setIsVisible] = useState(false); const ref = useRef(); useEffect(() => { const observer = new IntersectionObserver(([entry]) => { if (entry.isIntersecting) { setIsVisible(true); observer.unobserve(entry.target); } }); observer.observe(ref.current); return () => observer.disconnect(); }, []); return ( <div ref={ref}> {isVisible ? <LoadedComponent /> : <Placeholder />} </div> );}Placeholder可为骨架屏或占位元素,提升加载过渡体验。
预加载策略在用户可能访问的路径上提前加载模块,例如:
useEffect(() => { const loadNextComponent = () => import('./NextComponent'); // 在首屏加载完成后预加载 setTimeout(loadNextComponent, 1000);}, []);结合link rel="preload"或服务端推送(Server Push)进一步优化。
错误边界处理使用ErrorBoundary捕获懒加载失败时的错误,避免整个应用崩溃:
class ErrorBoundary extends React.Component { state = { hasError: false }; static getDerivedStateFromError() { return { hasError: true }; } render() { if (this.state.hasError) { return <div>组件加载失败</div>; } return this.props.children; }}// 使用方式<ErrorBoundary> <Suspense fallback={<div>加载中...</div>}> <LazyComponent /> </Suspense></ErrorBoundary>webpackPrefetch: true会在空闲时预加载,webpackPreload: true会在父模块加载时并行加载。
通过上述方案,可显著减少首屏加载时间,提升用户体验。实际开发中需根据项目复杂度选择基础懒加载或结合滚动/路由的进阶策略。