Code Splitting — это техника оптимизации производительности, которая позволяет разделить JavaScript-бандл приложения на несколько частей (чанков), загружаемых по требованию, а не все сразу при первоначальной загрузке.
Базовый подход без React.lazy:
import { useState, useEffect } from 'react';
function ComponentWithLazyLoad() {
const [LazyComponent, setLazyComponent] = useState(null);
useEffect(() => {
import('./HeavyComponent').then(module => {
setLazyComponent(() => module.default);
});
}, []);
return LazyComponent ? <LazyComponent /> : <div>Загрузка...</div>;
}
import { lazy, Suspense } from 'react';
const LazyComponent = lazy(() => import('./HeavyComponent'));
function App() {
return (
<Suspense fallback={<div>Загрузка компонента...</div>}>
<LazyComponent />
</Suspense>
);
}
С использованием React Router:
import { lazy, Suspense } 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>
);
}
Вынесение больших библиотек в отдельный чанк:
// В конфигурации webpack
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
},
},
},
}
С помощью webpack magic comments:
const ChatWidget = lazy(() => import(
/* webpackChunkName: "chat-widget" */
'./ChatWidget'
));
const Dashboard = lazy(() => import(
/* webpackChunkName: "dashboard" */
'./Dashboard'
));
// При наведении или других пользовательских действиях
function handleMouseEnter() {
import('./ComponentToPrefetch');
}
const CriticalComponent = lazy(() => import(
/* webpackPreload: true */
'./CriticalComponent'
));
const NonCriticalComponent = lazy(() => import(
/* webpackPrefetch: true */
'./NonCriticalComponent'
));
const UserProfile = lazy(() => import(
/* webpackChunkName: "user-profile" */
'./UserProfile'
));
const UserSettings = lazy(() => import(
/* webpackChunkName: "user-profile" */
'./UserSettings'
));
Обязательно добавляйте Error Boundary:
import { ErrorBoundary } from 'react-error-boundary';
function ErrorFallback({ error }) {
return (
<div role="alert">
<p>Ошибка загрузки модуля:</p>
<pre>{error.message}</pre>
</div>
);
}
<ErrorBoundary FallbackComponent={ErrorFallback}>
<Suspense fallback={<div>Загрузка...</div>}>
<LazyComponent />
</Suspense>
</ErrorBoundary>
Для Next.js используйте dynamic imports:
import dynamic from 'next/dynamic';
const DynamicComponent = dynamic(
() => import('../components/HeavyComponent'),
{
loading: () => <p>Загрузка...</p>,
ssr: false // Отключить для SSR при необходимости
}
);
Code Splitting в React — это мощный инструмент оптимизации, который реализуется через:
import()
)React.lazy
для компонентовSuspense
для управления состоянием загрузкиИспользуйте разделение кода для:
Помните о необходимости: