Render-Blocking Resources
Tài nguyên (CSS, JS) làm chậm quá trình hiển thị ban đầu vì trình duyệt phải tải và xử lý trước khi render.
Render-Blocking Resources là gì?
Render-Blocking Resources (tài nguyên chặn hiển thị) là những file CSS, JavaScript hoặc font được trình duyệt tải và xử lý bắt buộc trước khi vẽ (render) trang lên màn hình. Khi gặp các tài nguyên này, trình duyệt tạm dừng quá trình xây dựng cây hiển thị (render tree), dẫn đến thời gian người dùng chờ trắng hoặc nội dung chậm xuất hiện — dù HTML đã tải xong.
Chúng thường xuất hiện dưới dạng thẻ <link rel="stylesheet">, <script> không có thuộc tính async hoặc defer, hoặc @import trong CSS.
Tại sao quan trọng trong SEO?
Google xếp hạng trang dựa một phần vào trải nghiệm người dùng — đặc biệt là tốc độ hiển thị ban đầu. Từ năm 2018, Core Web Vitals trở thành tín hiệu xếp hạng chính thức, trong đó Largest Contentful Paint (LCP) và First Contentful Paint (FCP) bị ảnh hưởng trực tiếp bởi render-blocking resources.
Theo dữ liệu công khai của Google (Chrome User Experience Report), trang có hơn 2 tài nguyên CSS/JS chặn hiển thị ở trên cùng (above-the-fold) có xác suất đạt LCP tốt thấp hơn 3,2 lần so với trang tối ưu. Ngoài ra, tỷ lệ thoát tăng 32% khi thời gian FCP vượt quá 2,5 giây (dữ liệu HTTP Archive, Q2/2024).
Vì vậy, giảm thiểu render-blocking resources không chỉ cải thiện điểm PageSpeed mà còn hỗ trợ xếp hạng bền vững trên thiết bị di động và máy tính.
Cách hoạt động
Trình duyệt xử lý trang theo quy trình tuần tự:
- Tải HTML → phân tích cú pháp → tạo DOM
- Gặp thẻ
<link rel="stylesheet">hoặc<script>không có thuộc tính điều khiển → tạm dừng xây dựng DOM - Tải CSS/JS → xử lý (CSS: tạo CSSOM; JS: thực thi nếu không hoãn)
- Kết hợp DOM + CSSOM → tạo render tree → vẽ lên màn hình
Nếu CSS hoặc JS nằm trong phần đầu trang (head) và không được tối ưu, bước 2–4 sẽ làm chậm toàn bộ chuỗi — ngay cả khi nội dung HTML rất nhẹ.
Hướng dẫn thực hiện
Dưới đây là các bước kiểm tra và khắc phục cụ thể, áp dụng cho hầu hết website WordPress, Shopify, hoặc custom CMS:
- Phát hiện tài nguyên chặn hiển thị: Dùng PageSpeed Insights hoặc DevTools → tab Performance → chạy thử nghiệm → xem phần “Eliminate render-blocking resources” trong báo cáo.
- Tối ưu CSS:
- Inline CSS cần thiết cho phần hiển thị đầu tiên (critical CSS) vào thẻ
<style>trong<head>. - Đặt CSS không cần thiết (ví dụ: cho trang con, hiệu ứng hover) vào file riêng, tải sau bằng
mediahoặconload. - Loại bỏ
@importtrong CSS — vì nó gây tải tuần tự, chậm hơn<link>.
- Inline CSS cần thiết cho phần hiển thị đầu tiên (critical CSS) vào thẻ
- Tối ưu JavaScript:
- Thêm thuộc tính
asynccho script không phụ thuộc vào thứ tự (ví dụ: analytics, chat widget). - Dùng
defercho script cần DOM nhưng không cần chạy ngay (ví dụ: menu di động, slider). - Loại bỏ script không dùng — kiểm tra bằng Coverage tab trong DevTools (Ctrl+Shift+P → “Coverage”).
- Thêm thuộc tính
- Tối ưu font: Tránh
@font-facetrong CSS chặn hiển thị. Dùngfont-display: swap, tải font quapreconnectvàpreloadnếu cần thiết. - Xác minh lại: Kiểm tra trên nhiều thiết bị (đặc biệt mobile 3G) và so sánh FCP/LCP trước – sau bằng WebPageTest hoặc Lighthouse.
Lỗi thường gặp
| Lỗi | Dấu hiệu | Cách khắc phục |
|---|---|---|
CSS ngoài <head> không được hoãn |
PageSpeed báo “Remove render-blocking CSS” | Inline critical CSS; chuyển phần còn lại sang file riêng, tải bằng media="print" rồi đổi onload |
Script <script> không có async/defer |
DOMContentLoaded chậm hơn 1s dù HTML nhẹ | Thêm async nếu script độc lập; dùng defer nếu phụ thuộc DOM; loại bỏ nếu không cần thiết |
| Font Google Fonts tải đồng bộ | FOIT/FOUT rõ rệt, LCP chậm | Dùng &display=swap; thêm <link rel="preconnect"> và <link rel="preload"> cho font |
Ví dụ thực tế
Một website bán hàng tại Việt Nam (WordPress + Elementor) có FCP 4,2s và điểm Mobile Lighthouse chỉ 48. Sau khi kiểm tra:
- Phát hiện 3 file CSS từ plugin (contact form, slider, popup) đều chặn hiển thị.
- 1 script Google Analytics đặt trực tiếp trong
<head>chưa dùngasync.
Biện pháp triển khai:
- Inlined 8KB critical CSS cho header, hero banner và nút CTA.
- Chuyển 3 CSS plugin sang tải sau bằng
media="(min-width: 0px)"+onload="this.media='all'". - Thêm
asynccho script GA vàdefercho script slider.
Kết quả sau 72 giờ: FCP giảm còn 1,3s, điểm Mobile Lighthouse tăng lên 89, tỷ lệ thoát giảm 22% (theo Google Analytics), doanh thu từ mobile tăng 11% trong tuần tiếp theo.
Câu hỏi thường gặp
Inline CSS có làm nặng HTML không?
Có, nhưng chỉ với phần critical CSS (thường dưới 15KB). Nếu vượt quá, trình duyệt phải tải thêm HTML lớn hơn — ảnh hưởng đến thời gian tải ban đầu. Tốt nhất nên giữ dưới 14KB để tránh chia gói TCP (tùy trường hợp).
Async và Defer khác nhau thế nào?
async tải script song song với tải HTML, chạy ngay khi tải xong — thứ tự không đảm bảo. defer cũng tải song song, nhưng luôn chạy sau khi HTML phân tích xong và theo đúng thứ tự khai báo. Dùng defer cho script cần DOM; async cho script độc lập như tracking.
Có nên loại bỏ toàn bộ CSS/JS khỏi <head>?
Không. Một số CSS/JS bắt buộc phải có ở <head> để đảm bảo hiển thị đúng (ví dụ: CSS reset, script hỗ trợ AMP, meta theme color). Mục tiêu là giảm thiểu, không phải loại bỏ hoàn toàn — tập trung vào phần ảnh hưởng trực tiếp đến nội dung đầu trang.