HTTP adalah aturan bicara antara browser dan server: browser mengirim request (GET /style.css), server menjawab dengan response. Isinya sama di semua versi, yang beda adalah cara mengangkutnya lewat jaringan. HTTP/1.1 (1997), HTTP/2 (2015), dan HTTP/3 (2022) makin pintar memakai satu sambungan. Bayangin antre di minimarket: HTTP/1.1 itu enam kasir yang masing-masing melayani satu pembeli sampai selesai, jadi pembeli dengan keranjang penuh menahan semua yang antre di belakangnya. HTTP/2 itu satu kasir yang memindai barang semua pembeli bergantian, jadi gak ada yang menunggu giliran. HTTP/3 sama, tapi kalau satu barang jatuh ke kolong meja, cuma pemilik barang itu yang menunggu.
🧪 Tebakan cepat: halaman di Lab memuat 14 file setelah HTML. Dengan HTTP/1.1 semuanya selesai di 875 ms. Kalau server-nya pindah ke HTTP/2 tanpa mengubah satu baris kode pun, halamannya lebih cepat, sama, atau lebih lambat? Tebak dulu, jawabannya ada di bagian "HTTP/2: banyak request di satu koneksi".
HTTP/1.1: satu request per koneksi
HTTP/1.1 berjalan di atas TCP, sambungan yang menjamin data sampai lengkap dan berurutan. Sebelum request pertama, browser butuh dua kali bolak-balik (disebut RTT, round trip time): satu untuk membuka TCP, satu untuk TLS (enkripsi HTTPS). Lalu aturannya:
- Satu koneksi cuma mengerjakan satu request pada satu waktu. Request berikutnya menunggu response sebelumnya selesai.
- Browser membuka paling banyak 6 koneksi per host. File ke-7 dan seterusnya antre.
- File yang lambat menahan semua yang antre di belakangnya di koneksi itu. Ini disebut head-of-line blocking.
Di Lab (RTT 100 ms, 14 file: style.css, app.js, dan 12 gambar kecil), HTML selesai di 408 ms. Koneksi pertama langsung mengambil style.css. Lima koneksi baru butuh 200 ms untuk TCP dan TLS, jadi baru siap di 608 ms. Ke-14 file dikerjakan dalam tiga gelombang, dan halaman baru lengkap di 875 ms.
HTTP/2: banyak request di satu koneksi
HTTP/2 tetap memakai TCP, tapi memotong tiap request dan response jadi potongan kecil (frame) yang diberi nomor stream. Potongan dari banyak stream boleh dikirim selang-seling di satu koneksi. Ini namanya multiplexing: gak ada request yang menunggu giliran.
- Di Lab, ke-14 file diminta sekaligus di 408 ms, di koneksi yang sama dengan HTML. Halaman lengkap di 628 ms, bukan 875 ms. Lebih cepat, tanpa mengubah kode: itu jawaban tebakannya.
- Header compression (HPACK): header yang sama di tiap request (cookie, user-agent) gak dikirim ulang utuh.
- Browser cuma memakai HTTP/2 lewat HTTPS. Mengaktifkannya urusan server, bukan kode halaman.
- Server Push, fitur HTTP/2 untuk mengirim file sebelum diminta, sudah dihapus dari browser (Chrome mematikannya sejak 2022, Firefox sejak 2024). Pakai
<link rel="preload">atau response 103 Early Hints.
Masalah yang tersisa: paket hilang di TCP
Data di jaringan dikirim dalam paket, dan kadang satu paket hilang, apalagi di sinyal HP yang lemah. TCP menjamin urutan, jadi kalau satu paket hilang, semua data sesudahnya ditahan sampai paket itu dikirim ulang, sekitar satu RTT. Di HTTP/2 semua stream ada di satu sambungan TCP, jadi semua ikut tertahan, walaupun paket yang hilang cuma milik satu file.
Di Lab, satu paket app.js hilang di HTTP/2: ke-13 file lain ikut menunggu, dan semua gambar yang tadinya selesai di 592 ms baru bisa dipakai di 637 ms. Jadi multiplexing memperbaiki head-of-line blocking di level HTTP, tapi belum di level TCP.
HTTP/3: QUIC di atas UDP
HTTP/3 gak memakai TCP lagi. Dia memakai QUIC, protokol baru yang dibangun di atas UDP. UDP cuma mengirim paket tanpa janji urutan; QUIC menambahkan sendiri keandalan dan urutan, tapi per stream.
- Paket hilang cuma menahan stream pemiliknya. Di Lab, satu paket
app.jshilang di HTTP/3: cumaapp.jsyang menunggu, gambar tetap selesai di 492 ms. - Handshake lebih cepat: QUIC menggabungkan sambungan dan TLS 1.3 jadi 1 RTT, bukan 2. Di Lab, halaman lengkap di 528 ms, bukan 628 ms. Pengunjung yang kembali bahkan bisa langsung mengirim data (0-RTT).
- Connection migration: pindah dari Wi-Fi ke data seluler tanpa menyambung ulang.
- Browser baru tahu server mendukung HTTP/3 dari header
Alt-Svc(atau record DNS). Jadi kunjungan pertama biasanya masih HTTP/2, kunjungan berikutnya baru HTTP/3.
Trik HTTP/1.1 yang sekarang merugikan
Dulu orang mengakali batas 6 koneksi. Di HTTP/2 dan HTTP/3, trik itu gak perlu lagi, bahkan merugikan:
- Domain sharding: menyebar file ke
img1.tokoku.iddanimg2.tokoku.idsupaya dapat lebih banyak koneksi. Tiap domain baru butuh DNS dan handshake sendiri. Di Lab, HTTP/2 dengan sharding jadi 880 ms, dari 628 ms. Di HTTP/1.1 pun gak menolong di halaman ini (875 jadi 880 ms). - Sprite: menggabungkan semua ikon jadi satu gambar. Gak perlu lagi, dan satu ikon berubah membuat seluruh sprite harus diunduh ulang.
- Menggabungkan semua JavaScript jadi satu file raksasa. Beberapa chunk berukuran sedang (hasil code splitting) aman di HTTP/2 dan lebih ramah cache. Tapi ribuan file kecil tetap rugi: tiap request punya ongkos sendiri.
🎯 Mengaktifkan dan mengecek
Di Nginx 1.25 ke atas:
server {
listen 443 ssl;
listen 443 quic reuseport; # HTTP/3 lewat UDP
http2 on; # HTTP/2
http3 on;
server_name tokoku.id;
ssl_certificate /etc/ssl/tokoku.crt;
ssl_certificate_key /etc/ssl/tokoku.key;
# Kasih tahu browser: HTTP/3 tersedia di port 443
add_header Alt-Svc 'h3=":443"; ma=86400';
}
Buka port UDP 443 di firewall juga. CDN seperti Cloudflare biasanya sudah menyalakan keduanya. Untuk mengecek, buka tab Network di DevTools, klik kanan judul kolom, nyalakan Protocol: isinya http/1.1, h2, atau h3.
⚠️ Jebakan yang sering ketemu
- Masih domain sharding di HTTP/2. Koneksi tambahan butuh DNS dan handshake, dan file-nya malah lebih lambat.
- Mengandalkan Server Push. Sudah dihapus dari Chrome dan Firefox. Pakai preload atau 103 Early Hints.
- Mengira HTTP/2 bebas head-of-line blocking. Di level TCP masih ada: satu paket hilang menahan semua stream. Itu yang diperbaiki HTTP/3.
- Mengaktifkan HTTP/3 tapi lupa
Alt-Svcatau port UDP. Browser gak pernah tahu, jadi tetap memakai HTTP/2.
TL;DR: HTTP/1.1 mengerjakan satu request per koneksi dan cuma 6 koneksi per host, jadi file antre dan saling menahan (head-of-line blocking). HTTP/2 memakai multiplexing: banyak request selang-seling di satu koneksi TCP, plus header compression (HPACK); di Lab 875 ms jadi 628 ms tanpa mengubah kode. Tapi di TCP, satu paket hilang menahan semua stream. HTTP/3 memakai QUIC di atas UDP: paket hilang cuma menahan stream-nya sendiri, dan handshake cuma 1 RTT (628 jadi 528 ms). Server Push sudah dihapus dari browser, dan trik lama seperti domain sharding malah memperlambat.