First Contentful Paint (FCP)
Thời điểm trình duyệt hiển thị phần tử nội dung đầu tiên (văn bản, hình ảnh, SVG, canvas) trong viewport.
First Contentful Paint (FCP) là gì?
First Contentful Paint (FCP) là thời điểm trình duyệt lần đầu tiên hiển thị một phần tử nội dung có ý nghĩa trong vùng nhìn thấy được (viewport) của người dùng. Phần tử này có thể là đoạn văn bản, hình ảnh (<img>), biểu tượng SVG, canvas hoặc bất kỳ thành phần nào tạo ra pixel hiển thị — không bao gồm nền trống, màu nền, hay khung viền.
FCP đo từ lúc bắt đầu tải trang (navigation start) đến khi phần tử nội dung đầu tiên xuất hiện trên màn hình. Đây là một chỉ số thuộc nhóm Core Web Vitals do Google xác định, và được tính theo đơn vị miligiây (ms).
Tại sao quan trọng trong SEO?
FCP phản ánh cảm giác tốc độ ban đầu của người dùng — yếu tố ảnh hưởng trực tiếp đến trải nghiệm và hành vi tương tác. Google đã xác nhận từ năm 2021 rằng Core Web Vitals (trong đó có FCP) là tín hiệu xếp hạng chính thức trên cả tìm kiếm di động và máy tính.
Một trang có FCP chậm thường đi kèm với tỷ lệ thoát cao hơn, thời gian ở lại ngắn hơn và ít khả năng chuyển đổi. Ngược lại, FCP dưới 1.8 giây được Google xếp vào mức tốt, từ 1.8–3.0 giây là cần cải thiện, và trên 3.0 giây là kém. Đây không phải ngưỡng cứng cho mọi trang, nhưng là mốc tham chiếu được kiểm chứng qua dữ liệu thực tế từ Chrome User Experience Report (CrUX).
Cách hoạt động
Trình duyệt bắt đầu đo FCP ngay khi bắt đầu xử lý HTML (tức sau navigationStart). Nó theo dõi tất cả các sự kiện render: vẽ văn bản, tải và hiển thị ảnh, render SVG… và ghi nhận thời điểm phần tử nội dung đầu tiên thực sự xuất hiện trong viewport.
Lưu ý quan trọng:
- FCP không chờ toàn bộ trang tải xong — chỉ cần một phần tử có nội dung xuất hiện.
- Nó không tính các phần tử ẩn (có
display: nonehoặcvisibility: hidden), hoặc nằm ngoài viewport (scroll xuống mới thấy). - FCP không bị ảnh hưởng bởi JavaScript chặn hiển thị nếu phần tử nội dung đã được render trước khi JS chạy — ví dụ: nội dung tĩnh trong HTML gốc.
Hướng dẫn thực hiện
Để tối ưu FCP, cần tập trung vào giai đoạn đầu của chuỗi tải trang. Dưới đây là các bước cụ thể, ưu tiên theo mức độ ảnh hưởng:
- Tối ưu hóa tài nguyên chặn hiển thị: Giảm thiểu hoặc loại bỏ CSS/JS không cần thiết trong
<head>. Dùngmediacho CSS không dùng trên màn hình nhỏ, hoặcpreloadcho font/font-icon quan trọng. - Tối ưu HTML truyền tải nhanh: Đảm bảo server trả về HTML trong vòng dưới 200ms (TTFB thấp). Kiểm tra cấu hình caching, bật Gzip/Brotli, dùng CDN.
- Hiển thị nội dung sớm hơn: Tránh render-blocking bằng cách chuyển CSS sang inline nếu nhỏ (<5KB), hoặc dùng
defercho script không cần chạy ngay. - Tối ưu hình ảnh phía client: Dùng thẻ
<img>vớiloading="eager"cho ảnh đầu trang, kèmwidth/heightđể tránh layout shift. - Giảm thời gian xử lý HTML: Tránh server-side rendering quá phức tạp nếu không cần thiết; cân nhắc sử dụng SSR nhẹ hoặc static site generation (SSG) cho trang đích.
Lỗi thường gặp
Dưới đây là những sai lầm phổ biến khiến FCP tăng cao — kèm cách khắc phục rõ ràng:
| Lỗi | Tác động đến FCP | Cách khắc phục |
|---|---|---|
| CSS lớn chặn render | Trình duyệt phải tải và phân tích toàn bộ CSS trước khi vẽ nội dung | Chia nhỏ CSS theo trang, inline critical CSS, loại bỏ CSS dư thừa (uncss, purgecss) |
| TTFB cao (>600ms) | HTML gửi chậm → FCP bắt đầu muộn | Tối ưu server (OPcache, Redis), dùng CDN, giảm query DB, bật HTTP/2 hoặc HTTP/3 |
| Ảnh không có kích thước cố định | Gây layout shift, nhưng không làm chậm FCP trực tiếp — tuy nhiên thường đi kèm với lazy-load sai cách | Thêm width/height, dùng loading="eager" cho ảnh đầu trang |
| Font hiển thị chậm (FOIT/FOUT) | Văn bản có thể bị ẩn hoặc hiển thị sai font → trì hoãn FCP nếu trình duyệt đợi font tải xong | Dùng font-display: swap, preload font quan trọng, tránh @import trong CSS |
Ví dụ thực tế
Một trang tin tức có FCP 4.2s do:
- HTML tải chậm (TTFB 950ms vì không dùng CDN và không bật cache)
- CSS chính (main.css, 420KB) được gọi đồng bộ trong
<head> - Ảnh tiêu đề dùng
loading="lazy"dù nằm trong viewport
Sau khi áp dụng tối ưu:
- CDN + cache server → TTFB giảm còn 180ms
- Critical CSS (12KB) được inline; phần còn lại tải bất đồng bộ
- Ảnh tiêu đề thêm
loading="eager"và kích thước rõ ràng
Kết quả: FCP giảm từ 4.2s xuống còn 1.3s — đạt mức “tốt” theo tiêu chuẩn CrUX. Tỷ lệ thoát giảm 22%, thời gian ở lại tăng 35% trong 30 ngày theo báo cáo Google Analytics.
Câu hỏi thường gặp
FCP khác gì so với Largest Contentful Paint (LCP)?
FCP đo thời điểm phần tử nội dung đầu tiên xuất hiện, còn LCP đo thời điểm phần tử nội dung lớn nhất trong viewport được hiển thị (thường là ảnh hoặc khối văn bản lớn). LCP phản ánh tốc độ tải nội dung chính, trong khi FCP phản ánh cảm giác “trang bắt đầu hiện lên”. Cả hai đều là Core Web Vitals, nhưng tối ưu FCP không đảm bảo LCP cũng tốt — và ngược lại.
Có nên tối ưu FCP nếu trang chủ dùng SPA (React/Vue)?
Có, nhưng cần lưu ý: FCP trong SPA thường bị đẩy lùi do thời gian tải và thực thi framework. Giải pháp hiệu quả là kết hợp server-side rendering (SSR) hoặc static site generation (SSG) để gửi HTML có nội dung sẵn — giúp FCP bắt đầu sớm hơn. Nếu chỉ dùng CSR thuần, FCP có thể trên 5s — điều này gây rủi ro SEO rõ rệt.
FCP có phụ thuộc vào thiết bị người dùng không?
Có. FCP đo trên thiết bị thực (real-user monitoring – RUM), nên chịu ảnh hưởng bởi mạng, CPU, RAM và phiên bản trình duyệt. Google dùng dữ liệu CrUX từ hàng triệu thiết bị để tính giá trị đại diện. Do đó, FCP báo cáo trong PageSpeed Insights hoặc Search Console là giá trị trung vị trên thiết bị di động và máy tính riêng biệt — không phải giá trị lý thuyết trên máy mạnh. Tối ưu nên nhắm vào thiết bị phổ biến (Android低端, iOS cũ, mạng 3G/4G) — tùy trường hợp.