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 agregasi dari semua pergeseran tata letak, jadi dalam postingan ini, saya pikir akan menarik untuk mempelajari lebih lanjut dan memeriksa setiap pergeseran tata letak di halaman untuk mencoba memahami apa yang dapat menyebabkan ketidakstabilan dan benar-benar mencoba memperbaiki masalah tersebut.
Mengukur perubahan 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);
Tindakan 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, ada satu pergeseran sangat kecil sebesar 0,01% pada 210 md.
Mengetahui waktu dan tingkat keparahan pergeseran berguna untuk membantu mempersempit hal yang dapat menyebabkan pergeseran. Mari kita kembali ke WebPageTest untuk lingkungan lab guna melakukan pengujian lebih lanjut.
Mengukur pergeseran tata letak di WebPageTest
Serupa dengan mengukur CLS di WebPageTest, mengukur setiap pergeseran tata letak 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 dengan flag 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 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
Di 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 3.087 md. Untuk membantu mengidentifikasi penyebabnya, mari kita gunakan tampilan filmstrip WebPageTest.
Men-scroll ke tanda ~3 detik di filmstrip menunjukkan dengan tepat penyebab pergeseran tata letak 34%: tabel berwarna-warni. Situs mengambil file JSON secara asinkron, lalu merendernya ke tabel. Tabel awalnya kosong, sehingga menunggu untuk mengisinya saat hasil dimuat akan menyebabkan pergeseran.
Namun, bukan itu saja. Saat halaman selesai secara visual dalam waktu ~4,3 detik, kita dapat melihat bahwa <h1>
halaman "Apakah host saya sudah cepat?" muncul entah dari mana. Hal ini terjadi karena situs menggunakan font web dan belum melakukan langkah apa pun untuk mengoptimalkan rendering. Tata letak sebenarnya tidak tampak bergeser saat hal ini terjadi, tetapi pengalaman pengguna tetap buruk karena harus menunggu begitu lama untuk membaca judul.
Memperbaiki ketidakstabilan tata letak
Setelah mengetahui bahwa tabel yang dibuat secara asinkron menyebabkan sepertiga area pandang bergeser, sekarang saatnya memperbaikinya. Kita tidak mengetahui konten tabel hingga hasil JSON benar-benar dimuat, tetapi kita masih dapat mengisi tabel dengan semacam data placeholder sehingga tata letak itu sendiri relatif stabil saat DOM dirender.
Berikut adalah kode untuk membuat data placeholder:
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 dihasilkan secara acak. Saya juga menambahkan beberapa gaya untuk mendesaturasi semua warna dari tabel agar jelas bahwa data belum dimuat sepenuhnya.
Tampilan placeholder yang Anda gunakan tidak berpengaruh pada stabilitas tata letak. Tujuan placeholder adalah untuk meyakinkan pengguna bahwa konten akan segera hadir dan halaman tidak rusak.
Berikut adalah 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 langsung merender teks dalam font penggantian. 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 menerimanya.
Dari filmstrip juga terlihat jelas bahwa font <h1>
langsung kembali ke font sistem, sehingga pengguna dapat membacanya lebih cepat.
Kesimpulan
Situs yang kompleks mungkin akan mengalami lebih banyak pergeseran tata letak daripada dalam contoh ini, tetapi proses perbaikannya tetap sama: tambahkan metrik ketidakstabilan tata letak ke WebPageTest, lakukan referensi silang pada hasil 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 sebenarnya
Sangatlah baik jika Anda dapat menjalankan WebPageTest di halaman sebelum dan sesudah pengoptimalan dan melihat peningkatan pada metrik, tetapi yang benar-benar penting adalah pengalaman pengguna benar-benar menjadi lebih baik. Bukankah itulah alasan kita mencoba membuat situs menjadi lebih baik?
Jadi, sebaiknya kita mulai mengukur pengalaman ketidakstabilan tata letak pengguna sungguhan bersama dengan metrik performa web tradisional. Ini adalah bagian penting dari loop masukan pengoptimalan karena memiliki data dari lapangan akan memberi tahu kita letak masalah dan apakah perbaikan yang kita lakukan memberikan dampak positif.
Selain mengumpulkan data ketidakstabilan tata letak Anda sendiri, lihat Laporan UX Chrome, yang menyertakan data Cumulative Layout Shift dari pengalaman pengguna yang sebenarnya di jutaan situs. Dengan alat ini, Anda dapat mengetahui performa Anda (atau pesaing Anda), atau Anda dapat menggunakannya untuk mempelajari status ketidakstabilan tata letak di seluruh web.