Critical CSS – Tải trang nhanh hơn 2 giây

Bạn có bao giờ truy cập một website và phải chờ đợi màn hình trắng xóa vài giây trước khi nội dung hiển thị? Đó chính là dấu hiệu của việc CSS chưa được tối ưu. Critical CSS là kỹ thuật giúp website của bạn hiển thị nội dung quan trọng ngay lập tức, mang lại trải nghiệm người dùng vượt trội và cải thiện đáng kể thứ hạng SEO. Trong bài viết này, chúng ta sẽ tìm hiểu Critical CSS là gì, tại sao nó quan trọng, và cách triển khai đúng cách để website của bạn tải nhanh như chớp.

Critical CSS – Tải trang nhanh hơn 2 giây

Critical CSS là gì?

Critical CSS (CSS tới hạn) là tập hợp các quy tắc CSS tối thiểu cần thiết để hiển thị phần nội dung “above the fold” – tức phần người dùng nhìn thấy đầu tiên khi trang web load mà không cần cuộn xuống. Thay vì để trình duyệt tải toàn bộ file CSS trước khi render trang, Critical CSS được nhúng trực tiếp vào phần head của HTML, cho phép trình duyệt hiển thị nội dung quan trọng ngay lập tức.

Ví dụ, với một blog post, Critical CSS sẽ bao gồm styles cho header, menu, tiêu đề bài viết và đoạn văn đầu tiên. Các phần còn lại như footer, sidebar hay phần bình luận có thể được load sau mà không ảnh hưởng đến trải nghiệm ban đầu của người dùng.

Tại sao Critical CSS quan trọng?

Khi trình duyệt tải một trang web, nó phải tải và phân tích toàn bộ file CSS trước khi có thể render nội dung. Đây được gọi là “render-blocking CSS” – CSS chặn việc hiển thị trang. Với các file CSS lớn (thường từ 100KB đến vài MB), việc này tạo ra độ trễ đáng kể, đặc biệt trên kết nối mạng chậm hoặc thiết bị di động.

Critical CSS giải quyết vấn đề này bằng cách chia CSS thành hai phần: phần quan trọng được inline ngay trong HTML, và phần còn lại được load bất đồng bộ. Kết quả là First Contentful Paint (FCP) và Largest Contentful Paint (LCP) – hai chỉ số quan trọng của Google Core Web Vitals – được cải thiện đáng kể, thường giảm từ 3-4 giây xuống còn dưới 1 giây.

Render-blocking CSS và vấn đề hiệu năng

Khi bạn link một file CSS bằng thẻ link thông thường, trình duyệt phải thực hiện các bước sau:

<link rel="stylesheet" href="styles.css">

1. Tải file CSS từ server (network request)
2. Phân tích và xây dựng CSSOM (CSS Object Model)
3. Kết hợp CSSOM với DOM để tạo render tree
4. Cuối cùng mới paint nội dung lên màn hình

Trong suốt quá trình này, người dùng nhìn thấy màn hình trắng – hiện tượng gọi là FOUC (Flash of Unstyled Content) hoặc white screen. Với file CSS lớn hoặc kết nối chậm, thời gian chờ đợi này có thể lên đến 3-5 giây, khiến người dùng nghĩ trang web bị lỗi và rời đi.

Cách xác định Critical CSS của bạn

Bước đầu tiên là xác định CSS nào thực sự “critical”. Có hai cách tiếp cận chính:

Cách thủ công: Mở DevTools của trình duyệt, set kích thước viewport thành 1920×1080 (desktop) hoặc 375×667 (mobile), sau đó xác định tất cả các elements hiển thị mà không cần scroll. Lưu lại tất cả CSS rules áp dụng cho các elements này. Phương pháp này tốn thời gian nhưng cho kết quả chính xác nhất.

Cách tự động: Sử dụng các tools như Critical (npm package), Penthouse, hoặc online tools như criticalcss.com. Các tool này sẽ tự động phân tích trang của bạn và trích xuất Critical CSS. Ví dụ với Critical:

npm install -g critical

critical https://inithtml.com --base=./ --inline > index-critical.html

Tool sẽ tạo ra file HTML mới với Critical CSS đã được inline trong thẻ style ở head.

Inline Critical CSS vào HTML

Sau khi có Critical CSS, bạn cần nhúng nó trực tiếp vào HTML. Đây là cấu trúc chuẩn:

