Khi phát triển ứng dụng chạy đồng thời trên Web (Next.js) và Mobile (React Native) trong một monorepo, kích thước bundle thường phình to do code chung, thư viện nặng và việc thiếu cơ chế chia tách. Dưới đây là quy trình thực tế đã giúp giảm 35‑40 % dung lượng JavaScript tải lần đầu và cải thiện First Contentful Paint rõ rệt. 1. Phân tách code theo route và màn hình - Sử dụng dynamic import của Next.js (`next/dynamic`) cho các trang ít truy cập. - Trên React Native, áp dụng `React.lazy` kết hợp với `Suspense` cho các screen chỉ hiển thị khi người dùng điều hướng. - Cấu hình `webpack` (Web) và `metro` (Native) để tạo chunk riêng cho từng feature, tránh gộp toàn bộ vào bundle chính. 2. Tree‑shaking triệt để - Đảm bảo tất cả package nội bộ xuất khẩu dưới dạng ESM (`export const …`) thay vì CommonJS. - Bật `sideEffects: false` trong `package.json` của từng workspace để bundler loại bỏ code không dùng. - Kiểm tra với `webpack-bundle-analyzer` và `metro-bundle-visualizer` sau mỗi build. 3. Chia sẻ thư viện nhẹ thay thế nặng - Thay `moment.js` bằng `date-fns` (chỉ import hàm cần thiết). - Dùng `lodash-es` và import từng hàm (`import debounce from 'lodash-es/debounce'`). - Loại bỏ polyfill không cần thiết nhờ `browserslist` chính xác và `react-native-get-random-values` cho crypto. 4. Cấu hình cache và nén - Bật `gzip`/`brotli` trên CDN và server Next.js (`compress: true`). - Thiết lập `Cache-Control: public, max-age=31536000, immutable` cho các chunk có hash trong tên file. - Trên mobile, bật `hermes` và `inlineRequires` trong `metro.config.js` để tải module theo yêu cầu. 5. Đo lường và lặp lại - Tích hợp `web-vitals` (Web) và `react-native-performance` (Mobile) để theo dõi TTI, TBT sau mỗi deploy. - Thiết lập ngưỡng cảnh báo trong CI: nếu bundle JS tăng >5 % so với baseline thì fail pipeline. Áp dụng các bước trên theo thứ tự giúp team giữ được hiệu năng ổn định khi mở rộng tính năng mới, đồng thời giảm chi phí băng thông và cải thiện trải nghiệm người dùng trên cả hai nền tảng.