Gezinme Zamanlaması ve Kaynak Zamanlaması ile sahada yükleme performansını değerlendirme

Sahada yükleme performansını değerlendirmek için Navigation and Resource Timing API'lerinin kullanımıyla ilgili temel bilgileri öğrenin.

Yükleme performansını değerlendirmek için tarayıcının geliştirici araçlarındaki (veya Chrome'da Lighthouse'taki) ağ panelinde bağlantı daraltma özelliğini kullandıysanız bu araçların performans ayarlama için ne kadar kullanışlı olduğunu biliyorsunuz demektir. Tutarlı ve istikrarlı bir referans bağlantı hızıyla performans optimizasyonlarının etkisini hızla ölçebilirsiniz. Tek sorun bunun sentetik bir test olmasıdır. Bu test, alan verileri yerine laboratuvar verileri sağlar.

Sentetik test, 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 temsil etmez. Bunun için Gezinme Zamanlaması ve Kaynak Zamanlaması API'lerinden toplayabileceğiniz alan verileri gerekir.

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

Gezinme Zamanlaması ve Kaynak Zamanlaması, iki farklı şeyi ölçen önemli ölçüde çakışmaya sahip iki benzer API'dir:

  • Gezinme Zamanlaması, HTML dokümanı isteklerinin (yani gezinme istekleri) hızını ölçer.
  • Kaynak Zamanlaması, CSS, JavaScript, resimler gibi dokümana bağlı kaynaklar için yapılan isteklerin hızını ölçer.

Bu API'ler, verilerini JavaScript ile tarayıcıdan erişilebilen bir performans giriş arabelleğinde açığa çıkarır. Performans arabelleğini sorgulamanın birden çok yolu vardır. Ancak yaygın olarak kullanılan bir yöntem de performance.getEntriesByType kullanmaktır:

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

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

performance.getEntriesByType, performans giriş 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 onlar web sitenizi ziyaret eden kullanıcılardan bu zamanlamaları toplayabileceğiniz için, sahadaki yükleme performansını ölçmek için kullanacağınız anahtar kelimelerdir.

Ağ isteğinin ömrü ve zamanlamaları

Gezinme ve kaynak zamanlamalarını toplayıp analiz etmek bir tür arkeolojiye benzer, çünkü bir ağ isteğinin olaydan sonraki kısa süreli yaşamını yeniden oluşturursunuz. Bazen kavramları görselleştirmeye yardımcı olabilir ve ağ istekleri söz konusu olduğunda tarayıcınızın geliştirici araçlarından yararlanabilirsiniz.

Chrome'un Geliştirici Araçları'nda gösterilen ağ zamanlamaları şeması. Gösterilen zamanlamalar istek sıraya alma, bağlantı görüşmesi, isteğin kendisi ve renk kodlu çubuklardaki yanıt içindir.
Chrome'un Geliştirici Araçları'nın ağ panelindeki ağ isteğinin görselleştirmesi

Bir ağ isteğinin ömrü; DNS araması, bağlantı kurma, TLS iletişimi gibi farklı aşamalardan oluşur. Bu zamanlamalar DOMHighResTimestamp olarak gösterilir. Tarayıcınıza bağlı olarak, zamanlamaların ayrıntı düzeyi mikrosaniyeye kadar inebilir veya milisaniyeye yuvarlanabilir. Bu aşamaları ayrıntılı olarak inceleyip Gezinme Zamanlaması ve Kaynak Zamanlaması ile ilişkisini inceleyelim.

DNS araması

Kullanıcı bir URL'ye gittiğinde Alan Adı Sistemi (DNS), alan adını bir IP adresine çevirmesi için sorgulanır. Bu işlem uzun sürebilir. Hatta sahada ölçüm yapmak için gereken zamanı bile artırabilirsiniz. Gezinme Zamanlaması ve Kaynak Zamanlaması, DNS ile ilgili iki zamanlama gösterir:

  • domainLookupStart, DNS araması başladığında başlar.
  • domainLookupEnd, DNS araması sona erdiğinde gerçekleşir.

