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

Alandaki yükleme performansını değerlendirmek için Gezinme ve Kaynak Zamanlama API'lerini kullanmanın temel özelliklerini öğ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 ağ panelinde (veya Chrome'daki Lighthouse'ta) bağlantıyı azaltma özelliğini kullandıysanız bu araçların performans ayarı için ne kadar kullanışlı olduğunu bilirsiniz. Performans optimizasyonlarının etkisini, tutarlı ve istikrarlı bir referans bağlantı hızıyla hızlıca ölçebilirsiniz. Tek sorun, bunun sentetik test olmasıdır. Bu test alan verileri değil, laboratuvar verileri sağlar.

Sentetik testler temelde kötü değildir ancak web sitenizin gerçek kullanıcılar için ne kadar hızlı yüklendiğini yansıtmaz. Bunun için Navigation Timing ve Resource Timing API'lerinden toplayabileceğiniz alan verileri gerekir.

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

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

  • Gezinme Zamanlaması, HTML dokümanlarına yönelik isteklerin (yani gezinme isteklerinin) hızını ölçer.
  • Kaynak Zamanlaması; CSS, JavaScript, resimler ve diğer kaynak türleri gibi dokümana bağlı kaynaklara yönelik isteklerin hızını ölçer.

Bu API'ler, verilerini tarayıcıdan JavaScript ile erişilebilen bir performans girişi arabelleğinde gösterir. Performans tamponunu sorgulamanın birden fazla yolu vardır ancak yaygın bir yol 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ş türlerini açıklayan bir dize kabul eder. 'navigation' ve 'resource', sırasıyla Gezinme Zamanlaması ve Kaynak Zamanlaması API'leri için zamanlamaları alır.

Bu API'lerin sağladığı bilgi miktarı göz korkutucu olabilir, ancak web sitenizi ziyaret eden kullanıcılardan bu zamanlamaları toplayabileceğiniz için, sahadaki yükleme performansını ölçmek için kullanılan anahtardırlar.

Bir ağ isteğinin ömrü ve zamanlamaları

Rota izleme ve kaynak zamanlamalarını toplayıp analiz etmek arkeoloji gibidir. Buradaki amacımız, bir ağ isteğinin kısa süreli durumunu yeniden yapılandırmaktır. Bazen kavramları görselleştirmek işe yarar. Ağ isteklerinin gerekli olduğu durumlarda 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 zamanlamalar; istek kuyruğuna ekleme, bağlantı anlaşması, isteğin kendisi ve renk kodlu çubuklardaki yanıt içindir.
Chrome Geliştirici Araçları'nın ağ panelinde bir ağ isteğinin görselleştirmesi

Bir ağ isteğinin ömrü; DNS araması, bağlantı kurma, TLS iletişimi ve diğer gecikme kaynakları 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ı ve Gezinme Zamanlaması ile Kaynak Zamanlaması ile ilişkilerini ayrıntılı olarak incelemeniz gerekir.

DNS araması

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. Gezinme Zamanlaması ve Kaynak Zamanlaması, DNS ile ilgili iki zamanlamayı gösterir:

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

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

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

Bağlantı pazarlığı

Yükleme performansını etkileyen bir diğer faktör de bağlantı pazarlığıdır. Bu, web sunucusuna bağlanırken oluşan gecikmeyi ifade eder. HTTPS kullanılıyorsa 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 sunucusu bağlantısını açmaya başladığı zamandır.
  • secureConnectionStart, istemcinin TLS iletişimine başladığı zamanı gösterir.
  • connectEnd, web sunucusuyla bağlantı kurulduğunda gerçekleşir.

Toplam bağlantı süresini ölçmek, toplam DNS arama süresini ölçmeye benzer: Başlangıç zamanını bitiş zamanından çıkarırsınız. Ancak HTTPS kullanılmadığında veya bağlantı kalıcıysa 0 değerini alabilecek ek bir secureConnectionStart mülkü vardır. TLS müzakere süresini ölçmek istiyorsanız aşağıdakileri 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ı pazarlığı sona erdiğinde, dokümanları ve bunlara bağlı kaynakları getirmeyle 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 faktörlerdir. Kullanıcılar web'e her yerden erişebildiğinden, barındırma şirketi ve muhtemelen bir CDN seçmenin dışındaki konular (çoğunlukla) bizim kontrolümüzde değildir.
  • Doğası gereği faktörler: Sunucu ve istemci tarafı mimariler, kaynak boyutu ve bu faktörler için optimizasyon yapma becerimiz gibi kontrolümüz altında olan faktörlerdir.

