Một file JavaScript nhỏ hơn sau nén có thể giúp giảm lượng dữ liệu truyền, nhưng chưa đủ để kết luận cấu hình mới tốt hơn cho toàn hệ thống. Bạn còn cần biết nén lúc build hay mỗi request, client giải mã được gì và cache đang lưu biến thể nào.
Bài này đánh giá gzip và Brotli bằng một phép thử local nhỏ. Mã được chạy trên Node.js 24.18.1, nguồn đối chiếu ngày 25/10/2026. Dữ liệu hoàn toàn tự tạo, không phải bundle production; bài không cung cấp benchmark độ trễ, CPU hoặc băng thông tiết kiệm của một website thật.
1. Đo cùng đầu vào và kiểm tra chiều ngược lại
Node có các hàm nén và giải nén trong module zlib chính thức. Ví dụ dùng các hàm Sync vì đây là script local xử lý một buffer nhỏ. Không đặt nguyên đoạn Sync này vào đường xử lý request của server rồi coi đó là cấu hình vận hành đã được đánh giá.
Tạo compression-demo.mjs:
import assert from 'node:assert/strict';
import {
gzipSync, gunzipSync,
brotliCompressSync, brotliDecompressSync,
constants,
} from 'node:zlib';
const lines = Array.from({length: 200}, (_, id) => JSON.stringify({
id,
title: 'Hướng dẫn lập trình dành cho developer Việt Nam',
category: 'tutorial',
}));
const input = Buffer.from(lines.join('\n'), 'utf8');
const variants = [
['gzip', gzipSync(input, {level: 6}), gunzipSync],
['br', brotliCompressSync(input, {
params: {[constants.BROTLI_PARAM_QUALITY]: 4},
}), brotliDecompressSync],
];
console.log('raw bytes:', input.length);
for (const [name, compressed, decompress] of variants) {
assert.deepEqual(decompress(compressed), input);
console.log(name, 'bytes:', compressed.length, 'roundtrip: ok');
}
Chạy bằng node compression-demo.mjs. Script in số byte đầu vào và hai đầu ra, đồng thời dừng nếu giải nén không khớp buffer gốc. Cả hai phép roundtrip đã qua kiểm tra trong lượt biên tập. Kích thước ở đây thuộc riêng fixture và cấu hình đã ghi, không phải một tỷ lệ nén đại diện cho mọi JavaScript hay CSS.
Level 6 của gzip và quality 4 của Brotli là hai tham số khác thang đo; chúng không tạo thành một cặp “cùng chất lượng” để suy luận tốc độ. Khi tự so sánh nhiều cấu hình, giữ dữ liệu gốc cố định và ghi rõ mọi tham số.
2. So sánh theo cùng nhóm tiêu chí
Về độ dễ bắt đầu, hãy kiểm tra stack đang có sẵn gì: CDN, reverse proxy hoặc bước build có thể đã hỗ trợ một hay cả hai định dạng. Nếu hệ thống đã phục vụ gzip đúng, việc thêm Brotli cần một mục tiêu đo được thay vì thay đổi chỉ để dùng tên công nghệ mới.
Về quyền kiểm soát, cả hai cho phép bạn chọn tham số nén. Tăng mức nén cần được đánh giá cùng chi phí tạo artifact hoặc xử lý tại runtime. Với asset bất biến theo hash, nén trước ở bước build là một phương án để thử; với nội dung động, bài toán tài nguyên và thời điểm nén khác đi.
Về hệ sinh thái, hai tên content coding được dùng trong HTTP là gzip và br, như tham chiếu Content-Encoding mô tả. Không suy ra khả năng phục vụ của hạ tầng chỉ từ việc Node local tạo được buffer Brotli. Cần kiểm tra client mục tiêu và cấu hình phân phối artifact.
Về hiệu năng, ít byte hơn là một chỉ số, không phải toàn bộ thời gian tải. Bài chưa đo tốc độ giải nén trên thiết bị yếu, thời gian build hoặc độ trễ cuối cùng trong trình duyệt. Bạn cần bộ asset thật và điều kiện thử lặp lại được để trả lời những câu hỏi đó.
Về chi phí vận hành, lưu hai biến thể cần quản lý thêm artifact, cache và đường fallback. Chọn một cấu hình dễ quan sát, có log và có thể quay lại thường hữu ích hơn việc đẩy mọi mức nén lên tối đa ngay từ đầu.
3. Kiểm tra cách phục vụ, không chỉ file trên đĩa
Khi dùng HTTP, Accept-Encoding thể hiện khả năng chấp nhận của client còn Content-Encoding mô tả dữ liệu server thực sự trả. Với cache chọn biến thể theo request header, kiểm tra cơ chế phân biệt biến thể; tài liệu Vary giải thích vai trò header này trong cache key.
Trong môi trường thử, mở công cụ mạng để đối chiếu response header, kích thước truyền và nội dung được giải mã. Xác nhận client không hỗ trợ một biến thể vẫn có đường nhận nội dung hợp lệ. Đừng đổi đuôi file thành .br rồi cho rằng trình duyệt sẽ tự hiểu mọi cấu hình header còn lại.
Lỗi thường gặp
Đừng lấy string.length làm số byte UTF-8 của text tiếng Việt; fixture dùng Buffer.length sau khi mã hóa. Đừng coi việc giải nén thành chuỗi “trông giống” là đủ; so sánh byte giúp phát hiện khác biệt nhỏ.
Không mặc định nén lại ảnh JPEG hay file zip sẽ có lợi. Tài liệu Content-Encoding lưu ý media đã nén có thể tăng kích thước khi nén thêm. Nếu proxy đã tự nén, kiểm tra đường phục vụ trước khi thêm một tầng khác để tránh cấu hình khó hiểu.
Kết luận
Bắt đầu bằng phép đo trên cùng dữ liệu, kiểm tra roundtrip và ghi cấu hình rõ ràng. Sau đó đánh giá hạ tầng phục vụ cùng chi phí vận hành. Script local giúp bạn đặt phép thử đúng; quyết định gzip hay Brotli cho sản phẩm cần thêm bằng chứng từ asset và client thực tế.



