## Giới thiệu Khi phát triển ứng dụng React cho cả Web (Next.js) và Mobile (Expo) trong một monorepo, kích thước bundle thường tăng nhanh do chia sẻ nhiều thư viện chung. Việc tải toàn bộ mã nguồn ngay từ đầu làm chậm thời gian khởi động, đặc biệt trên thiết bị di động có băng thông hạn chế. Code Splitting kết hợp Dynamic Import là giải pháp hiệu quả để chỉ tải những phần mã thực sự cần thiết cho từng màn hình hoặc tính năng. ## Tại sao cần Code Splitting trong monorepo? - Giảm First Contentful Paint (FCP) và Time to Interactive (TTI) trên Web. - Giảm kích thước ứng dụng cài đặt (IPA/APK) và thời gian khởi động cold start trên Mobile. - Tận dụng cache của trình duyệt và Metro bundler cho các chunk riêng biệt. - Cho phép tải lazy các feature flag, màn hình ít dùng hoặc heavy library (chart, editor). ## Các bước triển khai thực tế 1. **Phân tích dependency graph** – Sử dụng `webpack-bundle-analyzer` (Web) và `expo-bundle-analyzer` (Mobile) để xác định các module lớn và ít thay đổi. 2. **Tách route/component cấp cao** – Với Next.js dùng `next/dynamic` hoặc `React.lazy` + `Suspense` cho từng page. Với Expo/React Navigation dùng `React.lazy` cho screen component và wrap trong `Suspense` ở navigator gốc. 3. **Dynamic import cho heavy library** – Ví dụ: chỉ import `chart.js` khi người dùng mở màn hình báo cáo: ```js const ChartView = React.lazy(() => import('./ChartView')); ``` Đảm bảo fallback loading nhẹ (skeleton hoặc spinner). 4. **Cấu hình shared chunks trong Turborepo** – Định nghĩa `pipeline` build cho từng package, bật `splitChunks` (Web) và `metro` `maxWorkers` + `createModuleIdFactory` để tạo chunk ổn định. 5. **Preload/prefetch chiến lược** – Trên Web dùng `<link rel="preload" as="script" href="...">` cho chunk quan trọng; trên Mobile dùng `Asset.loadAsync` để tải trước khi điều hướng. 6. **Kiểm thử hiệu năng** – Chạy Lighthouse (Web) và `expo start --no-dev --minify` kết hợp `react-native-performance` để đo cold start sau khi áp dụng. ## Lưu ý thường gặp - Tránh lặp lại `React.lazy` cho cùng một component ở nhiều nơi; tập trung export một lazy wrapper duy nhất. - Đảm bảo SSR (Next.js) vẫn hoạt động: bật `ssr: false` chỉ cho component thực sự client‑only. - Cập nhật `tsconfig`/`babel` để hỗ trợ `import()` dynamic syntax trên cả hai nền tảng. ## Kết luận Áp dụng Code Splitting và Dynamic Import trong monorepo React đa nền tảng giúp giảm đáng kể bundle size, cải thiện trải nghiệm người dùng và tối ưu chi phí băng thông. Quy trình trên có thể lặp lại cho mỗi feature mới, giữ cho ứng dụng nhẹ nhàng và dễ bảo trì.