[WP] Nén Gzip vs Brotli: khác biệt giữa 2 thuật toán nén
Để tăng tốc website, kể cả website xây dựng bằng WordPress CMS, việc thiết lập nén dữ liệu trên server rất hữu ích. Cách này giúp dữ liệu truyền giữa web server và trình duyệt tải nhanh hơn, từ đó làm website nhanh hơn. Đây là một trong những yếu tố mà người quản trị website thường cân nhắc nhiều. Nén gzip đang được dùng rộng rãi, và trên nhiều web server, xu hướng chuyển dần từ gzip sang nén Brotli ngày càng phổ biến.
1️⃣ Nén là gì?
Website URL: khi bạn truy cập địa chỉ này, trình duyệt và server bắt đầu trao đổi với nhau. Lúc này, trình duyệt cho server biết nó có thể giải nén nội dung đã được nén (Compression) hay không và dùng thuật toán nén nào. Thông tin này giúp trình duyệt giải nén đúng cách khi server gửi dữ liệu đã nén. Vì vậy, khi dùng server và trình duyệt có hỗ trợ thuật toán nén, website sẽ tải nhanh hơn nữa.

Khi kết nối tới server, trình duyệt web gửi các header như nén gzip hoặc nén Brotli. Dữ liệu được nén bằng một trong hai cách sẽ được gửi tới trình duyệt, và dữ liệu đã nén tải nhanh hơn dữ liệu chưa nén.
Content-encoding: gzip
Content-encoding: br
Các tệp được nén chủ yếu là tệp văn bản. · HTML · CSS · JavaScript
2️⃣ Nén Gzip là gì?
Các thuật toán nén phổ biến mà nhà cung cấp web hosting hay dùng là Gzip và Brotli. Bản beta của Gzip ra đời năm 1992, và phiên bản 1.0 được phát hành năm 1993. Nói chung, Gzip là một trong những phương pháp nén tiêu chuẩn dùng để nén dữ liệu khi truyền qua Internet. Phương pháp này dựa trên DEFLATE, một thuật toán nén ra đời từ sớm, và lấy tên từ gzip, chương trình nén tệp của Unix được phát triển trước đó.
DEFLATE là phương pháp nén kết hợp thuật toán LZ77 (Lempel-Ziv 1977) với mã hóa Huffman. LZ77 tìm kiếm dữ liệu lặp lại để tìm ra các chuỗi trùng khớp, rồi thay các chuỗi đó bằng mã để nén. Mã hóa Huffman dựa vào tần suất xuất hiện của từng ký tự để gán mã bit ngắn nhất, qua đó nén dữ liệu.
Gzip nén dữ liệu bằng phương pháp DEFLATE, và dùng header ‘Accept-Encoding: gzip’ trong yêu cầu và phản hồi HTTP để chỉ nén khi client hỗ trợ nén Gzip. Nhờ việc nén dữ liệu này, tốc độ tải website được cải thiện.
3️⃣ Nén Brotli là gì?
Nén Brotli được hai nhân viên Google là Jyrki Alakuijala và Zoltán Szabadka phát triển vào năm 2013.

Gzip vốn được tạo ra để nén tệp, nhưng đã được điều chỉnh để dùng được cả trên web. Ngược lại, nén Brotli được phát triển với mục đích dùng trên web. Vì vậy, khi dùng Brotli, web server có thể nén nội dung trước khi gửi tới trình duyệt. Vì nội dung được nén trước khi truyền (stream) tới trình duyệt, đây là cách tốt hơn và tiên tiến hơn.
Nén Brotli dùng hai kỹ thuật cốt lõi giống như nén GZIP là LZ77 và mã hóa Huffman.
4️⃣ Nén Gzip vs nén Brotli
Gzip dùng phương pháp DEFLATE, còn Brotli dùng định dạng riêng, bổ sung mô hình hóa ngữ cảnh vào LZ77 và mã hóa Huffman, để nén (& giải nén) dữ liệu.

