Khi nào nên sử dụng Dynamic Import trong React/Next.js?
Dynamic import cho phép bạn lazy load các component, nghĩa là chúng chỉ được tải khi cần thiết, thay vì đóng gói tất cả ngay từ đầu. Điều này giúp cải thiện hiệu suất và thời gian tải trang cho ứng dụng của bạn.
Mục lục
- Dynamic Import là gì?
- Tại sao nên sử dụng Dynamic Import?
- Trường hợp sử dụng tốt
- Ví dụ thực tế
- So sánh hiệu suất (Trước vs Sau)
- Cách đo lường trong ứng dụng của bạn
- Khi nào không nên sử dụng Dynamic Import?
- Bảng tóm tắt (TL;DR)
Dynamic Import là gì?
Dynamic import cho phép bạn tải các module một cách động. Ví dụ:
javascript
// Import tĩnh (luôn nằm trong gói ban đầu)
import BigChart from "./BigChart"
// Import động (chia tách mã, tải theo yêu cầu)
import dynamic from "next/dynamic"
const BigChart = dynamic(() => import("./BigChart"))
Tại sao nên sử dụng Dynamic Import?
Sử dụng Dynamic Import mang lại nhiều lợi ích:
- ✅ Tải ban đầu nhanh hơn (giảm kích thước JS)
- ✅ Tải có điều kiện (chỉ khi cần thiết)
- ✅ Tránh các vấn đề SSR cho các thư viện chỉ dành cho client (
{ ssr: false })
Trường hợp sử dụng tốt
Dynamic Import rất hữu ích trong các tình huống sau:
- Các widget nặng, tùy chọn: biểu đồ, bản đồ, trình soạn thảo phong phú, modal
- Các thư viện chỉ dành cho client truy cập
window - Các cờ tính năng / A/B test
- Bảng điều khiển với nhiều panel có thể mở rộng
Ví dụ thực tế
a) Trình soạn thảo văn bản phong phú (react-quill)
javascript
import dynamic from "next/dynamic"
const RichTextEditor = dynamic(() => import("react-quill"), { ssr: false })
export default function Page() {
return (
<div>
<h1>Tạo Bài Đăng</h1>
<RichTextEditor theme="snow" />
</div>
)
}
b) Biểu đồ (react-chartjs-2)
javascript
import dynamic from "next/dynamic"
const Chart = dynamic(() => import("react-chartjs-2"), { ssr: false })
export default function Dashboard() {
return (
<section>
<h2>Phân Tích</h2>
<Chart type="bar" data={{ labels: ["A","B","C"], datasets: [{ data: [12,19,3] }] }} />
</section>
)
}
}
So sánh hiệu suất (Trước vs Sau)
Dưới đây là một ví dụ so sánh cho thấy cách mà dynamic import có thể thay đổi cách phân tách gói.
| Chunk/Metric | Trước (import tĩnh) | Sau (import động) |
|---|---|---|
| JS ban đầu (tải đầu tiên) | 420 KB | 240 KB |
react-quill trong gói ban đầu |
170 KB | 0 KB (lazy) |
react-chartjs-2 trong gói ban đầu |
95 KB | 0 KB (lazy) |
| JS theo route (trang dashboard) | 210 KB | 80 KB |
| Số lượng chunk JS | 9 | 13 |
| Thời gian Largest Contentful Paint (LCP)* | 2.4s | 1.8s |
* LCP phụ thuộc vào mạng/thiet bị; coi đây là minh họa. Các chỉ số thực tế của bạn có thể khác.
Cách đo lường trong ứng dụng của bạn
Tùy chọn A — @next/bundle-analyzer
- Cài đặt
bash
npm i -D @next/bundle-analyzer
- Cấu hình
next.config.js
javascript
// next.config.js
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
})
module.exports = withBundleAnalyzer({
// cấu hình Next.js của bạn
})
- Xây dựng & Phân tích
bash
ANALYZE=true next build
# Sau đó mở các treemap đã tạo (thường ở .next/analyze) để kiểm tra các chunk.
Tùy chọn B — Kiểm tra đầu ra xây dựng
bash
next build
# Kiểm tra "First Load JS shared by all" và kích thước từng route trong đầu ra terminal.
Tùy chọn C — Web Vitals trong sản xuất
- Theo dõi LCP/TTFB/CLS trước và sau với phân tích của bạn (ví dụ: Vercel Web Analytics, Sentry, hoặc tùy chỉnh).
Khi nào không nên sử dụng Dynamic Import?
- Các thành phần UI nhỏ, chung (nút, input)
- Các thành phần có mặt trên mọi route (header, footer)
- Chia tách quá nhiều thành nhiều chunk nhỏ (yêu cầu thêm và độ trễ)
Bảng tóm tắt (TL;DR)
| Tình huống | Sử dụng Dynamic Import? |
|---|---|
| Các thành phần nặng/tùy chọn | ✔️ Có |
Thư viện chỉ dành cho client (cần window) |
✔️ Có |
| Cờ tính năng / A/B features | ✔️ Có |
| Bố cục luôn sử dụng (navbar/footer) | ❌ Không |
| Các thành phần chung nhỏ | ❌ Không |
Mẹo chuyên nghiệp: Kết hợp dynamic imports với skeletons hoặc loading placeholders để giao diện cảm thấy nhanh nhạy trong khi các chunk đang tải.
Kết luận: Dynamic Import là một công cụ mạnh mẽ giúp tối ưu hóa hiệu suất ứng dụng React/Next.js của bạn. Hãy áp dụng nó một cách thông minh để cải thiện trải nghiệm người dùng. Nếu bạn có bất kỳ câu hỏi nào, đừng ngần ngại để lại câu hỏi bên dưới!