Toplam DNS arama süresi, başlangıç metriği bitiş metriğinden çıkarılarak hesaplanabilir:

// 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 başka faktör de bağlantı iletişimidir. Bağlantı iletişimi, bir web sunucusuna bağlanırken yaşanan gecikmedir. HTTPS söz konusuysa bu süreç TLS iletişim süresini de içerir. Bağlantı aşaması üç zamanlamadan oluşur:

  • connectStart, tarayıcının bir web sunucusuyla bağlantı açmaya başlamasını ifade eder.
  • secureConnectionStart, istemci TLS iletişimi başlattığında işaretler.
  • connectEnd, web sunucusuyla bağlantı kurulduğunda gerçekleşir.

Toplam bağlantı süresinin ölçülmesi, toplam DNS arama süresini ölçmeye benzer: Başlangıç zamanını bitiş zamanlamasından çıkarırsınız. Bununla birlikte, HTTPS kullanılmıyorsa veya bağlantı kalıcısa 0 olabilecek ek bir secureConnectionStart özelliği vardır. TLS iletişim süresini ölçmek istiyorsanız bunu 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ı iletişimi sona erdiğinde, belgelerin ve bunlara bağlı kaynakların getirilmesiyle ilgili zamanlamalar devreye girer.

İstekler ve yanıtlar

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

  • Dış faktörler: Bunlar, gecikme ve bant genişliği gibi unsurlardır. Bir barındırma şirketi ve CDN seçmek dışında, kullanıcılar web'e her yerden erişebildiğinden bunlar (çoğunlukla) kontrolümüzün dışındadır.
  • Doğal faktörler: Bunlar sunucu ve istemci tarafı mimarilerinin yanı sıra kaynak boyutu ve kontrolümüzde olan bunlara göre optimizasyon yapabilme kabiliyeti gibi şeylerdir.

Her iki faktör de yükleme performansını etkiler. Kaynakların ne kadar sürede indirileceğini açıkladığı için bu unsurlara yönelik zamanlamalar son derece önemlidir. Hem Gezinme Zamanlaması hem de Kaynak Zamanlaması, yükleme performansını aşağıdaki metriklerle açıklar:

  • fetchStart, tarayıcı bir kaynağı (Kaynak Zamanlaması) veya gezinme isteği için bir doküman (Gezinme Zamanlaması) getirmeye başladığında işaretler. Bu, gerçek istekten önce gelir ve tarayıcının önbellekleri (örneğin, HTTP ve Cache örnekleri) kontrol ettiği noktadır.
  • workerStart, bir hizmet çalışanının fetch etkinlik işleyicisi içinde bir istek işlenmeye başlandığında işaretler. Geçerli sayfayı hiçbir hizmet çalışanı kontrol etmiyorsa bu parametre 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, hizmet çalışanı içinde önbellek araması ve indirme süresi gibi yükleme performansını birçok açıdan ö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/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ı, yukarıdaki örneklerde kısaca açıklanandan daha fazla bilgi için yararlıdır. Alakalı zamanlamaları olan ve araştırmaya değer diğer bazı durumlar şunlardır:

  • Sayfa yönlendirmeleri: Yönlendirmeler, özellikle yönlendirme zincirleri olmak üzere gecikmenin gözden kaçan bir kaynağıdır. Gecikme, 302/önbelleğe alınmamış 301 yönlendirmeleri ve HTTP--HTTP atlamaları gibi birkaç şekilde eklenir. redirectStart, redirectEnd ve redirectCount zamanlamaları yönlendirme gecikmesini değerlendirmede faydalıdır.
  • Doküman kaldırma: Bir unload olay işleyicide kod çalıştıran sayfalarda, tarayıcının sonraki sayfaya gidebilmesi için bu kodu yürütmesi gerekir. unloadEventStart ve unloadEventEnd, belge kaldırma işlemini ölçüyor.
  • Belge işleme: Web siteniz çok büyük HTML yükleri göndermediği sürece belge işleme süresi, sonuç vermeyebilir. Durumunuz bu şekildeyse domInteractive, domContentLoadedEventStart, domContentLoadedEventEnd ve domComplete zamanlamaları ilginizi çekebilir.

