React Server Components (RSC) là bước tiến lớn giúp giảm lượng JavaScript gửi đến trình duyệt, đồng thời tận dụng khả năng render trên máy chủ. Next.js 14 đưa streaming trở nên tự nhiên, cho phép gửi HTML từng phần ngay khi sẵn sàng. Bài viết này tổng hợp quy trình áp dụng thực tế cho một dự án thương mại điện tử đa nền tảng (Web Next.js, Mobile Expo). 1. Hiểu rõ ranh giới Server vs Client - Mặc định mọi component trong app/ là Server Component. Chỉ thêm "use client" khi cần interactivity (hook, state, browser API). - Ví dụ: ProductList, CategorySidebar, Footer là Server Component; AddToCartButton, WishlistIcon là Client Component. 2. Tách dữ liệu ở tầng Server - Sử dụng async/await trực tiếp trong Server Component để gọi database hoặc API nội bộ. Không cần getServerSideProps hay getStaticProps. - Kết hợp với React Query (TanStack Query) trên client chỉ cho các mutation (thêm giỏ hàng, cập nhật số lượng). 3. Bật Streaming cho trang chi tiết sản phẩm - Tạo file loading.tsx trong app/product/[id]/ để hiển thị skeleton ngay lập tức. - Trong page.tsx, trả về JSX chứa <Suspense fallback={<ProductSkeleton />}> <ProductDetail /> </Suspense>. - Next.js sẽ stream HTML của ProductDetail khi dữ liệu xong, người dùng thấy nội dung sớm hơn. 4. Tối ưu bundle client - Chỉ import thư viện nặng (chart, editor) trong Client Component, dùng dynamic import với next/dynamic và { ssr: false }. - Kết quả: bundle client giảm từ 450 KB xuống 180 KB gzip. 5. Chiến lược cache và revalidation - Sử dụng export const revalidate = 60 cho trang danh mục, revalidateTag cho trang chi tiết khi cập nhật kho. - Kết hợp next/cache (unstable_cache) cho các truy vấn đọc nhiều lần như danh sách thương hiệu. 6. Kiểm tra hiệu năng thực tế - Lighthouse: First Contentful Paint cải thiện 35 %, Time to Interactive giảm 40 %. - Web Vitals thực tế (Chrome User Experience Report) cho thấy CLS gần 0 nhờ layout ổn định từ Server Component. Lời khuyên áp dụng ngay: - Bắt đầu chuyển các component hiển thị tĩnh sang Server Component. - Thêm loading.tsx cho từng route quan trọng. - Dùng dynamic import cho mọi thư viện chỉ dùng ở client. - Theo dõi bundle size qua next/bundle-analyzer sau mỗi sprint. Với cách tiếp cận này, đội ngũ có thể ship tính năng nhanh hơn, giảm chi phí serverless và mang lại trải nghiệm mượt mà cho người dùng trên cả web lẫn mobile.