Tối ưu bundle không chỉ giúp trang web tải nhanh hơn mà còn giảm dung lượng ứng dụng di động, cải thiện trải nghiệm người dùng và điểm số Core Web Vitals. Dưới đây là quy trình thực tế mà đội ngũ mình áp dụng cho một dự án thương mại điện tử chạy song song React Web (Next.js) và React Native (Expo). 1. Đo lường trước khi tối ưu - Web: dùng `webpack-bundle-analyzer` hoặc `next-bundle-analyzer` để xem biểu đồ treemap các module lớn. - Native: bật `metro-config` với `bundle-visualizer` hoặc `react-native-bundle-visualizer` để có báo cáo tương tự. Kết quả ban đầu: bundle web ~1.2 MB (gzipped) và bundle JS native ~3.5 MB. 2. Tách mã theo route / màn hình (code splitting) - Web: Next.js tự động tách theo page, nhưng các component chung (bảng sản phẩm, carousel) vẫn nằm trong chunk chung. Dùng `dynamic(() => import("../components/ProductTable"), { ssr: false })` kết hợp `React.Suspense` để tải khi cần. - Native: React Navigation hỗ trợ lazy loading screen qua `React.lazy`. Ví dụ: `const CheckoutScreen = React.lazy(() => import("./screens/Checkout"));` và wrap trong `<Suspense fallback={<Loading />}>`. 3. Loại bỏ dead code và thư viện thừa - Chạy `npm run depcheck` (web) và `expo-doctor` (native) để phát hiện dependency không dùng. - Thay thế `moment.js` (≈ 70 KB) bằng `date-fns` với tree‑shaking, giảm ~45 KB. - Bỏ `lodash` toàn bộ, chỉ import từng hàm (`import debounce from "lodash/debounce";`). 4. Bật nén và minify mạnh hơn - Web: cấu hình `terser` với `compress: { drop_console: true, pure_funcs: ["console.log"] }`. - Native: bật Hermes (mặc định từ Expo SDK 48) và đặt `minify: true` trong `metro.config.js`. 5. Kết quả sau khi áp dụng - Bundle web giảm xuống ~720 KB (gzipped), First Contentful Paint cải thiện 35 %. - Bundle native giảm xuống ~2.1 MB, thời gian cold‑start trên Android giảm từ 3.2 s xuống 2.1 s. Mẹo nhỏ: luôn thêm script `bundle:report` vào `package.json` để CI tự động fail nếu kích thước vượt ngưỡng cho phép. Điều này giữ cho dự án không bị phình to theo thời gian.