<!DOCTYPE html>
<html lang="vi">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Trang web của bạn</title>
    
    <!-- Critical CSS inline -->
    <style>
        /* CSS cho header */
        header { 
            background: #333; 
            color: white; 
            padding: 20px; 
        }
        
        /* CSS cho hero section */
        .hero { 
            min-height: 100vh; 
            display: flex; 
            align-items: center; 
        }
        
        /* CSS cho navigation */
        nav ul { 
            display: flex; 
            list-style: none; 
        }
    </style>
    
    <!-- Preload font quan trọng -->
    <link rel="preload" href="fonts/main.woff2" as="font" type="font/woff2" crossorigin>
</head>
<body>
    <!-- Nội dung trang -->
</body>
</html>

Lưu ý: Critical CSS nên được giữ dưới 14KB (kích thước của TCP slow start window) để đảm bảo được gửi trong request đầu tiên. Nếu vượt quá, bạn cần tối ưu thêm.

Load phần CSS còn lại bất đồng bộ

Phần CSS không critical cần được load bất đồng bộ để không chặn rendering. Có nhiều cách để làm điều này:

Phương pháp 1: Sử dụng media attribute

<link rel="stylesheet" href="styles.css" media="print" onload="this.media='all'">

Kỹ thuật này trick trình duyệt bằng cách set media=”print” ban đầu (CSS không được áp dụng cho màn hình), sau đó khi file đã load xong, JavaScript sẽ chuyển media=’all’ để apply CSS.

Phương pháp 2: Sử dụng preload

<link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="styles.css"></noscript>

Phương pháp này tốt hơn vì tương thích với nhiều trình duyệt. Thẻ noscript đảm bảo CSS vẫn load với người dùng tắt JavaScript.

Phương pháp 3: Load bằng JavaScript

<script>
function loadCSS(href) {
    var link = document.createElement('link');
    link.rel = 'stylesheet';
    link.href = href;
    document.head.appendChild(link);
}

// Load sau khi page đã load xong
window.addEventListener('load', function() {
    loadCSS('styles.css');
    loadCSS('animations.css');
});
</script>

Tối ưu Critical CSS cho nhiều trang

Với website có nhiều loại trang khác nhau (homepage, blog post, product page), mỗi trang có thể cần Critical CSS khác nhau. Có hai chiến lược:

Chiến lược 1: Critical CSS chung
Tạo một Critical CSS chung bao gồm các components xuất hiện ở tất cả các trang (header, navigation, footer). Cách này đơn giản nhưng file Critical CSS có thể lớn hơn cần thiết.

Chiến lược 2: Critical CSS riêng cho từng template
Tạo Critical CSS riêng cho từng loại trang. Ví dụ:

critical-home.css (5KB) - cho homepage
critical-blog.css (4KB) - cho blog posts
critical-product.css (6KB) - cho product pages

Với phương pháp này, mỗi trang chỉ load Critical CSS cần thiết, tối ưu nhất nhưng phức tạp hơn trong việc maintain.

Tools và automation cho Critical CSS

Việc tạo và maintain Critical CSS thủ công rất tốn thời gian. Dưới đây là các tools phổ biến:

Critical (Node.js package)
Tool mạnh mẽ nhất, hỗ trợ nhiều options và có thể tích hợp vào build process:

const critical = require('critical');

critical.generate({
    inline: true,
    base: 'dist/',
    src: 'index.html',
    target: 'index-critical.html',
    width: 1300,
    height: 900,
    minify: true
});

Penthouse
Tool nhẹ hơn Critical, chỉ tập trung vào việc extract Critical CSS:

const penthouse = require('penthouse');

penthouse({
    url: 'https://inithtml.com',
    cssString: 'body { background: blue; }',
}).then(criticalCss => {
    console.log(criticalCss);
});

Critters (Webpack plugin)
Tự động inline Critical CSS trong quá trình build với Webpack:

const Critters = require('critters-webpack-plugin');

module.exports = {
    plugins: [
        new Critters({
            preload: 'swap',
            noscriptFallback: true
        })
    ]
};

Đo lường hiệu quả của Critical CSS

Sau khi implement Critical CSS, bạn cần đo lường để xác nhận cải thiện. Các metrics quan trọng:

