Bỏ qua tới nội dung
Performance· ·9 phút đọc

Minify JS và CSS đúng cách (làm ở đâu, tránh bẫy gì)

Nguyễn Quốc An
Minify JS và CSS đúng cách (làm ở đâu, tránh bẫy gì)
Cỡ chữ

Khi mở DevTools và thấy một file app.js nặng 240KB, phản xạ đầu tiên của nhiều người là bật một nút “minify” nào đó. Nhưng để dùng đúng, bạn cần phân biệt rõ hai việc hoàn toàn khác nhau: rút gọn mã (minify) và nén truyền tải (compression). Hiểu sai chỗ này dẫn tới làm trùng, hoặc tệ hơn là dính một cái bẫy khiến khách thấy bản cũ suốt nhiều ngày.

Minify khác nén gzip/brotli như thế nào

Đây là điểm nhầm phổ biến nhất, nên cần tách bạch ngay.

Minify tác động vào chính nội dung file mã nguồn: bỏ khoảng trắng thừa, xoá dấu xuống dòng, cắt hết ghi chú (comment), đổi tên biến cục bộ như userAccountBalance thành a. File sau minify vẫn là một file .js hoặc .css đọc được bằng mắt (dù khó đọc), trình duyệt chạy thẳng. Việc này làm một lần lúc build rồi giữ nguyên.

Nén (compression) là gzip hoặc brotli — thuật toán nén ở tầng truyền tải HTTP. Web server gói file lại thành dạng nhị phân khi gửi qua mạng, trình duyệt nhận được sẽ tự giải nén ra. File trên đĩa không đổi; nó chỉ “co lại” trong lúc đi trên đường truyền.

MinifyNén gzip/brotli
Tác động lênNội dung file mã nguồnLuồng truyền tải HTTP
Làm khi nàoMột lần lúc build/deployMỗi lần server gửi file đi
Trình duyệt cầnKhông cần giải mã gìTự giải nén (Content-Encoding)
File trên đĩaBị thay đổi (nhỏ lại)Giữ nguyên

Quan trọng nhất: hai việc này cộng dồn, không thay thế nhau. Minify trước rồi nén sau cho kết quả gọn hơn cả. Theo tổng hợp của web.dev và các benchmark cộng đồng, từ một file JS chưa tối ưu, riêng nén gzip đã tiết kiệm khoảng 88%, brotli khoảng 90%; minify trước khi nén đẩy con số đó cao thêm. Brotli thường nén JS tốt hơn gzip 14–20% và CSS tới khoảng 28–30%, nên nếu host hỗ trợ thì ưu tiên brotli.

Sơ đồ so sánh minify mã nguồn với nén gzip brotli ở server
Minify viết gọn mã, gzip/brotli nén luồng truyền — hai việc khác nhau, nên làm cả hai.

Minify giúp gì cho Core Web Vitals

File JS/CSS nhỏ hơn nghĩa là tải nhanh hơn, và đặc biệt với JS là phân tích cú pháp (parse) nhanh hơn. Điều này gián tiếp hỗ trợ ba chỉ số Core Web Vitals (chỉ số sức khoẻ web cốt lõi) — ngưỡng “Good” năm 2026 đo ở phân vị 75 (p75) vẫn là LCP (Largest Contentful Paint — thời điểm phần tử lớn nhất hiện ra) ≤ 2,5s, INP (Interaction to Next Paint — độ trễ tới khung hình kế tiếp sau tương tác) ≤ 200ms, CLS (Cumulative Layout Shift — tổng độ xê dịch bố cục) ≤ 0,1.

Nói thẳng để bạn không kỳ vọng sai: minify là đòn bẩy nhỏ. Cắt vài chục KB không cứu được một trang mà LCP đang 4 giây vì thiếu cache trang hay ảnh quá nặng. Hãy coi nó là bước dọn dẹp cuối, làm sau khi đã xử lý cache, font và ảnh. Nếu muốn hiểu thứ tự ưu tiên đầy đủ, xem trang tối ưu Core Web Vitals.

Làm minify ở đâu — build tool là chuẩn 2026

Cách đúng hiện nay là minify tại origin, lúc build, để file gửi đi đã gọn sẵn. Hầu hết công cụ build hiện đại tự minify khi chạy bản production:

  • Vite / Rollup: tự minify bằng esbuild hoặc terser khi chạy build.
  • Webpack: dùng TerserPlugin (JS) và CssMinimizerPlugin (CSS) ở chế độ production.
  • WordPress: cấu hình ở plugin cache (LiteSpeed Cache, WP Rocket, W3 Total Cache) gộp và minify JS/CSS.

