Webpack · Part 9 — Bundle Analysis & Performance
Measure what is actually in your bundle: webpack-bundle-analyzer treemaps, finding bloat and duplicates, performance budgets that fail the build, and prefetch/preload hints. With an interactive bundle analyzer.
Bạn không thể tối ưu cái không thấy. Đa số bundle phình to vì những lý do nhàm chán, sửa được: một thư viện ngày tháng ship mọi locale, một import lodash đầy đủ, hai phiên bản của cùng phụ thuộc. Phần này là về tìm và sửa chúng.
Bấm các khối trong treemap bên dưới để sửa các thủ phạm phổ biến và xem bundle giảm dưới ngân sách:
1. Đo trước
Thêm webpack-bundle-analyzer và chạy nó trên bản build production:
npm install --save-dev webpack-bundle-analyzer
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
module.exports = {
plugins: [new BundleAnalyzerPlugin({ analyzerMode: "static" })],
};
Nó mở một treemap tương tác nơi kích thước khối = kích thước file. Khối to là nơi byte của bạn đi. Bạn cũng có thể tạo stats --json và xem bằng công cụ online.
2. Các thủ phạm thường gặp
| Triệu chứng | Sửa |
|---|---|
moment ~230 KB | đổi sang dayjs, hoặc IgnorePlugin để bỏ locale |
full lodash | import { debounce } from "lodash-es" + import có tên + tree shaking |
| duplicate deps (two axios versions) | resolve.alias về một bản, hoặc npm dedupe |
| huge polyfills | nhắm trình duyệt hiện đại; cắt targets |
| source maps in bundle | dùng source-map không inline-source-map |
Trong demo analyzer, bấm moment, lodash, và khối axios trùng để áp các fix này và xem tổng giảm.
3. Bỏ locale của moment
Nếu phải giữ moment, bỏ locale không dùng:
const webpack = require("webpack");
plugins: [
new webpack.IgnorePlugin({
resourceRegExp: /^\.\/locale$/,
contextRegExp: /moment$/,
}),
],
Một plugin đó có thể cắt ~200 KB. Nhưng dayjs hoặc date-fns là lựa chọn dài hạn tốt hơn.
4. Ngân sách hiệu năng
Cho Webpack lỗi hoặc cảnh báo khi một bundle vượt ngưỡng kích thước, để bắt phình to trong CI:
module.exports = {
performance: {
maxEntrypointSize: 250000, // bytes
maxAssetSize: 250000,
hints: "warning", // or "error" to fail the build
},
};
Một ngân sách biến “bundle dần phình to trong sáu tháng” thành “PR vượt giới hạn bị fail review”. Thanh ngân sách của demo hiện đường 250 KB.
5. Prefetch & preload
Khi đã tách (Phần 6), dùng resource hint để điều hướng tức thì mà không phình tải ban đầu:
import(/* webpackPrefetch: true */ "./routes/Settings"); // fetch when idle
import(/* webpackPreload: true */ "./CriticalChart"); // fetch with parent
- = “user có lẽ sẽ cần sớm” — ưu tiên thấp, lúc rảnh.
- = “trang này cần ngay bây giờ” — ưu tiên cao, song song.
Dùng prefetch thoải mái cho route có khả năng tiếp theo, preload tiết kiệm cho chunk quan trọng của trang hiện tại.
6. Các thắng lợi tốc độ khác
- cache công việc build giữa các lần chạy, build lại nhanh hơn nhiều.
- transpile nhanh hơn Babel.
- loại một phụ thuộc tải-từ-CDN khỏi bundle hoàn toàn.
- Thu hẹp
include/excludeđể loader chạy trên ít file nhất.
module.exports = {
cache: { type: "filesystem" }, // huge rebuild speedup
};
7. Bài tập
1. Analyzer hiện khối 230 KB cho moment, chủ yếu là file locale bạn không dùng. Hai cách thu nhỏ?
Lời giải
IgnorePlugin để bỏ locale, hoặc thay moment bằng dayjs/date-fns.
2. Bạn muốn CI fail khi ai đó push PR làm bundle chính vượt 250 KB. Cấu hình gì?
Lời giải
performance: { maxEntrypointSize: 250000, hints: "error" }.
3. Analyzer hiện hai bản axios phiên bản khác nhau. Khử trùng lặp thế nào?
Lời giải
Đồng bộ phiên bản (npm dedupe) hoặc ép một bản với resolve.alias.
Nâng cao:trong demo analyzer, sửa moment, lodash, và axios trùng, và xác nhận bundle chuyển từ vượt-ngân-sách (đỏ) sang trong-ngân-sách (xanh).
Điểm chính
- Đo bằng
webpack-bundle-analyzertrước khi tối ưu. - Phình phổ biến: locale
moment,lodashđầy đủ, phụ thuộc trùng, polyfill to. - Đặt ngân sách hiệu năng để bắt thoái lui trong CI.
- Dùng gợi ý prefetch/preload để tải thông minh.
cache: { type: "filesystem" }tăng tốc build lại đáng kể.
Tiếp theo
Phần 10 — Resolve nâng cao + tự viết loader & plugin: nội bộ resolve và externals, rồi viết một loader tùy chỉnh và một plugin tùy chỉnh để hiểu Webpack từ bên trong.