Đo trước, cắt sau. Mở bundle analyzer để biết dung lượng đến từ đâu; thường 2–3 thư viện nặng chiếm phần lớn (thư viện biểu đồ, trình soạn thảo rich text, thư viện xử lý ngày tháng, bản đồ).
Thứ tự xử lý theo mức hiệu quả:
1. Tách theo route. Mỗi trang là một chunk riêng, người dùng vào trang chủ không phải tải code của trang quản trị.
2. Lazy load theo tương tác. Code chỉ chạy khi mở modal, chuyển tab hay cuộn xuống thì để lazy + Suspense:
const ReportChart = lazy(() => import('./report-chart'))
{showChart && (
<Suspense fallback={<ChartSkeleton />}>
<ReportChart data={data} />
</Suspense>
)}3. Thay thư viện nặng bằng API sẵn có: định dạng ngày giờ dùng Intl thay cho thư viện ngày tháng đầy đủ; icon import lẻ từng cái thay vì import cả bộ.
4. Kiểm tra tree-shaking: import { debounce } from 'lodash' kéo cả gói, lodash-es hoặc import đúng đường dẫn con thì không.
Hai bẫy thường gặp:
- Chia quá vụn làm tăng số request và thời gian chờ chuỗi phụ thuộc; nhóm các chunk nhỏ liên quan lại.
- Fallback rỗng khiến trang nhảy layout khi chunk về. Dùng skeleton đúng kích thước, và prefetch chunk khi người dùng hover vào nút mở để cảm giác tức thì.
Cuối cùng, đo lại bằng chỉ số thật (LCP, INP) chứ không chỉ nhìn con số kích thước bundle giảm.