Panduan penggunaan WebPageTest untuk mengidentifikasi dan memperbaiki masalah ketidakstabilan tata letak.
Dalam postingan sebelumnya, saya menulis tentang mengukur Pergeseran Tata Letak Kumulatif (CLS) di WebPageTest. CLS adalah gabungan dari semua pergeseran tata letak, jadi dalam postingan ini, saya pikir akan menarik untuk mempelajari lebih dalam dan memeriksa setiap pergeseran tata letak individual di halaman untuk mencoba memahami apa yang dapat menyebabkan ketidakstabilan dan benar-benar mencoba memperbaiki masalahnya.
Mengukur pergeseran tata letak
Dengan menggunakan Layout Instability API, kita bisa mendapatkan daftar semua peristiwa pergeseran tata letak di halaman:
new Promise(resolve => {
new PerformanceObserver(list => {
resolve(list.getEntries().filter(entry => !entry.hadRecentInput));
}).observe({type: "layout-shift", buffered: true});
}).then(console.log);
Hal ini menghasilkan array pergeseran tata letak yang tidak didahului oleh peristiwa input:
[
{
"name": "",
"entryType": "layout-shift",
"startTime": 210.78500000294298,
"duration": 0,
"value": 0.0001045969445437389,
"hadRecentInput": false,
"lastInputTime": 0
}
]
Dalam contoh ini, terjadi satu pergeseran yang sangat kecil sebesar 0,01% pada 210 md.
Mengetahui waktu dan tingkat keparahan perubahan ini berguna untuk membantu mempersempit penyebab perubahan tersebut. Mari kita kembali ke WebPageTest untuk lingkungan lab guna melakukan pengujian lebih lanjut.
Mengukur pergeseran tata letak di WebPageTest
Mirip dengan mengukur CLS di WebPageTest, mengukur pergeseran tata letak individual akan memerlukan metrik kustom. Untungnya, prosesnya kini lebih mudah karena Chrome 77 sudah stabil. Layout Instability API diaktifkan secara default, sehingga Anda dapat menjalankan cuplikan JS tersebut di situs mana pun dalam Chrome 77 dan langsung mendapatkan hasilnya. Di WebPageTest, Anda dapat menggunakan browser Chrome default dan tidak perlu khawatir tentang tanda command line atau menggunakan Canary.
Jadi, mari kita ubah skrip tersebut untuk menghasilkan metrik kustom untuk WebPageTest:
[LayoutShifts]
return new Promise(resolve => {
new PerformanceObserver(list => {
resolve(JSON.stringify(list.getEntries().filter(entry => !entry.hadRecentInput)));
}).observe({type: "layout-shift", buffered: true});
});
Promise dalam skrip ini di-resolve ke representasi JSON dari array, bukan array itu sendiri. Hal ini karena metrik kustom hanya dapat menghasilkan jenis data primitif seperti string atau angka.
Situs yang akan saya gunakan untuk pengujian adalah ismyhostfastyet.com, situs yang saya buat untuk membandingkan performa pemuatan host web di dunia nyata.
Mengidentifikasi penyebab ketidakstabilan tata letak
Dalam hasil, kita dapat melihat metrik kustom LayoutShifts memiliki nilai ini:
[
{
"name": "",
"entryType": "layout-shift",
"startTime": 3087.2349999990547,
"duration": 0,
"value": 0.3422101449275362,
"hadRecentInput": false,
"lastInputTime": 0
}
]
Singkatnya, ada satu pergeseran tata letak sebesar 34,2% yang terjadi pada 3087 md. Untuk membantu mengidentifikasi penyebabnya, mari kita gunakan tampilan setrip film WebPageTest.

Men-scroll ke tanda ~3 detik di filmstrip menunjukkan dengan tepat penyebab pergeseran tata letak 34%: tabel berwarna. Situs mengambil file JSON secara asinkron, lalu merendernya ke tabel. Awalnya tabel kosong, jadi menunggu untuk mengisinya saat hasil dimuat menyebabkan pergeseran.