Uygulama kodunda zamanlamaları edinme

Şu ana kadar gösterilen tüm örneklerde performance.getEntriesByType kullanılmıştır ancak performans girişi arabelleğini sorgulamanın performance.getEntriesByName ve performance.getEntries gibi başka yolları da vardır. Yalnızca küçük bir analiz gerektiğinde bu yöntemler uygundur. Diğer durumlarda ise çok sayıda girişte yineleme yaparak ve hatta yeni girişler bulmak için performans arabelleğini sürekli yoklayarak aşırı sayıda ana iş parçacığı çalışmasına yol açabilir.

Performans giriş arabelleğinden giriş toplamak için önerilen yaklaşım, PerformanceObserver kullanmaktır. PerformanceObserver, performans girişlerini dinler ve arabelleğe eklenirken 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
});

Bu zamanlama toplama yöntemi, doğrudan performans girişi arabelleğine erişmekle karşılaştırıldığında kulağa tuhaf gelebilir ancak ana iş parçacığını kritik ve kullanıcıya yönelik bir amaca hizmet etmeyen işlerle birleştirmek tercih edilir.

Ev telefonu aranıyor

İhtiyacınız olan tüm zamanlamaları topladıktan sonra bunları daha ayrıntılı analiz için bir uç noktaya gönderebilirsiniz. Bunu yapmanın iki yolu, navigator.sendBeacon veya keepalive seçenekli fetch ayarlamaktır. Her iki yöntem de belirtilen bir uç noktaya erişimi engellemeyen bir şekilde istek gönderir ve istek, gerektiğinde geçerli sayfa oturumundan daha uzun süre dayanacak şekilde sıraya alınır:

// 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()));

// The endpoint to transmit the encoded data to
const endpoint = '/analytics';

// Check for fetch keepalive support
if ('keepalive' in Request.prototype) {
  fetch(endpoint, {
    method: 'POST',
    body: data,
    keepalive: true,
    headers: {
      'Content-Type': 'application/json'
    }
  });
} else if ('sendBeacon' in navigator) {
  // Use sendBeacon as a fallback
  navigator.sendBeacon(endpoint, data);
}

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

Özet

Metrikleri topladıktan sonra bu alan verilerini nasıl analiz edeceğinizi bulmak size kalmıştır. Alan verilerini analiz ederken anlamlı sonuçlar çıkardığınızdan emin olmak için uyulması gereken birkaç genel kural vardır:

  • Herhangi bir kullanıcının deneyimini temsil etmediğinden ve aykırı kullanıcılar tarafından sarsılabileceğinden ortalamalardan kaçının.
  • Yüzdelik dilimlere güvenin. Zamana dayalı performans metrikleri içeren veri kümelerinde düşük değerde daha düşük değerler tercih edilir. Bu, düşük yüzdelik dilimlere öncelik verdiğinizde yalnızca en hızlı deneyimlere dikkat ettiğiniz anlamına gelir.
  • Değerlerin uzun kuyruklarına öncelik verin. 75. yüzdelik dilimde veya daha yüksek bir yüzdelik dilimde deneyimlere öncelik verdiğinizde, odağınızı ait olduğu yere, yani en yavaş deneyimlere odaklamış olursunuz.

Bu kılavuzun amacı, Gezinme veya Kaynak Zamanlaması hakkında kapsamlı bir kaynak değildir, bir başlangıç noktasıdır. Yararlı bulabileceğiniz bazı ek kaynaklar aşağıda verilmiştir:

Bu API'ler ve sağladıkları verilerle, gerçek kullanıcıların yükleme performansı hakkında nasıl bir deneyim yaşadığını daha iyi anlayabilirsiniz. Böylece, sahada yükleme performansı sorunlarını teşhis etme ve çözme konusunda kendinize daha fazla güvenirsiniz.