Düzen kararsızlığını düzeltme

Düzen kararsızlığı sorunlarını belirleyip düzeltmek için WebPageTest'i kullanma kılavuzu.

WebPageTest'te kümülatif düzen değişikliğini (CLS) ölçme hakkında daha önce yazmıştım. CLS, tüm düzen değişikliklerinin bir toplamıdır. Bu nedenle bu yayında, kararsızlığa neyin neden olabileceğini anlamak ve sorunları gerçekten düzeltmeye çalışmak için daha ayrıntılı bir inceleme yapıp sayfadaki her düzen değişikliğini tek tek incelemenin ilginç olacağını düşündüm.

Düzen kaymalarını ölçme

Layout Instability API'yi kullanarak bir sayfadaki tüm düzen kayması etkinliklerinin listesini alabiliriz:

new Promise(resolve => {
  new PerformanceObserver(list => {
    resolve(list.getEntries().filter(entry => !entry.hadRecentInput));
  }).observe({type: "layout-shift", buffered: true});
}).then(console.log);

Bu işlem, giriş etkinliklerinden önce gelmeyen bir düzen kayması dizisi oluşturur:

[
  {
    "name": "",
    "entryType": "layout-shift",
    "startTime": 210.78500000294298,
    "duration": 0,
    "value": 0.0001045969445437389,
    "hadRecentInput": false,
    "lastInputTime": 0
  }
]

Bu örnekte, 210 ms'de %0,01'lik tek bir çok küçük kayma olmuştur.

Değişikliğin zamanını ve önemini bilmek, değişime neyin neden olmuş olabileceğini belirlemenize yardımcı olur. Daha fazla test yapmak amacıyla laboratuvar ortamı için WebPageTest'e dönelim.

WebPageTest'te düzen kaymalarını ölçme

WebPageTest'te CLS'nin ölçümüne benzer şekilde, düzen kaymalarını ayrı ayrı ölçmek için özel bir metrik gerekir. Neyse ki Chrome 77 kararlı olduğu için bu işlem artık daha kolay. Layout Instability API varsayılan olarak etkindir. Bu nedenle, bu JS snippet'ini Chrome 77'deki herhangi bir web sitesinde çalıştırabilir ve hemen sonuç alabilirsiniz. WebPageTest'te, varsayılan Chrome tarayıcıyı kullanabilirsiniz ve komut satırı işaretleri veya Canary kullanma konusunda endişelenmeniz gerekmez.

Bu nedenle, WebPageTest için özel bir metrik oluşturacak şekilde bu komut dosyasını değiştirelim:

[LayoutShifts]
return new Promise(resolve => {
  new PerformanceObserver(list => {
    resolve(JSON.stringify(list.getEntries().filter(entry => !entry.hadRecentInput)));
  }).observe({type: "layout-shift", buffered: true});
});

Bu komut dosyasındaki promise, dizinin kendisi yerine dizinin JSON temsiline çözümlenir. Bunun nedeni, özel metriklerin yalnızca dize veya sayı gibi ilkel veri türleri üretebilmesidir.

Test için kullanacağım web sitesi, web barındırma sağlayıcılarının gerçek yükleme performansını karşılaştırmak için oluşturduğum ismyhostfastyet.com sitesidir.

Düzen kararsızlığının nedenlerini belirleme

Sonuçlar bölümünde, LayoutShifts özel metriğinin şu değeri olduğunu görebiliriz:

[
  {
    "name": "",
    "entryType": "layout-shift",
    "startTime": 3087.2349999990547,
    "duration": 0,
    "value": 0.3422101449275362,
    "hadRecentInput": false,
    "lastInputTime": 0
  }
]

Özetlemek gerekirse, 3087 ms'de %34,2 oranında tek bir düzen kayması gerçekleşiyor. Sorunu tespit etmek için WebPageTest'in film şeridi görünümünü kullanalım.

Düzen kaymasından önceki ve sonraki ekran görüntülerini gösteren film şeridindeki iki hücre.
Film şeridinde, düzen değişikliğinden önceki ve sonraki ekran görüntülerini gösteren iki hücre.

Film şeridindeki yaklaşık 3 saniyelik işarete gelindiğinde, %34'lük düzen kaymasının tam olarak nedeni gösterilmektedir: renkli tablo. Web sitesi, JSON dosyasını asynkron olarak getirir ve ardından bir tabloda oluşturur. Tablo başlangıçta boş olduğundan, sonuçlar yüklendiğinde tablonun doldurulmasını beklemek kaymaya neden oluyor.

Bir anda görünen web yazı tipi başlığı.
Yerli olmayan bir web yazı tipi başlığı göründü.

Ancak avantajlar bunlarla sınırlı değil. Sayfa yaklaşık 4,3 saniyede görsel olarak tamamlandığında, "Barındırıcım henüz hızlı mı?" sayfasının <h1>'sinin aniden göründüğünü görebiliriz. Bunun nedeni, sitenin bir web yazı tipi kullanması ve oluşturmayı optimize etmek için herhangi bir adım atmamasıdır. Bu durumda düzen aslında değişmiyor ancak başlığı okumak için uzun süre beklemek zorunda kalmak kullanıcı deneyimini olumsuz etkiler.