Namun, bukan itu saja. Saat halaman selesai secara visual pada ~4,3 detik, kita dapat melihat bahwa <h1>
halaman "Is my host fast yet?" muncul entah dari mana. Hal ini terjadi karena situs menggunakan font web dan belum melakukan langkah-langkah untuk mengoptimalkan rendering. Tata letak sebenarnya tidak tampak bergeser saat hal ini terjadi, tetapi pengguna tetap akan merasa tidak nyaman karena harus menunggu begitu lama untuk membaca judul.
Memperbaiki ketidakstabilan tata letak
Setelah mengetahui bahwa tabel yang dibuat secara asinkron menyebabkan sepertiga area tampilan bergeser, saatnya memperbaikinya. Kita tidak mengetahui isi tabel hingga hasil JSON benar-benar dimuat, tetapi kita masih dapat mengisi tabel dengan data pengganti sehingga tata letaknya sendiri relatif stabil saat DOM dirender.
Berikut kode untuk membuat data pengganti:
function getRandomFiller(maxLength) {
var filler = '█';
var len = Math.ceil(Math.random() * maxLength);
return new Array(len).fill(filler).join('');
}
function getRandomDistribution() {
var fast = Math.random();
var avg = (1 - fast) * Math.random();
var slow = 1 - (fast + avg);
return [fast, avg, slow];
}
// Temporary placeholder data.
window.data = [];
for (var i = 0; i < 36; i++) {
var [fast, avg, slow] = getRandomDistribution();
window.data.push({
platform: getRandomFiller(10),
client: getRandomFiller(5),
n: getRandomFiller(1),
fast,
avg,
slow
});
}
updateResultsTable(sortResults(window.data, 'fast'));
Data placeholder dibuat secara acak sebelum diurutkan. Ini mencakup karakter "█" yang diulang beberapa kali secara acak untuk membuat placeholder visual untuk teks dan distribusi tiga nilai utama yang dibuat secara acak. Saya juga menambahkan beberapa gaya untuk mengurangi saturasi semua warna dari tabel agar jelas bahwa data belum dimuat sepenuhnya.
Tampilan placeholder yang Anda gunakan tidak memengaruhi stabilitas tata letak. Tujuan placeholder adalah untuk meyakinkan pengguna bahwa konten akan muncul dan halaman tidak rusak.
Berikut tampilan placeholder saat data JSON dimuat:

Mengatasi masalah font web jauh lebih sederhana. Karena situs menggunakan Google Fonts, kita hanya perlu meneruskan properti display=swap
dalam permintaan CSS. Itu saja. Fonts API akan menambahkan gaya font-display: swap
dalam deklarasi font, sehingga browser dapat merender teks dalam font pengganti dengan segera. Berikut adalah markup yang sesuai dengan perbaikan yang disertakan:
<link href="https://fonts.googleapis.com/css?family=Chivo:900&display=swap" rel="stylesheet">
Memverifikasi pengoptimalan
Setelah menjalankan ulang halaman melalui WebPageTest, kita dapat membuat perbandingan sebelum dan sesudah untuk memvisualisasikan perbedaan dan mengukur tingkat ketidakstabilan tata letak yang baru:

[
{
"name": "",
"entryType": "layout-shift",
"startTime": 3070.9349999997357,
"duration": 0,
"value": 0.000050272187989256116,
"hadRecentInput": false,
"lastInputTime": 0
}
]
Menurut metrik kustom, masih ada pergeseran tata letak yang terjadi pada 3071 md (sekitar waktu yang sama seperti sebelumnya), tetapi tingkat keparahan pergeseran jauh lebih kecil: 0,005%. Saya bisa menerima ini.
Dari filmstrip juga terlihat jelas bahwa font <h1>
langsung beralih ke font sistem, sehingga pengguna dapat membacanya lebih cepat.
Kesimpulan
Situs yang kompleks mungkin mengalami lebih banyak pergeseran tata letak daripada dalam contoh ini, tetapi proses perbaikannya tetap sama: tambahkan metrik ketidakstabilan tata letak ke WebPageTest, silangkan hasilnya dengan filmstrip pemuatan visual untuk mengidentifikasi penyebabnya, dan terapkan perbaikan menggunakan placeholder untuk mencadangkan ruang layar.
(Satu hal lagi) Mengukur ketidakstabilan tata letak yang dialami oleh pengguna sungguhan
Anda dapat menjalankan WebPageTest di halaman sebelum dan sesudah pengoptimalan serta melihat peningkatan pada metrik, tetapi yang benar-benar penting adalah pengalaman pengguna yang semakin baik. Bukankah itu alasan kami mencoba membuat situs menjadi lebih baik?
Jadi, akan lebih baik jika kita mulai mengukur pengalaman ketidakstabilan tata letak pengguna sungguhan bersama dengan metrik performa web tradisional kita. Hal ini merupakan bagian penting dari loop masukan pengoptimalan karena data dari lapangan memberi tahu kita di mana masalahnya dan apakah perbaikan yang kita lakukan memberikan dampak positif.
Selain mengumpulkan data ketidakstabilan tata letak Anda sendiri, lihat Chrome UX Report, yang mencakup data Cumulative Layout Shift dari pengalaman pengguna sebenarnya di jutaan situs. Anda dapat mengetahui performa Anda (atau pesaing), atau Anda dapat menggunakannya untuk mempelajari status ketidakstabilan tata letak di seluruh web.