Tailwind CSS 4.0: Cấu hình tối giản, engine mới và tối ưu hiệu suất CSS

2 tháng trước · 9 phút đọc
Tailwind 4.0 không phải là bản update thông thường
Mình đã dùng Tailwind từ hồi v2, và khi đọc changelog của v4, phản ứng đầu tiên là: "Ủa, cái này khác hoàn toàn rồi." Không phải kiểu thêm vài utility mới hay fix bug - đây là viết lại gần như toàn bộ kiến trúc.
Tailwind 4.0 ra mắt năm 2025 với ba thay đổi cốt lõi: engine xử lý được viết lại bằng Rust (tên là Oxide), cấu hình chuyển hoàn toàn sang CSS thay vì JavaScript, và content scanning trở thành tự động. Ba điểm này liên kết với nhau và thay đổi cách bạn làm việc với framework từ gốc rễ.
Tại sao bây giờ? Vì CSS hiện đại đã đủ mạnh để gánh được những thứ trước đây phải nhờ đến JavaScript config - cascade layers, container queries, CSS custom properties. Tailwind 4.0 tận dụng triệt để những khả năng này.
Ba trụ cột của Tailwind 4.0 - engine mới, config mới, và CSS hiện đại
Nếu bạn đang dùng Tailwind v3 và chưa chắc có nên upgrade không, bài này sẽ cho bạn đủ thông tin để quyết định.
Engine Oxide: tại sao Rust lại quan trọng
Trước đây Tailwind chạy trên pipeline JavaScript/PostCSS. Ổn với dự án nhỏ, nhưng khi codebase lớn lên, build time bắt đầu leo thang. Mình từng có dự án mà full build mất gần 8 giây - chưa tệ lắm, nhưng incremental build sau mỗi lần save cũng mất 1-2 giây, cộng dồn lại khá khó chịu.
Engine Oxide viết bằng Rust giải quyết vấn đề này ở tầng thấp nhất. Rust cho phép xử lý song song và quản lý bộ nhớ hiệu quả hơn JavaScript nhiều, đặc biệt khi quét hàng nghìn file để tìm class usage.
So sánh tốc độ build giữa Tailwind v3 và v4 trong các ngữ cảnh khác nhau
Các benchmark được ghi nhận từ cộng đồng cho thấy 3.78x faster full build (378ms → 100ms), 8.8x faster incremental rebuild (44ms → 5ms), 182x faster incremental rebuild with no CSS changes (35ms → 192µs) (Tailwind Labs Official Benchmarks) tùy ngữ cảnh. Full build nhanh hơn đáng kể, incremental build - tức là khi bạn chỉ sửa 1-2 file - thì cải thiện còn rõ hơn. Lý do là engine mới chỉ reprocess đúng phần thay đổi thay vì quét lại toàn bộ.
Một điểm cần nói thẳng: "JIT engine mới" mà nhiều bài viết nhắc đến không phải là JIT cũ được cải tiến. Đây là một engine khác hoàn toàn. JIT của v3 vẫn là JavaScript. Oxide của v4 là Rust, tích hợp trực tiếp với build pipeline thay vì chạy qua PostCSS như một plugin.
CSS-first configuration: nói lời tạm biệt với tailwind.config.js
Đây là thay đổi nhiều người dùng lâu năm sẽ thấy lạ nhất. Ở v3, mình quen với việc mở tailwind.config.js để extend theme, thêm màu, khai báo custom spacing. Ở v4, bạn làm tất cả điều đó ngay trong CSS.
Thay vì:
Bây giờ bạn viết:
CSS-first config - mọi thứ sống trong một file, không cần nhảy qua lại giữa JS và CSS
Cái hay ở đây là @theme không chỉ là nơi khai báo - các biến bạn định nghĩa trong đó trực tiếp trở thành CSS custom properties, có thể dùng ở runtime. Nghĩa là bạn có thể đọc var(--color-brand) trong JavaScript, trong CSS animation, hoặc trong bất kỳ component library nào - không cần import file config JS nữa.
@utility cũng tương tự - tạo utility tùy biến mà không cần viết plugin:
Sau đó dùng ngay: <div class="flex-center">. Đơn giản, không boilerplate.
Một entry point duy nhất @import "tailwindcss"; thay cho ba directive cũ @tailwind base; @tailwind components; @tailwind utilities;. Ít magic hơn, dễ debug hơn.
Dark mode và responsive trong v4
Cách viết responsive vẫn quen thuộc như v3 - breakpoint prefix sm:, md:, lg:, xl:. Nhưng v4 bổ sung thêm container queries như một tính năng native, không cần plugin:
Container queries giúp component phản ứng theo kích thước container của chính nó, không phải viewport. Đây là điểm mà responsive design truyền thống (theo viewport) thường bị thiếu - một card trong sidebar sẽ layout khác với cùng card đó ở main content, dù viewport không đổi.
Container queries: component tự layout theo không gian của mình, không phụ thuộc viewport
Dark mode với CSS variables
Trước đây dark mode với Tailwind thường là toggle class và viết dark:text-white dark:bg-gray-900 khắp nơi. Vẫn được, nhưng v4 mở ra cách tiếp cận gọn hơn qua CSS variables:
Hoặc class-based:
Sau đó trong HTML chỉ cần bg-[var(--color-background)] hoặc tạo utility wrapper. Token thay đổi, toàn bộ UI cập nhật - không cần dark: prefix dày đặc trên mỗi element.
Cách này đặc biệt hữu ích khi bạn có nhiều theme (không chỉ light/dark) hoặc cần đổi palette theo context như user preference, A/B testing, branded experience.
Migration guide từ Tailwind v3 lên v4
Mình sẽ không bảo bạn "migration dễ lắm" vì thật ra nó đòi hỏi kiểm tra khá kỹ, nhất là với dự án lớn. Nhưng cũng không quá phức tạp nếu bạn biết những điểm cần đổi.
Bước 1: Cài đặt
Bước 2: Đổi entry CSS
Bước 3: Chuyển theme sang @theme
Ba bước migration chính từ v3 lên v4 - đổi cài đặt, đổi entry CSS, đổi theme config
Bước 4: Kiểm tra các thay đổi breaking
Một số thay đổi cần chú ý:
contenttrong config không còn cần thiết - v4 tự scan. Xóa đi để tránh conflict.- Các plugin v3 chưa chắc tương thích với v4. Kiểm tra từng plugin hoặc thay bằng
@utility. @applyvẫn hoạt động nhưng một số cú pháp edge case có thể behave khác.- Nếu bạn dùng class prefix (như
tw-), cú pháp cấu hình prefix đã thay đổi.
Bước 5: Dùng codemod tự động
Tailwind Labs cung cấp codemod để migrate tự động phần lớn config:
Chạy xong, bạn vẫn nên review thủ công kết quả - codemod xử lý được phần lớn nhưng edge case thì vẫn cần mắt người.
Nếu bạn muốn nắm vững Tailwind từ gốc trước khi migrate, khóa Tailwind CSS của F8 là điểm khởi đầu tốt.
Best practices để tối ưu bundle size
Một trong những lý do người ta chọn Tailwind là CSS output nhỏ hơn nhiều so với viết custom CSS hết - engine chỉ generate class nào thật sự được dùng. Ở v4, cơ chế này mạnh hơn và có thêm vài cách để tối ưu.
1. Một entry point duy nhất
Chỉ import @import "tailwindcss"; ở đúng một file CSS. Import nhiều chỗ sẽ khiến engine generate duplicate output.
2. Khai báo token tối thiểu trong @theme
Chỉ định nghĩa token bạn thật sự dùng. Đừng copy toàn bộ design system vào @theme nếu chỉ dùng 20% trong số đó.
3. Tận dụng tự động content detection
V4 scan content tự động - đừng override bằng safelist trừ khi thật sự cần. Safelist giữ class dù không dùng, làm phình bundle.
4. Ưu tiên utility gốc thay vì custom CSS
Bốn chiến lược tối ưu bundle - áp dụng đúng thứ tự sẽ giảm CSS output đáng kể
Thực tế mức giảm bundle size phụ thuộc nhiều vào dự án. Dự án cũ với custom CSS nhiều, safelist lớn, và import lung tung sẽ thấy cải thiện rõ hơn. Dự án đã build tốt từ đầu thì output giảm ít hơn nhưng build time vẫn nhanh hơn hẳn nhờ engine Oxide.
Takeaways:
- Entry point duy nhất, token tối thiểu, không safelist trừ khi cần
- Tin tưởng automatic detection thay vì cấu hình thủ công
@utilitycho custom utility thay vì viết raw CSS riêng
Gặp vướng mắc trong quá trình migrate hoặc optimize, drop comment bên dưới - mình hay check.
