Настройка Code Splitting в React-приложении требует понимания нескольких ключевых аспектов. Рассмотрим пошаговую настройку и лучшие практики.
// Не требует дополнительной установки, доступно из коробки
import { lazy, Suspense } from 'react';
const LazyComponent = lazy(() => import('./components/LazyComponent'));
function App() {
return (
<Suspense fallback={<div>Загрузка...</div>}>
<LazyComponent />
</Suspense>
);
}
Добавьте в webpack.config.js:
module.exports = {
// ...
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
name: 'vendors',
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
},
},
},
},
};
Пример с React Router:
import { lazy, Suspense } from 'react';
import { Routes, Route } from 'react-router-dom';
const Home = lazy(() => import(
/* webpackChunkName: "home" */
'./pages/Home'
));
const About = lazy(() => import(
/* webpackChunkName: "about" */
'./pages/About'
));
function App() {
return (
<Suspense fallback={<PageLoader />}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</Suspense>
);
}
Добавьте плагин для динамических импортов:
// .babelrc или babel.config.js
{
"plugins": ["@babel/plugin-syntax-dynamic-import"]
}
const LazyComponent = lazy(() => import(
/* webpackChunkName: "my-component" */
/* webpackPrefetch: true */
'./MyComponent'
));
// Предзагрузка при наведении или других событиях
function handleMouseEnter() {
import('./components/LazyComponent');
}
// Или через webpackPrefetch
const LazyComponent = lazy(() => import(
/* webpackPrefetch: true */
'./components/LazyComponent'
));
// next.config.js
module.exports = {
webpack(config) {
config.optimization.splitChunks = {
chunks: 'all',
cacheGroups: {
default: false,
vendors: false,
// Ваши кастомные группы
},
};
return config;
},
};
Установите и используйте:
npm install --save-dev webpack-bundle-analyzer
Добавьте в webpack.config.js:
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: 'static',
openAnalyzer: false,
})
]
};
const LazyImage = ({ src, alt }) => {
const [isLoaded, setIsLoaded] = useState(false);
useEffect(() => {
const img = new Image();
img.src = src;
img.onload = () => setIsLoaded(true);
}, [src]);
return isLoaded ? <img src={src} alt={alt} /> : <Placeholder />;
};
function useLazyModule(importFn) {
const [module, setModule] = useState(null);
useEffect(() => {
let isMounted = true;
importFn().then(mod => {
if (isMounted) setModule(mod);
});
return () => { isMounted = false };
}, [importFn]);
return module;
}
// Использование
const MyComponent = () => {
const module = useLazyModule(() => import('./HeavyModule'));
return module ? <module.default /> : <Loader />;
};
Настройка Code Splitting в React включает:
Ключевые моменты:
Правильно настроенный Code Splitting может значительно улучшить производительность вашего React-приложения.