Một website chậm không chỉ khiến người dùng bỏ đi mà còn có thể ảnh hưởng tới thứ hạng tìm kiếm, vì Google sử dụng Core Web Vitals như một tín hiệu trong đánh giá trải nghiệm trang. Tin vui là nếu bạn đang dùng Next.js, rất nhiều công cụ tối ưu đã có sẵn trong framework. Vấn đề chỉ là dùng chúng đúng cách. Bài viết này đi qua ba chỉ số chính và những việc cụ thể bạn có thể làm để cải thiện từng chỉ số.
Ba chỉ số Core Web Vitals hiện nay
Theo web.dev, bộ Core Web Vitals hiện gồm:
- LCP (Largest Contentful Paint): thời gian hiển thị phần tử nội dung lớn nhất trong khung nhìn. Mức tốt là từ 2,5 giây trở xuống.
- INP (Interaction to Next Paint): độ trễ từ lúc người dùng tương tác đến khi giao diện phản hồi. Mức tốt là từ 200 mili giây trở xuống. INP đã thay thế FID trong bộ Core Web Vitals từ năm 2024.
- CLS (Cumulative Layout Shift): mức độ bố cục bị xê dịch bất ngờ. Mức tốt là từ 0,1 trở xuống.
Một trang được coi là đạt khi cả ba chỉ số ở mức tốt tại phân vị thứ 75 lượt tải trang, xét riêng cho mobile và desktop. Điều đó có nghĩa là bạn cần quan tâm tới người dùng có thiết bị và mạng ở mức trung bình kém, chứ không chỉ chiếc laptop mạnh của lập trình viên.
Đo trước khi tối ưu
Hãy phân biệt hai loại dữ liệu: dữ liệu phòng thí nghiệm từ Lighthouse hay PageSpeed Insights, hữu ích khi debug; và dữ liệu thực tế từ người dùng thật, chẳng hạn báo cáo Core Web Vitals trong Google Search Console. Trong Next.js, bạn có thể thu thập số liệu thực tế bằng hook useReportWebVitals rồi gửi về hệ thống phân tích của mình. Luôn đo trước, tối ưu sau, rồi đo lại để xác nhận.
Cải thiện LCP
Phần tử LCP thường là ảnh hero, banner hoặc khối tiêu đề lớn. Các bước nên làm:
- Dùng
next/imageđể tự động sinh ảnh đúng kích thước, định dạng hiện đại và lazy-load cho ảnh bên dưới màn hình đầu. - Ưu tiên tải ảnh LCP. Theo tài liệu Next.js, từ phiên bản 16 thuộc tính
priorityđã bị đánh dấu deprecated; thay vào đó bạn dùngpreload, hoặc trong đa số trường hợp làloading="eager"hayfetchPriority="high"cho ảnh hero. - Khai báo
sizeschính xác cho ảnh responsive để trình duyệt không tải ảnh lớn hơn cần thiết. - Render nội dung chính trên server. Server Components và tạo trang tĩnh giúp HTML có sẵn nội dung ngay, thay vì chờ JavaScript tải về rồi mới gọi API.
- Giảm thời gian phản hồi server bằng cache dữ liệu và triển khai gần người dùng qua CDN.
import Image from "next/image";
export function Hero() {
return (
<Image src="/hero.webp" alt="Giải pháp phần mềm Besoft"
width={1600} height={900} sizes="100vw" fetchPriority="high" />
);
}Cải thiện INP
INP kém thường do luồng chính bị chặn bởi quá nhiều JavaScript. Hướng xử lý:
- Giảm JavaScript gửi xuống client. Giữ component ở server khi không cần tương tác, chỉ đặt
"use client"cho đúng mảnh giao diện cần thiết. - Tải chậm thành phần nặng như biểu đồ, trình soạn thảo, bản đồ bằng
next/dynamicđể chúng không nằm trong bundle ban đầu. - Kiểm soát script bên thứ ba. Dùng
next/scriptvới chiến lượclazyOnloadcho chat widget, công cụ quảng cáo hay analytics không quan trọng. - Chia nhỏ tác vụ dài. Với xử lý nặng trong event handler, hãy cập nhật giao diện trước rồi đẩy phần tính toán ra sau, hoặc dùng
useTransitionđể đánh dấu cập nhật không khẩn cấp. - Debounce các input như ô tìm kiếm thay vì xử lý mỗi lần gõ phím.
Cải thiện CLS
CLS cao làm người dùng bấm nhầm và cảm thấy trang "chập chờn". Nguyên nhân phổ biến và cách khắc phục:
- Ảnh không có kích thước:
next/imageyêu cầuwidthvàheight, hoặc dùngfilltrong khung có kích thước xác định, nên tự động giữ chỗ. - Font thay đổi khi tải xong: dùng
next/fontđể tự host font và điều chỉnh font dự phòng, hạn chế việc chữ nhảy khi font chính được áp dụng. - Nội dung chèn động: banner cookie, quảng cáo hay thông báo nên được dành sẵn không gian, hoặc hiển thị dạng lớp phủ thay vì đẩy nội dung xuống.
- Skeleton đúng kích thước: khi dùng
loading.tsxhaySuspense, hãy làm khung chờ có kích thước gần với nội dung thật.
import { Inter } from "next/font/google";
const inter = Inter({ subsets: ["latin", "vietnamese"], display: "swap" });Lưu ý khai báo subset vietnamese để chữ có dấu hiển thị đúng với font đã tối ưu.
Biến tối ưu thành thói quen
Hiệu năng dễ "trôi" dần theo thời gian khi tính năng mới được thêm vào. Một số cách để giữ vững:
- Đặt ngân sách hiệu năng, chẳng hạn giới hạn kích thước bundle, và kiểm tra trong CI.
- Theo dõi dữ liệu thực tế hằng tuần thay vì chỉ chạy Lighthouse một lần trước khi ra mắt.
- Review kỹ mỗi thư viện mới trước khi thêm vào dự án.
Kết luận
Next.js cung cấp gần như đủ công cụ để đạt Core Web Vitals tốt: next/image cho LCP và CLS, next/font cho font ổn định, Server Components cùng next/dynamic và next/script để giảm tải JavaScript cho INP. Chìa khóa là đo bằng dữ liệu thật, xác định đúng nút thắt và xử lý từng chỉ số một cách có hệ thống. Một website nhanh mang lại trải nghiệm tốt cho người dùng, và đó cũng là điều công cụ tìm kiếm muốn thấy.