Ví dụ một cấu hình Vite tối thiểu cho production:

// vite.config.js
export default {
  build: {
    minify: 'esbuild',   // nhanh; đổi 'terser' nếu cần rút gọn sâu hơn
    cssMinify: true,
    sourcemap: false      // tắt source map ở bản chạy thật
  }
}

Với CSS thuần, công cụ phổ biến là cssnano; với JS thuần ngoài build, có thể dùng terser trực tiếp:

npx terser app.js -c -m -o app.min.js

Cờ -c nén logic (compress), -m đổi tên biến (mangle). Minify ăn nhập với hai kỹ thuật cùng họ: tree shaking để loại mã JS không dùngloại bỏ CSS thừa. Tree shaking và xoá CSS thừa cắt phần không cần trước; minify rút gọn phần còn lại. Làm cả ba mới ra file mỏng thật sự.

Bẫy thật từ thực chiến: minify + Cloudflare kẹt cache

Đây là bài học Web22 rút ra khi vận hành chính web22.dev trên LiteSpeed sau Cloudflare (CDN — mạng phân phối nội dung). Lưu ý quan trọng: từ 5/8/2024 Cloudflare đã khai tử tính năng Auto Minify và khuyến nghị minify tại origin lúc build (xem thông báo của Cloudflare). Vậy bẫy nằm ở đâu?

Vấn đề là tên file không đổi. Nếu plugin cache xuất ra style.min.css với URL cố định, rồi bạn sửa CSS và minify lại, file mới vẫn mang đúng cái tên cũ. Cloudflare đã cache phiên bản trước theo URL đó nên tiếp tục trả bản cũ cho khách — có khi nhiều ngày — dù origin đã cập nhật. Bạn xem trên máy mình (đã purge) thì thấy mới, khách thì thấy cũ.

Hai cách xử lý gốc, nên làm cả hai:

  1. Cache-busting bằng tên file đổi theo nội dung: để build tool gắn hash vào tên (vd app.a1b2c3.js). Nội dung đổi thì tên đổi, URL mới, Cloudflare buộc tải lại. Đây là cách bền nhất.
  2. Purge cache CDN sau mỗi lần deploy: nếu vẫn dùng URL cố định, bắt buộc purge Cloudflare (và purge cache plugin) ngay sau khi đẩy file mới.

Nguyên tắc rút ra: minify không gây lỗi, nhưng minify cộng với một lớp cache đứng trước mà không đổi tên file thì gây lỗi “khách thấy bản cũ”. Nếu site của bạn cũng nằm sau Cloudflare, hãy chốt quy ước cache-busting trước khi bật minify. Bạn có thể đọc thêm về cấu hình Cloudflare đúng cho web.

Sơ đồ bẫy thực chiến minify dính cache Cloudflare và cách purge để khách thấy bản mới
URL file không đổi khiến Cloudflare giữ bản cũ — cần đổi tên file hoặc purge cache.

Checklist nhanh trước khi đăng

  • Build tool bật minify cho cả JS lẫn CSS ở bản production.
  • Server bật brotli (hoặc tối thiểu gzip) — kiểm tra header Content-Encoding.
  • Tên file có hash theo nội dung, hoặc có bước purge CDN sau deploy.
  • Tắt source map ở bản chạy thật để không lộ mã gốc và không tốn dung lượng.
  • Đo lại bằng PageSpeed Insights / Lighthouse sau khi đổi.

Câu hỏi thường gặp

Minify rồi có cần nén gzip/brotli nữa không?

Có. Đây là hai lớp khác nhau và cộng dồn lợi ích. Minify gọn file gốc, nén co nhỏ lúc truyền. Bỏ qua lớp nén là phí một nửa hiệu quả.

Minify có làm hỏng code không?

Với công cụ chuẩn (terser, esbuild, cssnano) thì rất hiếm. Rủi ro chủ yếu ở JS phụ thuộc vào tên biến/hàm theo chuỗi; khi đó cấu hình giữ tên (reserved names) hoặc tránh mangle phần đó.

Nên minify thủ công hay để plugin/host lo?

Để build tool ở origin lo là chuẩn 2026. Tránh dựa vào tính năng minify của CDN — Cloudflare đã ngừng Auto Minify từ 2024.

Nếu trang của bạn đã minify mà điểm tốc độ vẫn thấp, gốc rễ thường nằm ở cache, ảnh hoặc TTFB chứ không phải dung lượng JS/CSS — đó là lúc nên xem qua dịch vụ tối ưu tốc độ website của Web22 để tìm đúng đòn bẩy.

Đọc tiếp

Bài viết
cùng chủ đề.

Tất cả bài viết