Layout sinkron paksa: membaca geometri setelah menulis ke DOM
Apa yang terjadi
Biasanya layout terjadi setelah JavaScript Anda selesai, sekali per frame. Tapi jika Anda mengubah DOM lalu segera membaca properti layout — offsetWidth, scrollHeight, getBoundingClientRect(), getComputedStyle() — browser harus berhenti dan menghitung layout di situ juga, secara sinkron, di dalam tugas Anda, karena jawabannya bergantung pada perubahan Anda yang belum diterapkan.
Satu layout paksa murah di halaman kecil. Di DOM besar, atau diulang dalam loop (yang menjadi layout thrashing), ia menambahkan ratusan milidetik ke handler.
Cara mengenali
- Processing time panjang dalam rincian INP, dengan blok Layout bersarang di dalam tugas skrip di DevTools Performance (peringatan “Forced reflow”).
- Long Animation Frames API melaporkan forcedStyleAndLayoutDuration besar untuk skrip Anda.
- Handler sekaligus mengubah DOM dan mengukur elemen.
Cara memperbaiki
- Baca semua geometri sebelum penulisan DOM pertama dalam tugas.
- Cache pengukuran yang tidak berubah (ukuran elemen, lebar kontainer) alih-alih membacanya ulang pada setiap event.
- Jika Anda harus mengukur setelah perubahan, tunda pembacaan ke requestAnimationFrame frame berikutnya, atau gunakan ResizeObserver / IntersectionObserver alih-alih menjajaki geometri.
Masalah
grid.style.width = next + "px" // write: layout is now dirty
const rect = cell.getBoundingClientRect() // read → forced synchronous layout
Perbaikan
const rect = cell.getBoundingClientRect() // read first, layout is clean
grid.style.width = next + "px" // write after; browser lays out
// once, before the next paint
Pindai situs Anda gratis →