Explore all courses in this category.
Explore all courses in this category.
Nguyễn Đình Cường
0 comment
09 Nov, 2026
Các ứng dụng web hiện đại hay "phình" ra: càng thêm tính năng và thư viện, gói JavaScript người dùng phải tải càng lớn. Trong khi đó, ở lần truy cập đầu, họ chỉ cần phần nhỏ của ứng dụng. Code splitting và lazy loading là cách chia nhỏ mã và chỉ tải khi cần.
Mặc định, công cụ đóng gói (bundler) như Vite, webpack hay Rollup gộp mã thành một hoặc vài file lớn. Người dùng vào trang chủ vẫn phải tải mã của trang quản trị, của biểu đồ, của trình soạn thảo mà họ có thể không bao giờ mở. Hệ quả: tải lâu hơn, trình duyệt phải phân tích và chạy nhiều JavaScript hơn, nhất là khó chịu trên điện thoại cấu hình thấp.
Hàm import() là tính năng chuẩn của JavaScript, trả về promise và tải module khi gọi. Bundler nhận ra nó và tự tách module đó thành file riêng (chunk):
const nut = document.querySelector('#xem-bieu-do');
nut.addEventListener('click', async () => {
const { veBieuDo } = await import('./bieu-do.js');
veBieuDo(document.querySelector('#khung'));
});Mã vẽ biểu đồ (có thể kèm thư viện nặng) chỉ tải khi người dùng bấm nút. Bạn cũng có thể tải trước lúc rảnh hoặc khi rê chuột vào nút để cảm giác tức thì mà vẫn không tải thừa ở lần đầu.
import { lazy, Suspense } from 'react';
const TrangQuanTri = lazy(() => import('./TrangQuanTri'));
function App() {
return (
<Suspense fallback={<p>Đang tải...</p>}>
<TrangQuanTri />
</Suspense>
);
}lazy nhận hàm trả về dynamic import của một component (xuất mặc định), Suspense hiển thị giao diện dự phòng trong lúc chờ tải. Cách phổ biến nhất là tách theo route, mỗi trang là một chunk riêng:
const TrangChu = lazy(() => import('./pages/TrangChu'));
const KhoaHoc = lazy(() => import('./pages/KhoaHoc'));
const CaiDat = lazy(() => import('./pages/CaiDat'));Vue Router cho phép khai báo route với import động: component: () => import('./views/CaiDat.vue'). Còn trong Vue có thể dùng defineAsyncComponent cho từng component. Next.js tự động tách mã theo trang và hỗ trợ next/dynamic cho component tải theo nhu cầu. Hãy xem công cụ bạn dùng đã làm sẵn những gì trước khi tự làm.
Đừng tách quá vụn. Mỗi chunk là một yêu cầu mạng thêm, và tách mọi thứ có thể tạo ra hiệu ứng "thác nước" làm chậm hơn. Hãy tách những phần đủ lớn để có lợi.
Thường bạn sẽ tìm ra vài "thủ phạm" gây phình gói: thư viện nhập cả bộ khi chỉ dùng một hàm, hoặc hai thư viện cùng làm một việc.
import { debounce } from 'lodash-es' thay vì nhập cả thư viện cũ).<link rel='prefetch' href='...'> hoặc gợi ý magic comment của bundler.loading='lazy'.Khi tải theo nhu cầu, mạng có thể chậm hoặc lỗi. Hãy luôn có giao diện chờ gọn gàng (khung xương skeleton thay vì vòng xoay chung chung), và bắt lỗi tải chunk bằng error boundary trong React để người dùng có thể thử lại thay vì thấy màn hình trắng.
Chỉ gửi cho người dùng đúng phần mã họ cần ở thời điểm họ cần. Hãy bắt đầu từ tách theo route và các thành phần nặng, dùng công cụ phân tích để tìm điểm phình, và đo lại sau mỗi thay đổi.
Nếu muốn học cách tổ chức và tối ưu dự án frontend quy mô lớn, bạn có thể xem các khóa học tại codebem.com.
Nguyễn Đình Cường
0 comment