Realtime di web artinya perubahan di server sampai ke layar pengguna saat itu juga, tanpa pengguna menekan refresh. Contoh paling jelas: aplikasi chat seperti WhatsApp Web, tempat pesan temanmu langsung muncul. Bayangin Laundry Bu Rini. Mas Eko kerja di belakang, dekat mesin cuci. Bu Rini di meja depan, menghadap papan order. Waktu cucian #12 milik Pak Darto pindah ke setrika, ada dua cara Bu Rini bisa tahu: dia jalan ke belakang tiap 30 detik dan bertanya "ada yang berubah?", atau Mas Eko langsung berseru "Dua belas, disetrika!" begitu terjadi. Cara pertama namanya pull (menarik kabar), cara kedua push (mendorong kabar). Realtime di web hampir selalu soal push.
🧪 Tebakan cepat: Papan Bu Rini bertanya ke server tiap 30 detik. Mas Eko mengubah status #12 di saat yang acak. Rata-rata, berapa lama sampai perubahan itu muncul di papan: 0 detik, 15 detik, atau 30 detik? Jawabannya ada di bagian "Pull: browser yang terus bertanya".
Proyek sepanjang jalur ini: papan Laundry Bu Rini
Di jalur htmx kamu sudah membangun papan order Bu Rini di http://localhost:8000/papan, aplikasi Laravel yang menyegarkan diri tiap 30 detik. Isinya tiga order:
| Order | Pelanggan | Berat | Status | Biaya (Rp 7.000/kg) |
|---|---|---|---|---|
| #12 | Pak Darto | 3 kg | Dicuci | Rp 21.000 |
| #13 | Mbak Wulan | 2 kg | Disetrika | Rp 14.000 |
| #14 | Mas Yoga | 5 kg | Siap diambil | Rp 35.000 |
Status selalu berjalan Antre → Dicuci → Disetrika → Siap diambil. Di jalur ini papannya dibuat hidup: Mas Eko mengubah status dari tablet di dekat mesin cuci, dan layar Bu Rini ikut berubah saat itu juga. Nanti HP pelanggan dapat kabar "Siap diambil", ada chat dengan pelanggan, tanda siapa yang sedang online, kolom catatan yang bisa diketik berdua, dan dashboard. Bagian realtime-nya dipegang server kecil Node.js di http://localhost:3000, di samping aplikasi Laravel-nya.
Realtime itu "cukup cepat", bukan nol
Tiap perubahan butuh waktu untuk sampai ke layar. Jeda dari perubahan terjadi sampai tampil disebut latency. Realtime artinya latency-nya cukup kecil untuk fiturnya. Batas yang masih bisa diterima disebut latency budget.
| Fitur | Latency budget | Kenapa |
|---|---|---|
| Panggilan suara, game | di bawah 150 ms | ITU-T G.114 menyarankan jeda satu arah suara maksimal 150 ms, lebih dari itu orang mulai saling potong |
| Chat, tanda "sedang mengetik" | di bawah 1 detik | sampai 1 detik obrolan masih terasa mengalir |
| Papan order saat pelanggan menunggu | beberapa detik | pelanggan berdiri di meja dan bertanya "punya saya udah?" |
| Grafik omzet harian | 1 menit pun oke | angkanya dibaca sesekali |
Batas klasik dari Jakob Nielsen: di bawah 0,1 detik terasa langsung, di bawah 1 detik pikiran gak terputus, lebih dari 10 detik perhatian orang lepas.
Web itu soft realtime: kalau telat, pengalamannya jelek, tapi gak ada yang celaka. Lawannya hard realtime, misalnya airbag mobil, yang gagal total kalau telat sedikit saja. Jadi tentukan dulu latency budget fiturmu, baru pilih teknologinya.
Pull: browser yang terus bertanya
HTTP biasa itu request-response: browser bertanya, server menjawab. Server gak bisa bicara duluan. Supaya tetap dapat kabar terbaru, browser bertanya berulang-ulang. Ini disebut polling. Papan Bu Rini melakukannya lewat htmx dengan hx-trigger="every 30s". Versi JavaScript-nya:
setInterval(async () => {
const res = await fetch('/papan') // tanya: papan terbaru?
document.querySelector('#papan').innerHTML = await res.text() // tempel jawabannya
}, 30000) // tiap 30.000 ms = 30 detik
setInterval(..., 30000)menjalankan function-nya tiap 30 detik, terus-menerus.fetch('/papan')adalah satu request. Ada yang berubah atau gak, request-nya tetap dikirim.- Perubahan baru kelihatan di request berikutnya.
Misalkan papan bertanya di detik 0, 30, 60, dan seterusnya:
| Mas Eko mengubah status di detik | Papan bertanya lagi di detik | Bu Rini menunggu |
|---|---|---|
| 4 | 30 | 26 detik |
| 29 | 30 | 1 detik |
| 31 | 60 | 29 detik |
Tunggunya bisa berapa saja, dari hampir 0 sampai 30 detik, tergantung kapan perubahan terjadi. Kalau perubahannya datang di saat acak, rata-ratanya setengah interval: 15 detik, paling lama 30 detik. Itu jawaban tebakannya. Lab di halaman ini mengukurnya: 1.000 perubahan di waktu acak, rata-rata tunggunya keluar 14,8 detik.
Biayanya juga diukur. Satu kali bertanya dari Chromium 147 ke server lokal yang meniru papan ini (tanpa cookie): request 625 byte, header jawaban 164 byte, isi papan 234 byte. Jadi 1.023 byte per pertanyaan, 120 pertanyaan per jam, 122.760 byte per jam per tab, walaupun gak ada yang berubah sama sekali. Di Laravel asli, cookie session menambah ratusan byte lagi tiap request.
Push: server yang memberi tahu
Push butuh koneksi yang dibiarkan terbuka. Browser membuka satu koneksi ke server realtime, lalu menunggu. Begitu Mas Eko mengubah status, server menulis kabarnya ke koneksi itu, dan papan langsung berubah. Jedanya tinggal satu perjalanan jaringan dari server ke layar: di localhost di bawah 1 ms, di internet seluler biasanya puluhan sampai ratusan milidetik.
Karena koneksinya sudah terbuka, tiap kabar jadi kecil. Diukur di Chromium 147 untuk satu jam dengan 6 perubahan status:
| Cara | Request per jam | Byte per jam | Rata-rata tunggu |
|---|---|---|---|
| Polling tiap 30 detik | 120 | 122.760 | 15 detik |
| SSE (Server-Sent Events) | 1 | 819 + 6 × 65 = 1.209 | 1 perjalanan jaringan |
| WebSocket | 1 | 616 + 6 × 48 = 904 | 1 perjalanan jaringan |
Angka 819 dan 616 adalah biaya membuka koneksinya, sekali saja. Sesudah itu satu kabar status cuma 65 byte lewat SSE, atau 48 byte lewat WebSocket, karena header HTTP-nya gak dikirim ulang. Rinciannya ada di pelajaran berikutnya.
Peta pilihannya
| Teknologi | Arah | Cara kerja singkat | Dibahas di |
|---|---|---|---|
| Short polling | browser bertanya | request tiap N detik | pelajaran ini |
| Long polling | browser bertanya | server menahan jawaban sampai ada kabar | Polling vs SSE vs WebSocket |
| SSE | server ke browser | satu response HTTP yang gak pernah selesai | Server-Sent Events |
| WebSocket | dua arah | satu koneksi, pesan bolak-balik kapan saja | WebSocket Fundamentals |
| Socket.IO | dua arah | library di atas WebSocket, plus reconnect dan room | Socket.IO Basics |
| WebRTC | browser ke browser | suara, video, dan data langsung antar pengguna | WebRTC Basics |
Kapan polling sudah cukup
Polling bukan cara yang salah. Pakai polling kalau:
- Setengah interval masih masuk latency budget. Grafik omzet yang dicek pemilik sesekali boleh telat 30 detik.
- Datanya jarang berubah dan yang melihat sedikit. Satu tab admin dengan 120 request per jam gak jadi masalah.
- Infrastrukturnya harus sederhana. Polling cuma request HTTP biasa: jalan di hosting PHP mana pun, lewat proxy apa pun, dan tiap request berdiri sendiri.
Papan Bu Rini beda. Pelanggan berdiri di meja dan bertanya, jadi 15 detik terasa lama. Di sini push yang tepat.
⚠️ Jebakan yang sering ketemu
- Mengira realtime berarti nol detik. Selalu ada jeda. Tentukan dulu berapa yang boleh untuk fiturmu.
- Mengecilkan interval polling supaya "realtime". Polling tiap 1 detik berarti 3.600 request per jam per tab, dan rata-rata tunggunya masih setengah detik.
- Mengira server bisa bicara duluan lewat request biasa. Server cuma bisa menjawab request. Untuk push, koneksinya harus dibiarkan terbuka, lewat SSE atau WebSocket.
- Langsung memakai WebSocket untuk semuanya. Kalau datanya cuma mengalir dari server ke browser, SSE lebih sederhana. Kalau jarang berubah dan boleh telat, polling cukup.
TL;DR: Realtime di web artinya data yang berubah di server sampai ke layar hampir seketika, tanpa refresh, seperti pesan di WhatsApp Web. Web itu soft realtime: tentukan latency budget-nya dulu (suara di bawah 150 ms, chat di bawah 1 detik, papan order beberapa detik). Pull alias polling bertanya tiap N detik: rata-rata telat setengah interval (15 detik untuk polling 30 detik) dan membayar 1.023 byte per pertanyaan walaupun gak ada yang berubah, 122.760 byte per jam per tab. Push membiarkan koneksi terbuka, jadi tiap kabar cuma 48 sampai 65 byte dan sampai dalam satu perjalanan jaringan. Pilihannya: short polling, long polling, SSE, WebSocket, Socket.IO, WebRTC. Polling masih tepat kalau setengah interval masuk budget, datanya jarang berubah, dan infrastrukturnya harus sederhana.