- Gzip nén nhanh hơn Brotli.
- Brotli được thiết kế dành riêng cho web.
- Brotli cho tỷ lệ nén tốt hơn (tức là tạo ra tệp nén nhỏ hơn) ở mọi mức nén.
- So với Gzip, tỷ lệ nén của Brotli với 3 loại tệp tốt hơn lần lượt HTML 21%, CSS 17% và JavaScript 14%.
Ngày càng có nhiều web server ưu tiên Brotli hơn Gzip. Vì Brotli được thiết kế để nén luồng dữ liệu (stream) ngay lập tức, tốc độ giải nén tổng thể ở phía front-end được cho là nhanh hơn Gzip tới 64%.
RFC 1952, công bố vào tháng 5 năm 1996, giải thích rằng định dạng Gzip dùng phương pháp nén DEFLATE và có giá trị CRC để kiểm tra dữ liệu bị hỏng. Cuối dữ liệu đã nén có ghi giá trị CRC-32 và kích thước của dữ liệu gốc.
RFC 7932, công bố vào tháng 7 năm 2016, ghi rằng Brotli nén bằng cách kết hợp thuật toán LZ77 với mã hóa Huffman. Ngoài ra, Brotli dùng hai byte đứng trước trong dữ liệu chưa nén làm ngữ cảnh để chọn mã Huffman, và thay vì chuỗi lặp lại, nó cũng có thể tham chiếu đến các từ trong một từ điển tĩnh có kích thước 122.784 byte.
Hai định dạng này được thể hiện trong header phản hồi là [Content-Encoding: gzip] và [Content-Encoding: br]. Giá trị [br] được đăng ký làm content coding của HTTP trong RFC 7932.
| Hạng mục | Gzip | Brotli |
|---|---|---|
| Tài liệu đặc tả | RFC 1952 · tháng 5 năm 1996 | RFC 7932 · tháng 7 năm 2016 |
| Phương pháp nén | DEFLATE (LZ77 và mã hóa Huffman) | LZ77 và mã hóa Huffman · ngữ cảnh từ hai byte đứng trước · từ điển tĩnh 122.784 byte |
| Header phản hồi | Content-Encoding: gzip | Content-Encoding: br |
5️⃣ Đo thực tế nén Gzip và Brotli: server Nginx + Apache
Trên một server WordPress dùng cùng lúc Nginx và Apache, phản hồi của cùng một bài viết, tệp CSS block mặc định của WordPress và tệp jQuery được so sánh với nhau, chỉ thay đổi header yêu cầu. Yêu cầu chỉ có gzip trong [Accept-Encoding], yêu cầu chỉ có br và yêu cầu không có header đều được gửi bằng curl từ cùng server đó.
for ae in gzip br ''; do echo == ${ae:-none}; curl -s -o /dev/null -D - -w 'size: %{size_download}\n' -H Accept-Encoding:$ae https://example.com/hello-world/ | grep -i -E '^(content-encoding|size)'; done== gzip
content-encoding: gzip
size: 21390
== br
content-encoding: br
size: 20190
== none
size: 90833HTML của một bài viết được nén còn 21.390 byte với yêu cầu gzip và 20.190 byte với yêu cầu br, còn yêu cầu không có header nhận về 90.833 byte chưa nén. Phản hồi br nhỏ hơn gzip 1.200 byte (5,6%).
for f in wp-includes/css/dist/block-library/style.min.css wp-includes/js/jquery/jquery.min.js; do for ae in gzip br ''; do echo == ${f##*/} ${ae:-none}; curl -s -o /dev/null -D - -w 'size: %{size_download}\n' -H Accept-Encoding:$ae https://example.com/$f | grep -i -E '^(content-encoding|size)'; done; done== style.min.css gzip
content-encoding: gzip
size: 19655
== style.min.css br
size: 140829
== style.min.css none
size: 140829
== jquery.min.js gzip
content-encoding: gzip
size: 30633
== jquery.min.js br
size: 87553
== jquery.min.js none
size: 87553Với yêu cầu gzip, tệp CSS được nén còn 19.655 byte và tệp jQuery còn 30.633 byte. Khi chỉ yêu cầu br hoặc không có header, server trả nguyên bản gốc 140.829 byte và 87.553 byte mà không có header [Content-Encoding].
nginx -V 2>&1 | grep -c brotli0httpd -M 2>/dev/null | grep -E 'brotli|deflate' deflate_module (shared)
brotli_module (shared)Các tệp tĩnh như CSS và JS do Nginx trực tiếp trả về và nén; Nginx trong cấu hình này không có module Brotli nên chỉ nén bằng gzip.
Với HTML, WordPress trả lời yêu cầu mà Nginx chuyển sang Apache, rồi Apache nén phản hồi đó. Apache có cả module Brotli lẫn module [mod_deflate] phụ trách nén Gzip.
for f in hello-world/ wp-includes/css/dist/block-library/style.min.css wp-includes/js/jquery/jquery.min.js; do echo == $f; curl -s -o /dev/null -D - -w 'size: %{size_download}\n' -H 'Accept-Encoding: gzip, deflate, br, zstd' https://example.com/$f | grep -i -E '^(content-encoding|size)'; done== hello-world/
content-encoding: gzip
size: 21390
== wp-includes/css/dist/block-library/style.min.css
content-encoding: gzip
size: 19655
== wp-includes/js/jquery/jquery.min.js
content-encoding: gzip
size: 30633Server có module Brotli không có nghĩa là trình duyệt sẽ nhận được phản hồi nén bằng Brotli. Khi gửi yêu cầu với [gzip, deflate, br, zstd], giống giá trị mà Edge 155 gửi, Apache cũng nén HTML bằng gzip, và cả ba tệp đều được trả về bằng gzip.
Dù đặt br trước gzip hay đánh dấu ưu tiên br như [br;q=1.0, gzip;q=0.5], HTML vẫn được trả về bằng gzip. Khi mở cùng bài viết và hai tệp đó bằng Edge, tất cả cũng đều được truyền bằng gzip.
Thời gian tới byte đầu tiên là trung vị của các giá trị [time_starttransfer] của curl, đo 40 lần mỗi loại với thứ tự yêu cầu được xáo trộn; mỗi yêu cầu đều mở kết nối mới nên đã bao gồm cả thời gian kết nối TLS. Với HTML, phản hồi không nén là 22,7ms, gzip 26,3ms, br 26,5ms và yêu cầu giống trình duyệt là 25,0ms. Với CSS và JS, dù có nén hay không đều ở mức 18–21ms.
Tốc độ nén của Gzip và Brotli không được đo trực tiếp mà được so sánh dựa trên tài liệu công khai. RFC 7932 ghi rằng Brotli nén với tỷ lệ nén cao hơn đáng kể so với chương trình gzip, và giải nén nhanh hơn nhiều so với các bản triển khai LZMA hiện nay. Trong kho mã Brotli, Google giải thích rằng Brotli có tốc độ tương đương deflate nhưng nén chặt hơn.
Năm 2015, Cloudflare đã thử nghiệm hai phương pháp này với 10.655 tệp HTML, CSS và JavaScript. Kết quả của Brotli ở chất lượng cao nhất nhỏ hơn trung bình 1,19 lần so với zlib ở chất lượng cao nhất, nhưng tốc độ nén chỉ 0,5MB mỗi giây, chậm hơn rất nhiều so với 41,9MB của zlib mức 9. Brotli mức 4 có tỷ lệ nén tương đương zlib mức 8 và nhanh hơn một chút nếu tính trung bình toàn bộ, nhưng nếu chỉ xét các tệp nhỏ hơn 64KB thì chậm hơn 1,48 lần.
Bài viết đã điểm qua quá trình tối ưu website bằng cách nén các tệp như HTML, CSS và JavaScript. Để cải thiện tốc độ website, có thể nói nén tệp và Tối ưu hình ảnh là những yếu tố thiết yếu.
🔢 FAQ & nội dung đề xuất
ℹ️ Thông báo tiếp thị liên kết
Nội dung trên trang này có chứa liên kết affiliate (tiếp thị liên kết). Khi khách truy cập mua sản phẩm hoặc dịch vụ qua các liên kết này, trang sẽ nhận hoa hồng từ bên bán. Trong quá trình đó, số tiền người mua phải trả (sẽ giảm khi có chương trình khuyến mãi ↓) không hề tăng lên. Giá, khuyến mãi và tình trạng hàng được đăng theo thời điểm viết bài và có thể khác với thực tế, vì vậy hãy kiểm tra lại lần cuối với bên bán trước khi mua. Việc chọn và đánh giá sản phẩm dựa trên tiêu chí riêng của trang; việc có nhận hoa hồng hay không không ảnh hưởng đến thứ tự giới thiệu hay nội dung đánh giá.

