Webpack 打包過大的問題通常會導致頁面加載變慢,影響用戶體驗。可以從代碼優化、依賴優化、構建優化等多個角度入手來減少打包體積:
- 代碼優化
(1)按需加載(代碼拆分)
① 路由懶加載
如果你的項目使用 Vue Router,可以使用動態 import() 進行路由懶加載:
const Home = () => import(’@/views/Home.vue’);
const About = () => import(’@/views/About.vue’);
const routes = [
{ path: ‘/’, component: Home },
{ path: ‘/about’, component: About },
];
這樣只會在需要時加載對應的頁面,而不是一次性加載所有路由組件。
② 組件懶加載
import { defineAsyncComponent } from ‘vue’;
const AsyncComponent = defineAsyncComponent(() =>
import(’@/components/HeavyComponent.vue’)
);
Vue 3 提供了 defineAsyncComponent,可以按需加載組件,避免一次性加載所有組件。
③ 動態導入依賴
對于某些不常用的庫,可以在使用時動態 import(),而不是一開始就加載:
button.addEventListener(‘click’, async () => {
const { heavyFunction } = await import(’@/utils/heavyModule’);
heavyFunction();
});
這樣不會在初始打包時包含該模塊,而是等用戶需要時才加載。
- 依賴優化
(1)移除不必要的依賴
可以用 webpack-bundle-analyzer 查看打包體積:
npm install -D webpack-bundle-analyzer
然后在 vue.config.js 或 webpack.config.js 中添加:
const BundleAnalyzerPlugin = require(‘webpack-bundle-analyzer’).BundleAnalyzerPlugin;
module.exports = {
plugins: [
new BundleAnalyzerPlugin(),
],
};
運行 npm run build 后,會生成一個可視化報告,看看哪些庫太大,可以考慮替換或刪除。
(2)使用更輕量的庫
Lodash 替換方案:
Tree Shaking:使用 lodash-es 代替 lodash,并確保只導入需要的方法:
import { debounce } from ‘lodash-es’;
第三方替代:如 just-debounce、just-throttle 等。
Moment.js 替換方案:
Moment.js 很大,可以換成 dayjs:
npm install dayjs
import dayjs from ‘dayjs’;
console.log(dayjs().format());
Element Plus/Ant Design Vue 按需加載 如果使用 UI 組件庫,不要全量引入,要改成按需引入:
import { Button } from ‘ant-design-vue’;
import ‘ant-design-vue/es/button/style’;
- 構建優化
(1)開啟 Tree Shaking
確保 package.json 中 “sideEffects” 設為 false,讓 Webpack 進行搖樹優化:
{
“sideEffects”: false
}
如果某些模塊有副作用(如樣式文件),可以單獨列出:
{
“sideEffects”: [".css", ".scss"]
}
(2)使用 ESBuild Loader 加速構建
ESBuild 比 Babel 更快,可以用來優化 TS/JS 解析:
npm install -D esbuild-loader
在 webpack.config.js 中:
module.exports = {
module: {
rules: [
{
test: /.ts$/,
loader: ‘esbuild-loader’,
options: {
loader: ‘ts’,
target: ‘esnext’,
},
},
],
},
};
(3)使用 Rspack 代替 Webpack
你已經有 Webpack 遷移到 Rspack 的經驗,可以考慮直接用 Rspack,它的構建速度更快,尤其適用于 Vue 3 項目。
- 靜態資源優化
(1)開啟 Gzip/Brotli 壓縮
開啟 Gzip:
npm install compression-webpack-plugin -D
const CompressionPlugin = require(‘compression-webpack-plugin’);
module.exports = {
plugins: [
new CompressionPlugin({
algorithm: ‘gzip’,
test: /.(js|css|html|svg)$/,
}),
],
};
Brotli 壓縮效果更好,可以用 brotli-webpack-plugin。
(2)圖片優化
使用 WebP:比 PNG/JPEG 體積小,加載更快。
SVG 優化:使用 svgo 或 unplugin-icons 讓 SVG 直接變 Vue 組件:
npm install -D unplugin-icons
import { OhVueIcon, addIcons } from ‘oh-vue-icons’;
import { BiGithub } from ‘oh-vue-icons/icons’;
addIcons(BiGithub);
- 緩存優化
(1)開啟瀏覽器緩存
在 webpack.config.js 中:
output: {
filename: ‘[name].[contenthash:8].js’,
chunkFilename: ‘[name].[contenthash:8].js’,
}
這樣文件名帶 contenthash,只要內容不變,瀏覽器就會用緩存,不會重復下載。
(2)分離第三方庫(Vendor Split)
可以用 Webpack splitChunks 把依賴拆分:
optimization: {
splitChunks: {
chunks: ‘all’,
cacheGroups: {
vendors: {
test: /[\/]node_modules[\/]/,
name: ‘vendors’,
chunks: ‘all’,
},
},
},
}
這樣 node_modules 里的庫會被打包成一個獨立的 vendors.js,瀏覽器可以緩存它,不用每次都下載。
總結
如果 Webpack 打包特別大,可以從以下幾方面優化: ? 按需加載(路由懶加載、組件懶加載、動態 import())
? 移除大依賴(lodash → lodash-es,moment → dayjs)
? 啟用 Tree Shaking(sideEffects: false)
? 用 ESBuild 加速編譯
? 靜態資源優化(圖片壓縮、Gzip/Brotli 壓縮)
? 分離第三方庫(splitChunks)
如果你的 Webpack 構建速度慢,考慮直接遷移到 Rspack,你之前已經做過類似的遷移,應該很容易上手!