Her iki faktör türü de yükleme performansını etkiler. Bu faktörlerle ilgili zamanlamalar, kaynakların indirilmesinin ne kadar sürdüğünü tanımladığı için çok önemlidir. 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ı getirmeye başladığı zamanı (Gezinme Zamanlaması) 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 bir hizmet çalışanının fetch etkinlik işleyicisinde işlenmeye başladığı zamanı işaret eder. Geçerli sayfayı hiçbir hizmet çalışanı kontrol etmiyorsa bu değer 0 olur.
  • requestStart, tarayıcının isteği yaptığı 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, bir hizmet çalışanı içinde önbellek araması ve indirme süresi gibi yükleme performansının çeşitli yönlerini ö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 açıklananlardan daha fazla yarar sağlar. Aşağıda, ilgili zamanlamalara sahip ve incelemeye değer olabilecek diğer bazı durumlar verilmiştir:

  • Sayfa yönlendirmeleri: Yönlendirmeler, özellikle yönlendirme zincirleri olmak üzere göz ardı edilen ek gecikme kaynaklarıdır. Gecikme, HTTP'den HTTP'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ğerlendirmede faydalıdır.
  • Belgenin boşaltılması: unload etkinlik işleyicisinde kod çalıştıran sayfalarda, tarayıcı bir sonraki sayfaya gidebilmek için bu kodu yürütmelidir. unloadEventStart ve unloadEventEnd, belge kaldırma işlemini ölçüyor.
  • Belge işleme: Web siteniz çok büyük HTML yükü göndermediği sürece belge işleme süresi sıralı olmayabilir. Bu, durumunuzu tanımlıyorsa domInteractive, domContentLoadedEventStart, domContentLoadedEventEnd ve domComplete zamanlamaları ilginizi çekebilir.

Kodunuzda zamanlamaları alma

Ş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 bulunur. Yalnızca basit analizler gerektiğinde bu yöntemler kullanılabilir. Ancak diğer durumlarda, çok sayıda girişi iterleyerek veya hatta yeni girişler bulmak için performans arabelleğini tekrar tekrar sorgulayarak aşırı ana iş parçacığı çalışmasına neden olabilirler.

Performans giriş arabelleğinden giriş toplamak için önerilen yaklaşım, bir PerformanceObserver kullanmaktır. PerformanceObserver, performans girişlerini dinler ve arabelleğe eklenirken bu girişleri 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ı toplamaya yönelik bu yöntem, performans girişi tamponuna doğrudan erişmekle kıyaslandığında tuhaf gelebilir, ancak ana iş parçacığını kritik ve kullanıcıya yönelik bir amaca hizmet etmeyen bir işle bağlamanız tercih edilir.

Evden telefon etme

İhtiyacınız olan tüm zamanlamaları topladıktan sonra, daha ayrıntılı analiz için bunları bir uç noktaya gönderebilirsiniz. Bunu, navigator.sendBeacon veya keepalive seçenekli fetch ile yapmanın iki yolu vardır. Her iki yöntem de, belirtilen uç noktaya engellenmeyen bir şekilde istek gönderir ve istek, gerekirse mevcut sayfa oturumundan daha uzun süre boyunca beklemeye 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, kodunu çözebileceğiniz, işleyebileceğiniz ve gerektiğinde bir uygulama arka ucunda depolayabileceğiniz bir POST yükü olarak gelir.

Sonuç

Metrikleri topladıktan sonra bu alan verilerini nasıl analiz edeceğinize karar vermeniz gerekir. Saha verilerini analiz ederken anlamlı sonuçlara ulaştığınızdan emin olmak için uymanız gereken birkaç genel kural vardır:

  • Hiçbir kullanıcının deneyimini temsil etmediği ve aykırı değerler nedeniyle sapma gösterebileceği için ortalamalardan kaçının.
  • Yüzdelik dilimlere güvenin. Zamana dayalı performans metriklerinin bulunduğu veri kümelerinde, daha düşük değerler daha iyidir. 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 dilim veya daha yüksek deneyimlere öncelik verdiğinizde, odaklanmanız gereken yere odaklanırsınız: en yavaş deneyimlere.

Bu kılavuz, Navigasyon veya Kaynak Zamanlaması hakkında kapsamlı bir kaynak değil, bir başlangıç noktası olarak tasarlanmıştır. İşinize yarayabilecek bazı ek kaynakları aşağıda bulabilirsiniz:

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