Gezinme zamanlaması ve kaynak zamanlaması ile sahada yükleme performansını değerlendirme

Alan yükleme performansını değerlendirmek için Navigation ve Resource Timing API'lerini kullanmanın temel bilgilerini öğrenin.

Yayınlanma tarihi: 8 Ekim 2021

Yükleme performansını değerlendirmek için bir tarayıcının geliştirici araçlarındaki (veya Chrome'daki Lighthouse) ağ panelinde bağlantı sınırlaması kullandıysanız bu araçların performans ayarlama için ne kadar kullanışlı olduğunu bilirsiniz. Tutarlı ve sabit bir temel bağlantı hızıyla performans optimizasyonlarının etkisini hızlıca ölçebilirsiniz. Tek sorun, bunun sentetik test olmasıdır. Bu test, alan verileri değil, laboratuvar verileri üretir.

Sentetik testler doğası gereği kötü değildir ancak web sitenizin gerçek kullanıcılar için ne kadar hızlı yüklendiğini göstermez. Bu işlem için alan verileri gerekir. Bu verileri Gezinme Zamanlama ve Kaynak Zamanlama API'lerinden toplayabilirsiniz.

Alan yükleme performansını değerlendirmenize yardımcı olacak API'ler

Navigation Timing ve Resource Timing, iki farklı şeyi ölçen ve önemli ölçüde çakışan iki benzer API'dir:

  • Navigation Timing, HTML dokümanlarına yönelik isteklerin (yani gezinme istekleri) hızını ölçer.
  • Kaynak Zamanlaması, CSS, JavaScript, resimler ve diğer kaynak türleri gibi dokümana bağlı kaynaklar için yapılan isteklerin hızını ölçer.

Bu API'ler, verilerini performans girişi arabelleğinde kullanıma sunar. Bu arabelleğe JavaScript ile tarayıcıdan erişilebilir. Performans arabelleğine sorgu göndermenin birden fazla yolu vardır ancak yaygın bir yöntem performance.getEntriesByType kullanmaktır:

// Get Navigation Timing entries:
performance.getEntriesByType('navigation');

// Get Resource Timing entries:
performance.getEntriesByType('resource');

performance.getEntriesByType, performans girişi arabelleğinden almak istediğiniz girişlerin türünü açıklayan bir dizeyi kabul eder. 'navigation' ve 'resource', sırasıyla Navigation Timing ve Resource Timing API'lerinin zamanlamalarını alır.

Bu API'lerin sağladığı bilgi miktarı çok fazla olabilir ancak bu API'ler, kullanıcılar web sitenizi ziyaret ederken bu süreleri toplayabileceğiniz için yükleme performansını sahada ölçmenizi sağlayan anahtarınızdır.

Ağ isteğinin yaşam döngüsü ve zamanlamaları

Gezinme ve kaynak zamanlamalarını toplama ve analiz etme, bir ağ isteğinin geçici ömrünü sonradan yeniden inşa etme açısından arkeolojiye benzer. Bazen kavramları görselleştirmek işe yarar. Ağ istekleri söz konusu olduğunda ise tarayıcınızın geliştirici araçları yardımcı olabilir.

Chrome'un Geliştirici Araçları'nda gösterilen ağ zamanlamaları. Gösterilen süreler, istek kuyruğa alma, bağlantı görüşmesi, isteğin kendisi ve yanıt için renk kodlu çubuklar şeklindedir.
Chrome Geliştirici Araçları'nın ağ panelinde bir ağ isteğinin görselleştirilmesi

Bir ağ isteğinin yaşam döngüsünde DNS araması, bağlantı oluşturma, TLS anlaşması ve diğer gecikme kaynakları gibi farklı aşamalar vardır. Bu süreler DOMHighResTimestamp olarak gösterilir. Tarayıcınıza bağlı olarak, zamanlamaların ayrıntı düzeyi mikrosaniyeye kadar düşebilir veya milisaniyeye yuvarlanabilir. Bu aşamaları ve bunların gezinme zamanlaması ve kaynak zamanlaması ile ilişkisini ayrıntılı olarak incelemeniz gerekir.

DNS araması

Bir kullanıcı bir URL'ye gittiğinde, alan adını IP adresine çevirmek için Alan Adı Sistemi (DNS) sorgulanır. Bu işlem önemli ölçüde zaman alabilir. Hatta bu süreyi sahada ölçmek isteyebilirsiniz. Navigation Timing ve Resource Timing, DNS ile ilgili iki zamanlamayı gösterir:

  • domainLookupStart, DNS aramasının başladığı zamandır.
  • domainLookupEnd, DNS aramasının sona erdiği zamandır.

Toplam DNS arama süresini hesaplamak için başlangıç metriğini bitiş metriğinden çıkarabilirsiniz:

// Measuring DNS lookup time
const [pageNav] = performance.getEntriesByType('navigation');
const totalLookupTime = pageNav.domainLookupEnd - pageNav.domainLookupStart;

Bağlantı görüşmesi

Yükleme performansına katkıda bulunan bir diğer faktör de bağlantı görüşmesidir. Bu, bir web sunucusuna bağlanırken oluşan gecikmedir. HTTPS kullanılıyorsa bu işleme TLS iletişimi süresi de dahil edilir. Bağlantı aşaması üç zamanlamadan oluşur:

  • connectStart, tarayıcının bir web sunucusuyla bağlantı açmaya başladığı zamandır.
  • secureConnectionStart, istemci TLS görüşmesine başladığında işaretlenir.
  • connectEnd, web sunucusuyla bağlantının kurulduğu zamandır.

Toplam bağlantı süresini ölçmek, toplam DNS arama süresini ölçmeye benzer: Başlangıç zamanlamasını bitiş zamanlamasından çıkarırsınız. Ancak, HTTPS kullanılmıyorsa veya bağlantı kalıcıysa 0 olabilecek ek bir secureConnectionStart özelliği vardır. TLS anlaşma süresini ölçmek istiyorsanız şunları göz önünde bulundurmanız gerekir:

// Quantifying total connection time
const [pageNav] = performance.getEntriesByType('navigation');
const connectionTime = pageNav.connectEnd - pageNav.connectStart;
let tlsTime = 0; // <-- Assume 0 to start with

// Was there TLS negotiation?
if (pageNav.secureConnectionStart > 0) {
  // Awesome! Calculate it!
  tlsTime = pageNav.connectEnd - pageNav.secureConnectionStart;
}

DNS araması ve bağlantı görüşmesi sona erdiğinde, dokümanların ve bağımlı kaynaklarının getirilmesiyle ilgili zamanlamalar devreye girer.

İstekler ve yanıtlar

Yükleme performansı iki tür faktörden etkilenir:

  • Harici faktörler: Gecikme ve bant genişliği gibi unsurlardır. Bir barındırma şirketi ve muhtemelen bir CDN seçmenin ötesinde, kullanıcılar web'e her yerden erişebildiğinden (çoğunlukla) kontrolümüz dışındadırlar.
  • Doğal faktörler: Bunlar, sunucu ve istemci tarafı mimarileri, kaynak boyutu ve bu öğeler için optimizasyon yapma becerimiz gibi kontrolümüz dahilinde olan şeylerdir.

Her iki faktör türü de yükleme performansını etkiler. Bu faktörlerle ilgili zamanlamalar, kaynakların ne kadar sürede indirileceğini gösterdiğinden hayati önem taşır. Hem gezinme zamanlaması hem de kaynak zamanlaması, yükleme performansını aşağıdaki metriklerle açıklar:

  • fetchStart, tarayıcının bir kaynağı (Kaynak Zamanlaması) veya gezinme isteği için bir dokümanı (Gezinme Zamanlaması) getirmeye başladığı zamanı işaretler. Bu, gerçek istekten önce gelir ve tarayıcının önbellekleri (ör. HTTP ve Cache örnekleri) kontrol ettiği noktadır.
  • workerStart, bir isteğin hizmet çalışanın fetch etkinlik işleyicisi içinde işlenmeye başladığı zamanı işaretler. Bu, geçerli sayfayı kontrol eden bir hizmet çalışanı olmadığında 0 olur.
  • requestStart, tarayıcının isteği gönderdiği zamandır.
  • responseStart, yanıtın ilk baytının geldiği zamandır.
  • responseEnd, yanıtın son baytının geldiği zamandır.

Bu zamanlamalar, yükleme performansının birden fazla yönünü (ör. bir hizmet çalışanındaki önbellek arama ve indirme süresi) ölçmenize olanak tanır:

// Cache seek plus response time of the current document
const [pageNav] = performance.getEntriesByType('navigation');
const fetchTime = pageNav.responseEnd - pageNav.fetchStart;

// Service worker time plus response time
let workerTime = 0;

if (pageNav.workerStart > 0) {
  workerTime = pageNav.responseEnd - pageNav.workerStart;
}

İstek ve yanıt gecikmesinin diğer yönlerini de ölçebilirsiniz:

const [pageNav] = performance.getEntriesByType('navigation');

// Request time only (excluding redirects, DNS, and connection/TLS time)
const requestTime = pageNav.responseStart - pageNav.requestStart;

// Response time only (download)
const responseTime = pageNav.responseEnd - pageNav.responseStart;

// Request + response time
const requestResponseTime = pageNav.responseEnd - pageNav.requestStart;

Yapabileceğiniz diğer ölçümler

Gezinme Zamanlaması ve Kaynak Zamanlaması, önceki örneklerde belirtilenlerden daha fazla işe yarar. Aşağıda, keşfetmeye değer olabilecek ilgili zamanlamalara sahip diğer bazı durumlar verilmiştir:

  • Sayfa yönlendirmeleri: Yönlendirmeler, özellikle yönlendirme zincirleri, gözden kaçırılan bir ek gecikme kaynağıdır. Gecikme, HTTP'den HTTPS'ye atlamalar ve 302/önbelleğe alınmamış 301 yönlendirmeleri gibi çeşitli şekillerde eklenir. redirectStart, redirectEnd ve redirectCount zamanlamaları, yönlendirme gecikmesini değerlendirirken faydalıdır.
  • Belge yüklemeyi kaldırma: unload etkinlik işleyicisinde kod çalıştıran sayfalarda, tarayıcının bir sonraki sayfaya gitmeden önce bu kodu yürütmesi gerekir. unloadEventStart ve unloadEventEnd, doküman kaldırma işlemini ölçer.
  • Doküman işleme: Web siteniz çok büyük HTML yükleri göndermediği sürece doküman işleme süresi önemli olmayabilir. Bu durum sizin için geçerliyse domInteractive, domContentLoadedEventStart, domContentLoadedEventEnd ve domComplete zamanlamalarıyla ilgilenebilirsiniz.

Kodunuzda zamanlamaları alma

Şimdiye kadar gösterilen örneklerin tümünde performance.getEntriesByType kullanılıyor ancak performans girişi arabelleğine performance.getEntriesByName ve performance.getEntries gibi başka yöntemlerle de sorgu gönderebilirsiniz. Bu yöntemler yalnızca basit bir analiz gerektiğinde uygundur. Ancak diğer durumlarda, çok sayıda giriş üzerinde yineleme yaparak veya yeni girişler bulmak için performans arabelleğini tekrar tekrar yoklayarak aşırı ana iş parçacığı çalışmasına neden olabilirler.

Performans girişi arabelleğinden giriş toplamak için önerilen yaklaşım PerformanceObserver kullanmaktır. PerformanceObserver, performans girişlerini dinler ve arabelleğe eklendikçe bunları sağlar:

// Create the performance observer:
const perfObserver = new PerformanceObserver((observedEntries) => {
  // Get all resource entries collected so far:
  const entries = observedEntries.getEntries();

  // Iterate over entries:
  for (let i = 0; i < entries.length; i++) {
    // Do the work!
  }
});

// Run the observer for Navigation Timing entries:
perfObserver.observe({
  type: 'navigation',
  buffered: true
});

// Run the observer for Resource Timing entries:
perfObserver.observe({
  type: 'resource',
  buffered: true
});

Zamanlamaları toplama yöntemi, performans girişi arabelleğine doğrudan erişmeyle karşılaştırıldığında garip gelebilir ancak ana iş parçacığını kritik ve kullanıcıya yönelik bir amaca hizmet etmeyen işlerle bağlamaktan daha iyidir.

How to phone home

İhtiyacınız olan tüm zamanlamaları topladıktan sonra, daha fazla analiz için bunları bir uç noktaya gönderebilirsiniz. Bu işlem, navigator.sendBeacon veya fetch ile keepalive seçeneği ayarlanarak iki şekilde yapılabilir. Her iki yöntem de belirtilen uç noktaya engellemeyen bir şekilde istek gönderir ve gerekirse istek, geçerli sayfa oturumundan daha uzun süre devam edecek şekilde sıraya alınır:

// Check for navigator.sendBeacon support:
if ('sendBeacon' in navigator) {
  // Caution: If you have lots of performance entries, don't
  // do this. This is an example for illustrative purposes.
  const data = JSON.stringify(performance.getEntries());

  // Send the data!
  navigator.sendBeacon('/analytics', data);
}

Bu örnekte, JSON dizesi, gerektiğinde kodunu çözebileceğiniz, işleyebileceğiniz ve bir uygulama arka ucunda saklayabileceğiniz bir POST yükünde gelir.

Sonuç

Metrikler toplandıktan sonra bu saha verilerini nasıl analiz edeceğinizi belirlemek size kalır. Alan verilerini analiz ederken anlamlı sonuçlar çıkarabilmek için uymanız gereken birkaç genel kural vardır:

  • Ortalamalar herhangi bir kullanıcının deneyimini temsil etmediği ve aykırı değerlerden etkilenebileceği için ortalamalardan kaçının.
  • Yüzdelik dilimlerden yararlanın. Zamana dayalı performans metriklerinin veri kümelerinde daha düşük değerler daha iyidir. Bu nedenle, düşük yüzdelik dilimlere öncelik verdiğinizde yalnızca en hızlı deneyimlere dikkat edersiniz.
  • Değerlerin uzun kuyruğuna öncelik verin. 75. yüzdelik dilimdeki veya daha yüksek deneyimlere öncelik verdiğinizde odağınızı olması gereken yere, yani en yavaş deneyimlere yönlendirmiş olursunuz.

Bu kılavuz, Navigation veya Resource Timing hakkında kapsamlı bir kaynak değil, başlangıç noktası olarak tasarlanmıştır. Yararlı olabilecek bazı ek kaynakları aşağıda bulabilirsiniz:

Bu API'ler ve sağladıkları veriler sayesinde, yükleme performansının gerçek kullanıcılar tarafından nasıl deneyimlendiğini daha iyi anlayabilirsiniz. Bu da sahada yükleme performansıyla ilgili sorunları teşhis etme ve giderme konusunda size daha fazla güven verecektir.