First Contentful Paint (FCP): Thời gian từ khi bắt đầu load đến khi nội dung đầu tiên hiển thị. Mục tiêu: dưới 1.8 giây.

Largest Contentful Paint (LCP): Thời gian để phần tử lớn nhất hiển thị. Mục tiêu: dưới 2.5 giây.

Time to Interactive (TTI): Thời gian đến khi trang có thể tương tác. Mục tiêu: dưới 3.8 giây.

Sử dụng Google PageSpeed Insights, Lighthouse, hoặc WebPageTest để đo lường. So sánh trước và sau khi implement Critical CSS:

Trước Critical CSS:
- FCP: 3.2s
- LCP: 4.8s
- TTI: 5.1s

Sau Critical CSS:
- FCP: 0.9s (cải thiện 72%)
- LCP: 1.8s (cải thiện 62%)
- TTI: 2.4s (cải thiện 53%)

Những lỗi thường gặp khi implement Critical CSS

Lỗi 1: Inline quá nhiều CSS
Critical CSS chỉ nên chứa CSS cho phần above-the-fold. Nếu file inline vượt quá 14KB, bạn đang làm sai. Hậu quả: HTML file quá lớn, làm chậm việc parse HTML.

Lỗi 2: Quên load phần CSS còn lại
Sau khi inline Critical CSS, nhiều người quên load phần CSS còn lại, khiến các phần dưới fold bị mất style. Luôn đảm bảo có mechanism để load full CSS sau khi Critical CSS đã render.

Lỗi 3: Không minify Critical CSS
Critical CSS cần được minify để giảm kích thước. Sử dụng tools như cssnano hoặc clean-css:

const CleanCSS = require('clean-css');
const minified = new CleanCSS().minify(criticalCSS).styles;

Lỗi 4: Duplicate styles
Critical CSS được inline trong head, sau đó lại có trong full CSS file. Điều này tạo ra duplicate, làm tăng kích thước. Cách giải quyết: Remove Critical CSS khỏi full CSS file hoặc sử dụng tool tự động loại bỏ duplicate.

Critical CSS với frameworks và CMS

WordPress:
Sử dụng plugins như Autoptimize hoặc WP Rocket có tích hợp Critical CSS generation. Hoặc tự implement bằng cách hook vào wp_head:

function add_critical_css() {
    if (is_front_page()) {
        echo '<style>' . file_get_contents(get_template_directory() . '/critical-home.css') . '</style>';
    }
}
add_action('wp_head', 'add_critical_css', 1);

Next.js:
Next.js tự động inline CSS cho components above-the-fold. Bạn có thể tối ưu thêm với Critters:

// next.config.js
module.exports = {
    experimental: {
        optimizeCss: true
    }
};

React/Vue:
Với Single Page Applications, Critical CSS phức tạp hơn vì nội dung thay đổi động. Sử dụng code-splitting và lazy loading CSS theo route:

const Home = lazy(() => import('./pages/Home'));
const Blog = lazy(() => import('./pages/Blog'));

Kết luận

Critical CSS là một trong những kỹ thuật tối ưu performance quan trọng nhất mà mọi web developer nên biết. Bằng cách inline CSS cần thiết cho phần above-the-fold và load bất đồng bộ phần còn lại, bạn có thể giảm đáng kể thời gian First Contentful Paint và Largest Contentful Paint, mang lại trải nghiệm người dùng tốt hơn và cải thiện SEO ranking.

Việc implement Critical CSS có thể phức tạp ban đầu, nhưng với các tools tự động như Critical, Penthouse, hay Critters, quá trình này trở nên dễ dàng hơn nhiều. Quan trọng nhất là hiểu rõ nguyên lý hoạt động và đo lường kết quả để đảm bảo việc tối ưu thực sự hiệu quả.

Hãy bắt đầu áp dụng Critical CSS cho website của bạn ngay hôm nay và trải nghiệm sự khác biệt về tốc độ tải trang. Người dùng của bạn sẽ cảm nhận rõ sự cải thiện, và Google cũng sẽ đánh giá cao website của bạn hơn trong kết quả tìm kiếm.

Bình luận


  • Không có bình luận.

Init Toolbox

Nhấn Ctrl + \ trên máy tính, hoặc vuốt sang trái ở bất kỳ đâu trên mobile.

Đăng nhập





Đang tải...