Dipublikasikan: 20 Maret 2015, Terakhir diperbarui: 07 Mei 2025
Tata letak adalah tempat browser mencari tahu informasi geometris untuk elemen: ukuran dan lokasinya di halaman. Setiap elemen akan memiliki informasi ukuran eksplisit atau implisit berdasarkan CSS yang digunakan, konten elemen, atau elemen induk. Proses ini disebut Tata Letak di Chrome (dan browser turunan seperti Edge), dan Safari. Di Firefox, proses ini disebut Reflow, tetapi prosesnya sama.
Serupa dengan penghitungan gaya, masalah langsung untuk biaya tata letak adalah:
- Jumlah elemen yang memerlukan tata letak, yang merupakan produk sampingan dari ukuran DOM halaman.
- Kompleksitas tata letak tersebut.
Ringkasan
- Tata letak memiliki dampak langsung pada latensi interaksi
- Tata letak biasanya dicakup untuk seluruh dokumen.
- Jumlah elemen DOM akan memengaruhi performa; sebaiknya hindari memicu tata letak jika memungkinkan.
- Hindari tata letak sinkron paksa dan thrashing tata letak; baca nilai gaya, lalu buat perubahan gaya.
Pengaruh tata letak terhadap latensi interaksi
Saat pengguna berinteraksi dengan halaman, interaksi tersebut harus dilakukan secepat mungkin. Jumlah waktu yang diperlukan untuk menyelesaikan interaksi—berakhir saat browser menampilkan frame berikutnya untuk menampilkan hasil interaksi—dikenal sebagai latensi interaksi. Ini adalah aspek performa halaman yang diukur oleh metrik Interaction to Next Paint.
Jumlah waktu yang diperlukan browser untuk menampilkan frame berikutnya sebagai respons terhadap interaksi pengguna dikenal sebagai penundaan presentasi interaksi. Tujuan interaksi adalah memberikan masukan visual untuk memberi tahu pengguna bahwa sesuatu telah terjadi, dan pembaruan visual dapat melibatkan sejumlah pekerjaan tata letak untuk mencapai tujuan tersebut.
Agar INP situs Anda tetap serendah mungkin, sebaiknya hindari tata letak jika memungkinkan. Jika tidak dapat menghindari tata letak sepenuhnya, Anda harus membatasi pekerjaan tata letak tersebut agar browser dapat menampilkan frame berikutnya dengan cepat.
Hindari tata letak jika memungkinkan
Saat Anda mengubah gaya, browser akan memeriksa apakah ada perubahan yang memerlukan penghitungan tata letak, dan apakah hierarki render tersebut perlu diperbarui. Perubahan pada "properti geometris", seperti width
, height
, left
, atau top
semuanya memerlukan tata letak.
.box {
width: 20px;
height: 20px;
}
/**
* Changing width and height
* triggers layout.
*/
.box--expanded {
width: 200px;
height: 350px;
}
Tata letak hampir selalu dicakup untuk seluruh dokumen. Jika Anda memiliki banyak elemen, akan diperlukan waktu lama untuk mengetahui lokasi dan dimensi semuanya.
Jika tidak dapat menghindari tata letak, kuncinya adalah menggunakan Chrome DevTools lagi untuk melihat berapa lama waktu yang diperlukan, dan menentukan apakah tata letak adalah penyebab bottleneck. Pertama, buka DevTools, buka tab Linimasa, tekan rekam, lalu berinteraksi dengan situs Anda. Saat berhenti merekam, Anda akan melihat perincian performa situs:

Saat mempelajari rekaman aktivitas dalam contoh sebelumnya, kita melihat bahwa lebih dari 28 milidetik dihabiskan di dalam tata letak untuk setiap frame, yang, jika kita memiliki 16 milidetik untuk mendapatkan frame di layar dalam animasi, terlalu tinggi. Anda juga dapat melihat bahwa DevTools akan memberi tahu Anda ukuran hierarki (1.618 elemen dalam hal ini), dan jumlah node yang memerlukan tata letak (5 dalam hal ini).
Perlu diingat bahwa saran umum di sini adalah menghindari tata letak jika memungkinkan—tetapi tidak selalu memungkinkan untuk menghindari tata letak. Jika Anda tidak dapat menghindari tata letak, ketahui bahwa biaya tata letak memiliki hubungan dengan ukuran DOM. Meskipun hubungan antara keduanya tidak terikat erat, DOM yang lebih besar umumnya akan menimbulkan biaya tata letak yang lebih tinggi.
Menghindari tata letak sinkron paksa
Pengiriman frame ke layar memiliki urutan ini:

Pertama, JavaScript berjalan, lalu penghitungan gaya, lalu tata letak. Namun, Anda dapat memaksa browser untuk melakukan tata letak lebih awal dengan JavaScript. Hal ini disebut tata letak sinkron paksa (atau terkadang pembentukan ulang paksa).
Hal pertama yang perlu diingat adalah saat JavaScript berjalan, semua nilai tata letak lama dari frame sebelumnya diketahui dan tersedia untuk Anda buat kueri. Jadi, jika misalnya Anda ingin menulis tinggi elemen (sebut saja "kotak") di awal frame, Anda dapat menulis beberapa kode seperti ini:
// Schedule our function to run at the start of the frame:
requestAnimationFrame(logBoxHeight);
function logBoxHeight () {
// Gets the height of the box in pixels and logs it out:
console.log(box.offsetHeight);
}
Masalah akan muncul jika Anda telah mengubah gaya kotak sebelum meminta tingginya:
function logBoxHeight () {
box.classList.add('super-big');
// Gets the height of the box in pixels and logs it out:
console.log(box.offsetHeight);
}
Sekarang, untuk menjawab pertanyaan tinggi, browser harus terlebih dahulu menerapkan perubahan gaya (karena menambahkan class super-big
), lalu kemudian menjalankan tata letak. Hanya dengan begitu, kode ini dapat menampilkan tinggi yang benar. Hal ini tidak perlu dan berpotensi mahal.
Oleh karena itu, Anda harus selalu mengelompokkan pembacaan gaya dan melakukannya terlebih dahulu (saat browser dapat menggunakan nilai tata letak frame sebelumnya), lalu melakukan penulisan:
Versi yang lebih efisien dari fungsi sebelumnya adalah:
function logBoxHeight () {
// Gets the height of the box in pixels and logs it out:
console.log(box.offsetHeight);
box.classList.add('super-big');
}
Pada umumnya, Anda tidak perlu menerapkan gaya, lalu membuat kueri nilai; menggunakan nilai frame terakhir sudah cukup. Menjalankan penghitungan gaya dan tata letak secara sinkron dan lebih awal dari yang diinginkan browser adalah potensi bottleneck, dan bukan sesuatu yang biasanya ingin Anda lakukan.
Menghindari thrashing tata letak
Ada cara untuk membuat tata letak sinkron paksa menjadi lebih buruk: lakukan banyak tata letak sinkron secara berurutan. Lihat kode ini:
function resizeAllParagraphsToMatchBlockWidth () {
// Puts the browser into a read-write-read-write cycle.
for (let i = 0; i < paragraphs.length; i++) {
paragraphs[i].style.width = `${box.offsetWidth}px`;
}
}
Kode ini melakukan loop pada sekelompok paragraf dan menetapkan lebar setiap paragraf agar cocok dengan lebar elemen yang disebut "kotak". Tampaknya cukup tidak berbahaya, tetapi masalahnya adalah setiap iterasi loop membaca nilai gaya (box.offsetWidth
), lalu segera menggunakannya untuk memperbarui lebar paragraf (paragraphs[i].style.width
). Pada iterasi loop berikutnya, browser harus memperhitungkan fakta bahwa gaya telah berubah sejak offsetWidth
terakhir diminta (dalam iterasi sebelumnya), sehingga browser harus menerapkan perubahan gaya, dan menjalankan tata letak. Hal ini akan terjadi pada setiap iterasi.
Perbaikan untuk contoh ini adalah dengan sekali lagi membaca, lalu menulis nilai:
// Read.
const width = box.offsetWidth;
function resizeAllParagraphsToMatchBlockWidth () {
for (let i = 0; i < paragraphs.length; i++) {
// Now write.
paragraphs[i].style.width = `${width}px`;
}
}
Mengidentifikasi tata letak sinkron paksa dan thrashing
DevTools memiliki insight Forced Reflow, untuk membantu Anda mengidentifikasi kasus tata letak sinkron paksa dengan cepat (juga dikenal sebagai "forced reflow"):

Tata letak sinkron paksa juga dapat diidentifikasi di kolom menggunakan atribusi skrip Long Animation Frame API menggunakan properti forcedStyleAndLayoutDuration
.