React 中使用 `lazy` 和 `Suspense` 进行代码拆分
Source: Dev.to
请提供您想要翻译的完整文本内容(除代码块和 URL 之外),我将为您翻译成简体中文并保持原有的 Markdown 格式。
React 中的代码拆分
在 React 中,code splitting 允许我们仅在实际需要时加载应用程序的部分。我们可以在不一次性下载所有 JavaScript 的情况下,推迟加载不太重要或体积较大的组件,直到用户与 UI 交互时才加载。这对于大型应用程序或用户可能永远看不到的组件尤其有用。
为什么代码拆分很重要
好处
- 提升性能 – 更小的初始 JavaScript 包意味着更快的页面加载时间,尤其在慢速网络或低端设备上。
- 更好的用户体验 – 首次渲染时只加载必需的代码。其余代码在后续按需获取,正好在用户需要时加载。
问题:不必要的网络请求
在使用 React.lazy 和 Suspense 之前,SlowComponent 已经 在 Network 面板中被加载,即使:
- 切换按钮为
false。 - 用户从未打开或看到该组件。
这意味着浏览器下载了用户可能永远不会使用的代码。
之前(未使用懒加载)
SlowComponent 在页面加载时立即被加载:
这会浪费带宽并进行不必要的工作。
解决方案:React.lazy + Suspense
React 提供了 lazy 和 Suspense,用于在组件 实际渲染时 才加载它们。
基本示例
import React, { lazy, Suspense } from 'react';
const DataComponent = lazy(() => import('./DataComponent'));
function MyComponent() {
return (
Loading...}>
);
}
DataComponent不会 在渲染之前被加载。- 在组件加载期间会显示一个后备 UI。
使用大型组件的实用示例
在本示例中:
SlowComponent较为庞大,应仅在用户点击按钮时才加载。- 使用
useTransition以保持 UI 的响应性。
import { useState, useTransition, lazy, Suspense } from 'react';
const SlowComponent = lazy(() => import('./SlowComponent'));
const App = () => {
const [text, setText] = useState('');
const [items, setItems] = useState([]);
const [isPending, startTransition] = useTransition();
const [show, setShow] = useState(false);
const handleChange = (e) => {
setText(e.target.value);
startTransition(() => {
const newItems = Array.from({ length: 5000 }, (_, index) => (

));
setItems(newItems);
});
};
return (
#### Items Below
{isPending ? (
'Loading...'
) : (
{items}
)}
setShow(!show)} className="btn">
Toggle
{show && (
)}
);
};
export default App;
在网络标签页中有什么变化?
应用 lazy 后
SlowComponent 在初始页面加载时 不会被加载:
仅在用户操作时加载
该组件仅在用户点击切换按钮时 被请求:
这正是我们想要的。
关键要点
- 懒加载 –
SlowComponent在渲染之前不会被下载。 - Suspense – 在组件获取期间处理加载状态。
- 更佳性能 – 不会提前加载不必要的 JavaScript。
- 用户驱动加载 – 代码仅在用户实际需要时才会被获取。
可选:使用 Suspense 包裹更多
如果你的应用包含多个懒加载组件,你可以用 Suspense 包裹更大范围的组件树。在许多情况下,通常会将 整个返回语句 包裹起来,以便所有懒加载组件共享同一个加载回退:
{/* one or more lazy‑loaded components */}
结论
在使用 React.lazy 和 Suspense 之前,即使切换为 false,SlowComponent 仍会被下载,这意味着用户为可能永远看不到的代码付出了代价。
通过使用 代码拆分,我们:
- 减少初始 bundle 大小
- 提升性能
- 仅在真正需要时加载代码
致谢:John Smilga 的课程


