面试题答案
一键面试基于业务模块的代码分割
- 思路:将不同业务功能模块拆分,每个模块单独打包。例如电商项目中,将商品展示、购物车、用户中心等业务模块分开。这样在首屏加载时,只加载当前页面所需业务模块,减少首屏加载体积。
- Webpack配置示例:
module.exports = {
//...其他配置
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
commons: {
name: 'commons',
chunks: 'initial',
minChunks: 2
},
productModule: {
name: 'product',
test: /product\.(js|jsx)$/,
chunks: 'all',
enforce: true
},
cartModule: {
name: 'cart',
test: /cart\.(js|jsx)$/,
chunks: 'all',
enforce: true
}
}
}
}
};
基于路由的代码分割
- 思路:在SPA中,根据路由来分割代码。当访问某个路由时,才加载对应的路由组件代码。例如使用React Router,每个路由组件可以异步加载。这样首屏加载时,只加载首屏路由相关代码,提升加载速度。
- Webpack配置示例: 在React项目中,结合Babel和Webpack,路由组件可以这样定义(以React Router v5为例):
import React, { lazy, Suspense } from'react';
import { BrowserRouter as Router, Routes, Route } from'react-router-dom';
const Home = lazy(() => import('./components/Home'));
const About = lazy(() => import('./components/About'));
function App() {
return (
<Router>
<Routes>
<Route path="/" element={
<Suspense fallback={<div>Loading...</div>}>
<Home />
</Suspense>
} />
<Route path="/about" element={
<Suspense fallback={<div>Loading...</div>}>
<About />
</Suspense>
} />
</Routes>
</Router>
);
}
export default App;
Webpack默认支持这种动态导入语法,会自动进行代码分割。
异步加载的代码分割
- 思路:对于一些非首屏关键的资源,如某些弹窗组件、报表生成功能等,采用异步加载。在需要使用时再加载相关代码,避免阻塞首屏加载。
- Webpack配置示例:与基于路由的异步加载类似,例如在一个通用组件中:
import React, { lazy, Suspense } from'react';
const SpecialComponent = lazy(() => import('./SpecialComponent'));
function MainComponent() {
return (
<div>
<Suspense fallback={<div>Loading special component...</div>}>
<SpecialComponent />
</Suspense>
</div>
);
}
export default MainComponent;
Webpack同样会对这种动态导入进行代码分割,确保首屏加载不受这些异步资源影响,提升用户体验。