Düzen kararsızlığını düzeltme

Asenkron olarak oluşturulan tablonun, görüntü alanının üçte birinin kaymasına neden olduğunu bildiğimize göre bu sorunu düzeltme zamanı geldi. JSON sonuçları gerçekten yüklenene kadar tablonun içeriğini bilmiyoruz ancak DOM oluşturulduğunda düzenin nispeten kararlı olması için tabloyu bir tür yer tutucu veri ile doldurabiliriz.

Yer tutucu verileri oluşturmak için gereken kodu aşağıda görebilirsiniz:

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'));

Yer tutucu veriler, sıralanmadan önce rastgele oluşturulur. Metin için görsel yer tutucular oluşturmak amacıyla rastgele sayıda tekrarlanan "█" karakteri ve üç ana değerin rastgele oluşturulmuş bir dağılımını içerir. Ayrıca, verilerin henüz tam olarak yüklenmediğini açıkça belirtmek için tablodaki tüm renklerin doygunluğunu azaltan bazı stiller de ekledim.

Kullandığınız yer tutucuların görünümü, düzenin kararlılığı açısından önemli değildir. Yer tutucuların amacı, kullanıcılara içeriğin geleceği ve sayfanın bozuk olmadığı konusunda güvence vermektir.

JSON verileri yüklenirken yer tutucular aşağıdaki gibi görünür:

Veri tablosu, yer tutucu verileriyle oluşturulur.
Veri tablosu, yer tutucu verileriyle oluşturulur.

Web yazı tipi sorununu gidermek çok daha kolaydır. Sitede Google yazı tipleri kullanıldığı için CSS isteğine display=swap mülkünü göndermemiz yeterlidir. Hepsi bu kadar. Fonts API, yazı tipi beyanında font-display: swap stilini ekler. Bu sayede tarayıcı, metni hemen yedek yazı tipinde oluşturabilir. Çözümün dahil edildiği ilgili işaretleme aşağıda verilmiştir:

<link href="https://fonts.googleapis.com/css?family=Chivo:900&display=swap" rel="stylesheet">

Optimizasyonları doğrulama

Sayfayı WebPageTest üzerinden yeniden çalıştırdıktan sonra, farkı görselleştirmek ve yeni düzen kararsızlığı derecesini ölçmek için bir önceki ve sonraki karşılaştırma oluşturabiliriz:

Her iki sitenin düzen optimizasyonları olmadan yan yana yüklendiğini gösteren WebPageTest film şeridi.
Sayfa düzeni optimizasyonları uygulanmış ve uygulanmamış halleriyle her iki sitenin de yan yana yüklenmesini gösteren WebPageTest film şeridi.
[
  {
    "name": "",
    "entryType": "layout-shift",
    "startTime": 3070.9349999997357,
    "duration": 0,
    "value": 0.000050272187989256116,
    "hadRecentInput": false,
    "lastInputTime": 0
  }
]

Özel metriğe göre, 3071 ms'de (yaklaşık olarak öncekiyle aynı zaman) hâlâ bir sayfa düzeni kayması meydana geliyor ancak kaymanın önemi çok daha düşük: %0,005. Bu duruma katlanabilirim.

Film şeridinde, <h1> yazı tipinin hemen bir sistem yazı tipine geçtiği ve kullanıcıların metni daha hızlı okuyabildiği de açıkça görülüyor.

Sonuç

Karmaşık web sitelerinde bu örnektekinden çok daha fazla düzen değişikliği yaşanabilir ancak düzeltme süreci aynıdır: WebPageTest'e düzen kararsızlığı metrikleri ekleyin, suçluları belirlemek için sonuçları görsel yükleme film şeridiyle çapraz referans yaparak karşılaştırın ve ekran alanını ayırmak için yer tutucular kullanarak bir düzeltme uygulayın.

(Bir şey daha) Gerçek kullanıcıların yaşadığı düzen kararsızlığını ölçme

WebPageTest'i bir optimizasyon öncesinde ve sonrasında bir sayfada çalıştırabilmek ve bir metrikte iyileşme görebilmek güzel, ancak asıl önemli olan kullanıcı deneyiminin aslında daha iyi hale gelmesidir. Siteyi daha iyi hale getirmeye çalışmamızın nedeni de bu değil mi?

Bu nedenle, geleneksel web performansı metriklerimizle birlikte gerçek kullanıcıların düzen kararsızlığı deneyimlerini de ölçmeye başlamamız çok faydalı olacaktır. Sahadan gelen veriler, sorunların nerede olduğunu ve çözümlerimizin olumlu bir fark yaratıp yaratmadığını bize bildirdiğinden bu, optimizasyon geri bildirim döngüsünün önemli bir parçasıdır.

Kendi düzen kararsızlığı verilerinizi toplamanın yanı sıra, milyonlarca web sitesindeki gerçek kullanıcı deneyimlerinden elde edilen kümülatif düzen kayması verilerini içeren Chrome Kullanıcı Deneyimi Raporu'na göz atın. Bu rapor, sizin (veya rakiplerinizin) nasıl performans gösterdiğini öğrenmenize olanak tanır. Ayrıca, web'deki düzen kararsızlığının durumunu keşfetmek için de kullanabilirsiniz.