Kompresi artinya server mengecilkan file teks (HTML, CSS, JavaScript, JSON, SVG) sebelum dikirim, lalu browser mengembalikannya ke ukuran asli begitu sampai. Isinya sama persis, cuma yang lewat jaringan jauh lebih sedikit. Mirip mengepak baju pakai kantong vakum: bajunya sama, kopernya jauh lebih ringkas, dan begitu dibuka di tujuan ukurannya kembali normal. Tapi batu bata gak bisa divakum: file yang sudah terkompresi, seperti foto dan video, gak bisa dikecilkan lagi.
🧪 Tebakan cepat: di Lab ada
app.js, bundle JavaScript asli yang sudah di-minify, 199,9 KB. Setelah di-gzip, kira-kira jadi berapa: 150 KB, 100 KB, atau 47 KB? Tebak dulu, jawabannya ada di bagian "Seberapa kecil?".
Browser dan server sepakat lewat header
Browser memberi tahu kompresi apa saja yang dia bisa buka lewat header request Accept-Encoding. Server memilih satu, mengompres, lalu menyebut pilihannya di header response Content-Encoding:
GET /assets/app.js HTTP/2
accept-encoding: gzip, deflate, br, zstd
HTTP/2 200
content-type: text/javascript
content-encoding: br
vary: Accept-Encoding
content-length: 37673
accept-encoding: gzip, deflate, br, zstdadalah yang dikirim Chrome lewat HTTPS.brartinya Brotli. Lewathttp://biasa, browser cuma menawarkangzip, deflate.content-encoding: brberarti isi response-nya dikompres Brotli. Gak ada header ini berarti dikirim apa adanya.vary: Accept-Encodingmemberi tahu cache (CDN, proxy) bahwa isi response tergantung header itu, supaya browser yang gak bisa Brotli gak pernah dikirimi versi Brotli.content-length: 37673adalah ukuran yang lewat jaringan: 37.673 byte, padahal file aslinya 199.850 byte.
Kamu gak menulis kode apa pun di halaman: browser membuka kompresinya otomatis. Yang diatur adalah server-nya.
Seberapa kecil?
Ini file di Lab, diukur betulan dengan gzip level 6 dan Brotli level 11 (1 KB = 1.000 byte):
| File | Asli | gzip | Brotli |
|---|---|---|---|
app.js |
199,9 KB | 46,7 KB (76,6% lebih kecil) | 37,7 KB (81,1% lebih kecil) |
style.css |
47,3 KB | 8,9 KB (81,2%) | 7,9 KB (83,4%) |
index.html |
49,4 KB | 14,0 KB (71,6%) | 11,8 KB (76,1%) |
hero.webp |
98,9 KB | 98,5 KB (0,4%) | 98,3 KB (0,6%) |
app.js jadi 46,7 KB dengan gzip. Itu jawaban tebakannya. Teks gampang dikompres karena isinya penuh pengulangan: function, const, nama class, tag HTML yang sama berkali-kali. Secara umum, file teks mengecil 60 sampai 80 persen, rata-rata sekitar 70 persen; JavaScript yang sudah di-minify sering sekitar 70 sampai 80 persen.
Di jaringan 1,6 Mbps (sekitar 200 KB per detik), app.js butuh 1 detik kalau dikirim apa adanya, dan cuma 0,19 detik dengan Brotli. Satu hal yang gak berubah: begitu sampai, browser membuka kompresinya, jadi JavaScript engine tetap mem-parse dan menjalankan 199,9 KB. Kompresi menghemat jaringan, bukan kerja CPU di HP user.
gzip atau Brotli
- gzip sudah ada sejak tahun 1990-an dan didukung semua browser serta server.
- Brotli (
br) buatan Google, menghasilkan file sekitar 10 sampai 25 persen lebih kecil daripada gzip untuk teks. Di Lab,app.js37,7 KB dengan Brotli lawan 46,7 KB dengan gzip: hampir 20 persen lebih kecil. - Harganya: Brotli di level tertinggi (11) jauh lebih lambat waktu mengompres. Di satu laptop,
app.jsbutuh sekitar 245 ms dengan Brotli 11, dan cuma sekitar 4 ms dengan gzip level 6. Membukanya di browser sama-sama cepat, di bawah 1 ms. - Semua browser modern mendukung Brotli lewat HTTPS. Pasang keduanya: Brotli untuk browser yang menawarkannya, gzip sebagai cadangan. zstd, yang lebih baru, juga mulai ditawarkan Chrome dan Firefox.
Statis atau on-the-fly
Ada dua waktu untuk mengompres:
- Statis, saat build. File yang isinya gak berubah (
app.js,style.css) dikompres sekali saat deploy, disimpan sebagaiapp.js.brdanapp.js.gz, lalu server tinggal mengirim yang cocok. Karena cuma sekali, pakai level tertinggi: Brotli 11. - On-the-fly, tiap request. Response yang dibuat saat itu juga, misalnya JSON dari API, dikompres setiap kali dikirim. Pakai level sedang, misalnya Brotli 4 sampai 5 atau gzip 6, supaya server gak sibuk mengompres.
Contoh di Nginx (modul Brotli perlu dipasang terpisah):
gzip on;
gzip_types text/css text/javascript application/javascript application/json image/svg+xml;
gzip_min_length 1000; # file di bawah 1.000 byte gak dikompres
gzip_static on; # kirim app.js.gz kalau sudah ada
brotli on;
brotli_comp_level 5; # on-the-fly: level sedang
brotli_types text/css text/javascript application/javascript application/json image/svg+xml;
brotli_static on; # kirim app.js.br hasil build kalau sudah ada
text/html gak perlu ditulis: Nginx selalu mengompres HTML begitu gzip on. Banyak hosting modern (Cloudflare, Vercel, Netlify) sudah mengompres otomatis.
Yang gak perlu dikompres
- Gambar, video, audio: JPEG, PNG, WebP, AVIF, MP4 sudah terkompresi di dalam format-nya. Di Lab,
hero.webpcuma hemat 0,4 persen, dan CPU server terbuang. - Font WOFF2: di dalamnya sudah Brotli. Di Lab,
font.woff2malah membesar 23 byte dengan gzip. - File yang sangat kecil: gzip menambah kepala dan ekor sekitar 18 byte.
produk.jsonberisi 1 produk, 116 byte, jadi 123 byte setelah di-gzip. Makanya ada batas minimum sepertigzip_min_length 1000.
🎯 Cek di DevTools
Buka tab Network, muat ulang halaman, lalu klik satu file JS. Di Response Headers, cari content-encoding: harus br atau gzip. Di daftar file, kolom Size menampilkan dua angka kalau kamu aktifkan "Big request rows": yang atas ukuran yang lewat jaringan, yang bawah ukuran asli. Kalau dua angka itu hampir sama untuk file teks, kompresinya belum aktif.
⚠️ Jebakan yang sering ketemu
- Mengompres gambar dan font. Gak ada hematnya, kadang malah membesar, dan CPU server terbuang. Batasi kompresi ke type teks.
- Brotli level 11 on-the-fly. Tiap request menunggu ratusan milidetik cuma untuk dikompres. Level 11 untuk build, level sedang untuk response dinamis.
- Lupa
Vary: Accept-Encoding. CDN bisa menyimpan versi Brotli dan mengirimkannya ke client yang gak bisa membukanya. - Mengira kompresi mengurangi kerja browser. Ukuran yang di-parse tetap ukuran asli. Untuk mengurangi JavaScript-nya sendiri, pakai minify, tree shaking, dan code splitting.
TL;DR: Kompresi mengecilkan file teks sebelum dikirim. Browser menawarkan lewat Accept-Encoding (Chrome lewat HTTPS: gzip, deflate, br, zstd), server menjawab dengan Content-Encoding dan Vary: Accept-Encoding. Teks biasanya mengecil 60 sampai 80 persen, rata-rata sekitar 70 persen: di Lab app.js 199,9 KB jadi 46,7 KB (gzip) atau 37,7 KB (Brotli). Brotli sekitar 10 sampai 25 persen lebih kecil dari gzip tapi jauh lebih lambat dikompres di level 11, jadi level itu dipakai saat build; response dinamis dikompres on-the-fly di level sedang. Jangan kompres gambar, video, WOFF2, dan file di bawah sekitar 1 KB. Kompresi menghemat jaringan, bukan kerja parse.