- Dalam JavaScript,
setTimeout(0) sebenarnya tidak langsung dijalankan dan sering mengalami penundaan minimum 4ms, yang merupakan batasan bawaan browser untuk mencegah penyalahgunaan
- Batasan ini diterapkan untuk mencegah situs web menyalahgunakan timer secara berlebihan hingga menyebabkan boros baterai atau penurunan interaksi; dalam mode baterai batas ini bisa diperketat menjadi 16ms, dan di tab latar belakang menjadi 1 detik
- Para developer telah memanfaatkan berbagai API timer alternatif seperti
setImmediate, MessageChannel.postMessage, window.postMessage, dan scheduler.postTask untuk mengakali keterbatasan setTimeout
- Hasil benchmark nyata menunjukkan bahwa Chrome dan Firefox menerapkan clamping 4ms, tetapi
MessageChannel dan scheduler.postTask berjalan hampir tanpa jeda, sementara Safari cenderung membatasi setTimeout lebih agresif
- Pada dasarnya ini adalah persoalan keseimbangan antara perlindungan pengalaman pengguna dan kebebasan developer; saat ini Scheduler API mulai menjadi solusi standar, tetapi jika penyalahgunaan terjadi, intervensi browser baru juga bisa diperkenalkan
Latar belakang pembatasan setTimeout
Munculnya API timer lain
setImmediate: hanya didukung di IE dan Edge lama, praktis sudah usang
MessageChannel.postMessage: mengirim tugas ke event loop melalui kanal terpisah
window.postMessage: performanya bagus, tetapi berisiko bentrok dengan skrip lain
scheduler.postTask: didukung browser modern dan dinilai sebagai pilihan paling stabil
Hasil benchmark (MacBook Pro 2021, pengukuran 101 kali)
- Chrome 139:
setTimeout 4.2ms, scheduler.postTask 0ms
- Firefox 142:
setTimeout 4.72ms, scheduler.postTask 0.01ms
- Safari 18.4:
setTimeout 26.73ms, MessageChannel 0.52ms, window.postMessage 0.05ms
Kasus fake-indexeddb
- IndexedDB menginginkan auto-commit transaksi tepat setelah microtask pada event loop selesai
setImmediate di Node.js ideal untuk ini, tetapi di browser setTimeout tidak efisien
- Di Chrome, pekerjaan yang memakan 300ms di Node.js bisa membengkak menjadi 4.8 detik di browser
- Sebagai solusi,
scheduler.postTask digunakan sebagai default, dengan MessageChannel/window.postMessage sebagai fallback demi kompatibilitas
Perdebatan soal intervensi browser
- Satu pihak berpendapat timer harus dibatasi agar developer terlindungi dari kesalahannya sendiri
- Pihak lain berpendapat kebebasan harus dijamin agar developer bisa mengukur dan mengoptimalkan sendiri
- Pada akhirnya, dengan prinsip mengutamakan pengguna, browser melakukan intervensi untuk mencegah penyalahgunaan
- Scheduler API dirancang sebagai kompromi antara kedua posisi itu, memberi developer kendali tugas yang lebih rinci sambil tetap selaras dengan pipeline rendering browser
Prospek ke depan
postTask dan postMessage tampaknya akan tetap dipertahankan tanpa throttling untuk sementara waktu
- Namun, jika prioritas tinggi seperti
user-blocking disalahgunakan, intervensi bisa kembali terjadi
- Dalam jangka panjang, mungkin akan dibutuhkan API alternatif lain seperti
scheduler2
Belum ada komentar.