Özel metrikler

Herhangi bir web sitesinde evrensel olarak ölçebileceğiniz kullanıcı odaklı metrikler, çok değerlidir. Bu metrikler sayesinde:

  • Gerçek kullanıcıların web'i bir bütün olarak nasıl deneyimlediğini anlayın.
  • Sitenizi bir rakibin sitesiyle karşılaştırın.
  • Özel kod yazmanıza gerek kalmadan analiz araçlarınızda yararlı ve uygulanabilir verileri izleyin.

Evrensel metrikler iyi bir temel değer sunar ancak çoğu durumda, belirli sitenizdeki deneyimin tamamını yakalamak için bu metriklerden daha fazlasını ölçmeniz gerekir.

Özel metrikler, sitenizin deneyiminin yalnızca siteniz için geçerli olabilecek yönlerini ölçmenize olanak tanır. Örneğin:

  • Tek sayfa uygulamasının (SPA) bir "sayfadan" diğerine geçiş yapması ne kadar sürer?
  • Bir sayfanın, giriş yapmış kullanıcılar için veritabanından getirilen verileri göstermesi ne kadar sürüyor?
  • Sunucu tarafında oluşturulan (SSR) bir uygulamanın hidrasyonu ne kadar sürer?
  • Geri gelen ziyaretçiler tarafından yüklenen kaynaklar için önbellek isabet oranı.
  • Bir oyundaki tıklama veya klavye etkinliklerinin etkinlik gecikmesi.

Özel metrikleri ölçmeye yönelik API'ler

Geçmişte web geliştiricilerin performansı ölçmek için çok fazla düşük düzeyli API'si yoktu. Bu nedenle, bir sitenin iyi performans gösterip göstermediğini ölçmek için geçici çözümlere başvurmak zorunda kalıyorlardı.

Örneğin, requestAnimationFrame döngüsü çalıştırıp her kare arasındaki farkı hesaplayarak ana iş parçacığının uzun süren JavaScript görevleri nedeniyle engellenip engellenmediğini belirlemek mümkündür. Delta, ekranın kare hızından önemli ölçüde uzunsa bunu uzun görev olarak bildirebilirsiniz. Ancak bu tür çözümler, performansı etkilediği (ör. pili boşaltarak) için önerilmez.

Etkili performans ölçümünün ilk kuralı, performans ölçüm tekniklerinizin kendisinin performans sorunlarına neden olmadığından emin olmaktır. Bu nedenle, sitenizde ölçtüğünüz tüm özel metrikler için mümkünse aşağıdaki API'lerden birini kullanmanız önerilir.

Performance Observer API

Browser Support

  • Chrome: 52.
  • Edge: 79.
  • Firefox: 57.
  • Safari: 11.

Source

Performance Observer API, bu sayfada bahsedilen diğer tüm performans API'lerinden veri toplayan ve bu verileri görüntüleyen mekanizmadır. Bu kavramı anlamak, iyi veriler elde etmek için çok önemlidir.

Performansla ilgili etkinliklere pasif olarak abone olmak için PerformanceObserver kullanabilirsiniz. Bu, API geri çağırmalarının boşta kalma dönemlerinde etkinleşmesini sağlar. Bu da genellikle sayfa performansını etkilemeyecekleri anlamına gelir.

PerformanceObserver oluşturmak için yeni performans girişleri gönderildiğinde çalıştırılacak bir geri çağırma iletin. Ardından, observe() yöntemini kullanarak gözlemciye hangi tür girişleri dinlemesi gerektiğini söylersiniz:

const po = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    // Log the entry and all associated details.
    console.log(entry.toJSON());
  }
});

po.observe({type: 'some-entry-type'});

Aşağıdaki bölümlerde, gözlem için kullanılabilen tüm çeşitli giriş türleri listelenmektedir. Ancak daha yeni tarayıcılarda, hangi giriş türlerinin kullanılabildiğini statik PerformanceObserver.supportedEntryTypes özelliği aracılığıyla inceleyebilirsiniz.

Gerçekleşmiş girişleri gözlemleme

Varsayılan olarak, PerformanceObserver nesneleri yalnızca girişler gerçekleştiğinde gözlemleyebilir. Bu durum, performans analizleri kodunuzu daha yüksek öncelikli kaynakları engellemeyecek şekilde geç yüklemek istiyorsanız sorunlara neden olabilir.

Geçmiş girişleri (gerçekleştikten sonra) almak için observe() işlevini çağırırken buffered işaretini true olarak ayarlayın. Tarayıcı, PerformanceObserver geri çağırma işleviniz ilk kez çağrıldığında performans girişi arabelleğinden geçmiş girişleri, bu tür için maksimum arabellek boyutuna kadar içerir.

po.observe({
  type: 'some-entry-type',
  buffered: true,
});

Kaçınılması gereken eski performans API'leri

Performance Observer API'den önce geliştiriciler, performance nesnesinde tanımlanan aşağıdaki üç yöntemi kullanarak performans girişlerine erişebiliyordu:

Bu API'ler hâlâ destekleniyor olsa da yeni girişler yayınlandığında dinlemenize izin vermediği için kullanılması önerilmez. Ayrıca, birçok yeni API (ör. largest-contentful-paint) performance nesnesi aracılığıyla kullanıma sunulmaz, yalnızca PerformanceObserver aracılığıyla kullanıma sunulur.

Internet Explorer ile uyumluluğa özellikle ihtiyacınız yoksa kodunuzda bu yöntemlerden kaçınmanız ve bundan sonra PerformanceObserver kullanmanız en iyisidir.

User Timing API

Browser Support

  • Chrome: 28.
  • Edge: 12.
  • Firefox: 38.
  • Safari: 11.

Source

User Timing API, zamana dayalı metrikler için genel amaçlı bir ölçüm API'sidir. Bu araç, zaman içinde rastgele noktalar işaretlemenize ve daha sonra bu işaretler arasındaki süreyi ölçmenize olanak tanır.

// Record the time immediately before running a task.
performance.mark('myTask:start');
await doMyTask();

// Record the time immediately after running a task.
performance.mark('myTask:end');

// Measure the delta between the start and end of the task
performance.measure('myTask', 'myTask:start', 'myTask:end');

Date.now() veya performance.now() gibi API'ler benzer özellikler sunsa da User Timing API'nin avantajı, performans araçlarıyla iyi entegre olmasıdır. Örneğin, Chrome Geliştirici Araçları kullanıcı zamanlaması ölçümlerini Performans panelinde görselleştirir. Ayrıca, birçok analiz sağlayıcı da yaptığınız tüm ölçümleri otomatik olarak izler ve süre verilerini analiz arka uçlarına gönderir.

Kullanıcı Zamanlaması ölçümleri hakkında rapor oluşturmak için PerformanceObserver'ı kullanabilir ve measure türündeki girişleri gözlemlemek üzere kaydolabilirsiniz:

// Create the performance observer.
const po = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    // Log the entry and all associated details.
    console.log(entry.toJSON());
  }
});

// Start listening for `measure` entries to be dispatched.
po.observe({type: 'measure', buffered: true});

Long Tasks API

Browser Support

  • Chrome: 58.
  • Edge: 79.
  • Firefox: not supported.
  • Safari: not supported.

Source

Uzun Görevler API'si, tarayıcının ana iş parçacığı kare hızını veya giriş gecikmesini etkileyecek kadar uzun süre engellendiğinde bilgi edinmek için kullanışlıdır. API, 50 milisaniyeden uzun süren tüm görevleri bildirir.

Maliyetli kod çalıştırmanız veya büyük komut dosyaları yükleyip yürütmeniz gerektiğinde, bu kodun ana iş parçacığını engellediğini izlemek faydalıdır. Hatta daha üst düzeydeki birçok metrik, Long Tasks API'nin kendisi üzerine kurulmuştur (ör. Etkileşime Hazır Olma Süresi (TTI) ve Total Blocking Time (TBT)).

Uzun görevlerin ne zaman gerçekleştiğini belirlemek için PerformanceObserver'ı kullanabilir ve longtask türündeki girişleri gözlemlemek üzere kaydolabilirsiniz:

// Create the performance observer.
const po = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    // Log the entry and all associated details.
    console.log(entry.toJSON());
  }
});

// Start listening for `longtask` entries to be dispatched.
po.observe({type: 'longtask', buffered: true});

Long Animation Frames API

Browser Support

  • Chrome: 123.
  • Edge: 123.
  • Firefox: not supported.
  • Safari: not supported.

Source

Long Animation Frames API, 50 milisaniyeden uzun uzun görevler yerine uzun karelere bakan Long Tasks API'nin yeni bir sürümüdür. Bu, daha iyi ilişkilendirme ve olası sorunlu gecikmelerin daha geniş kapsamı dahil olmak üzere Uzun Görevler API'sinin bazı eksikliklerini giderir.

Uzun karelerin ne zaman gerçekleştiğini belirlemek için PerformanceObserver'ı kullanabilir ve long-animation-frame türündeki girişleri gözlemlemek üzere kaydolabilirsiniz:

// Create the performance observer.
const po = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    // Log the entry and all associated details.
    console.log(entry.toJSON());
  }
});

// Start listening for `long-animation-frame` entries to be dispatched.
po.observe({type: 'long-animation-frame', buffered: true});

Element Timing API

Browser Support

  • Chrome: 77.
  • Edge: 79.
  • Firefox: not supported.
  • Safari: not supported.

Source

Largest Contentful Paint (LCP) metriği, en büyük resmin veya metin bloğunun ekrana ne zaman çizildiğini öğrenmek için yararlıdır ancak bazı durumlarda farklı bir öğenin oluşturma süresini ölçmek isteyebilirsiniz.

Bu durumlarda Element Timing API'yi kullanın. LCP API aslında Element Timing API'nin üzerine kurulmuştur ve en büyük içerik öğesinin otomatik olarak raporlanmasını sağlar. Ancak elementtiming özelliğini açıkça ekleyerek ve element giriş türünü gözlemlemek için bir PerformanceObserver kaydederek diğer öğeler hakkında da rapor oluşturabilirsiniz.

<img elementtiming="hero-image" />
<p elementtiming="important-paragraph">This is text I care about.</p>
<!-- ... -->

<script>
  const po = new PerformanceObserver((entryList) => {
    for (const entry of entryList.getEntries()) {
      // Log the entry and all associated details.
      console.log(entry.toJSON());
    }
  });

  // Start listening for `element` entries to be dispatched.
  po.observe({type: 'element', buffered: true});
</script>

Event Timing API

Browser Support

  • Chrome: 76.
  • Edge: 79.
  • Firefox: 89.
  • Safari: 26.2.

Source

Interaction to Next Paint (INP) metriği, bir sayfanın ömrü boyunca tüm tıklama, dokunma ve klavye etkileşimlerini gözlemleyerek genel sayfa duyarlılığını değerlendirir. Bir sayfanın INP değeri, kullanıcının etkileşimi başlattığı andan itibaren tarayıcının kullanıcının girişinin görsel sonucunu gösteren bir sonraki kareyi boyadığı ana kadar tamamlanması en uzun süren etkileşimdir.

INP metriği, Event Timing API sayesinde kullanılabilir. Bu API, etkinlik yaşam döngüsü sırasında gerçekleşen bir dizi zaman damgasını kullanıma sunar. Örneğin:

  • startTime: Tarayıcının etkinliği aldığı zaman.
  • processingStart: Tarayıcının, etkinliğin etkinlik işleyicilerini işlemeye başlayabileceği zaman.
  • processingEnd: Tarayıcının, bu etkinlik için etkinlik işleyicilerinden başlatılan tüm eşzamanlı kodu yürütmeyi bitirdiği zaman.
  • duration: Tarayıcının etkinliği aldığı zaman ile etkinlik işleyicilerden başlatılan tüm senkron kodların yürütülmesini tamamladıktan sonraki kareyi oluşturabildiği zaman arasındaki süre (güvenlik nedeniyle 8 milisaniyeye yuvarlanır).

Aşağıdaki örnekte, özel ölçümler oluşturmak için bu değerlerin nasıl kullanılacağı gösterilmektedir:

const po = new PerformanceObserver((entryList) => {
  // Get the last interaction observed:
  const entries = Array.from(entryList.getEntries()).forEach((entry) => {
    // Get various bits of interaction data:
    const inputDelay = entry.processingStart - entry.startTime;
    const processingTime = entry.processingEnd - entry.processingStart;
    const presentationDelay = entry.startTime + entry.duration - entry.processingEnd;
    const duration = entry.duration;
    const eventType = entry.name;
    const target = entry.target || "(not set)"

    console.log("----- INTERACTION -----");
    console.log(`Input delay (ms): ${inputDelay}`);
    console.log(`Event handler processing time (ms): ${processingTime}`);
    console.log(`Presentation delay (ms): ${presentationDelay}`);
    console.log(`Total event duration (ms): ${duration}`);
    console.log(`Event type: ${eventType}`);
    console.log(target);
  });
});

// A durationThreshold of 16ms is necessary to include more
// interactions, since the default is 104ms. The minimum
// durationThreshold is 16ms.
po.observe({type: 'event', buffered: true, durationThreshold: 16});

Resource Timing API

Browser Support

  • Chrome: 29.
  • Edge: 12.
  • Firefox: 35.
  • Safari: 11.

Source

Resource Timing API, geliştiricilere belirli bir sayfanın kaynaklarının nasıl yüklendiği hakkında ayrıntılı bilgi verir. API'nin adına rağmen sağladığı bilgiler yalnızca zamanlama verileriyle sınırlı değildir (bu tür veriler de bolca bulunur). Erişebileceğiniz diğer veriler şunlardır:

  • initiatorType: Kaynağın nasıl getirildiği (ör. <script> veya <link> etiketinden ya da fetch() çağrısından).
  • nextHopProtocol: Kaynağı getirmek için kullanılan protokol (ör. h2 veya quic).
  • encodedBodySize/decodedBodySize]: Kaynağın kodlanmış veya kodlanmamış biçimindeki boyutu (sırasıyla)
  • transferSize: Ağ üzerinden aktarılan kaynağın gerçek boyutu. Kaynaklar önbellek tarafından karşılandığında bu değer encodedBodySize değerinden çok daha küçük olabilir ve bazı durumlarda sıfır olabilir (önbelleğin yeniden doğrulanması gerekmiyorsa).

Kaynak zamanlaması girişlerinin transferSize özelliğini kullanarak önbellek isabet oranı metriğini veya toplam önbelleğe alınmış kaynak boyutu metriğini ölçebilirsiniz. Bu metrikler, kaynak önbelleğe alma stratejinizin tekrar gelen ziyaretçilerin performansını nasıl etkilediğini anlamak için faydalı olabilir.

Aşağıdaki örnek, sayfa tarafından istenen tüm kaynakları günlüğe kaydeder ve her kaynağın önbellek tarafından karşılanıp karşılanmadığını belirtir.

// Create the performance observer.
const po = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    // If transferSize is 0, the resource was fulfilled using the cache.
    console.log(entry.name, entry.transferSize === 0);
  }
});

// Start listening for `resource` entries to be dispatched.
po.observe({type: 'resource', buffered: true});

Browser Support

  • Chrome: 57.
  • Edge: 12.
  • Firefox: 58.
  • Safari: 15.

Source

Navigation Timing API, Resource Timing API'ye benzer ancak yalnızca gezinme isteklerini bildirir. navigation giriş türü de resource giriş türüne benzer ancak yalnızca gezinme isteklerine (ör. DOMContentLoaded ve load etkinlikleri tetiklendiğinde) özel bazı ek bilgiler içerir.

Sunucu yanıt süresini (İlk Bayt Zamanı (TTFB)) anlamak için birçok geliştiricinin izlediği bir metrik, Navigation Timing API kullanılarak kullanılabilir. Bu metrik, özellikle girişin responseStart zaman damgasıdır.

// Create the performance observer.
const po = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    // If transferSize is 0, the resource was fulfilled using the cache.
    console.log('Time to first byte', entry.responseStart);
  }
});

// Start listening for `navigation` entries to be dispatched.
po.observe({type: 'navigation', buffered: true});

Hizmet çalışanı kullanan geliştiricilerin önem verdiği bir diğer metrik ise gezinme istekleri için hizmet çalışanı başlatma süresidir. Bu, tarayıcının getirme etkinliklerini yakalamaya başlamadan önce hizmet çalışanı iş parçacığını başlatması için gereken süredir.

Belirli bir gezinme isteğinin service worker başlatma süresi, entry.responseStart ile entry.workerStart arasındaki farktan belirlenebilir.

// Create the performance observer.
const po = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    console.log('Service Worker startup time:',
        entry.responseStart - entry.workerStart);
  }
});

// Start listening for `navigation` entries to be dispatched.
po.observe({type: 'navigation', buffered: true});

Server Timing API

Browser Support

  • Chrome: 65.
  • Edge: 79.
  • Firefox: 61.
  • Safari: 16.4.

Source

Server Timing API, isteğe özel zamanlama verilerini yanıt üstbilgileri aracılığıyla sunucunuzdan tarayıcıya iletmenize olanak tanır. Örneğin, belirli bir istek için verilerin bir veritabanında aranmasının ne kadar sürdüğünü belirtebilirsiniz. Bu, sunucudaki yavaşlıktan kaynaklanan performans sorunlarının hata ayıklamasında faydalı olabilir.

Üçüncü taraf analiz sağlayıcılarını kullanan geliştiriciler için Server Timing API, sunucu performans verilerini bu analiz araçlarının ölçebileceği diğer işletme metrikleriyle ilişkilendirmenin tek yoludur.

Yanıtlarınızda sunucu zamanlaması verilerini belirtmek için Server-Timing yanıt üst bilgisini kullanabilirsiniz. Örneğin,

HTTP/1.1 200 OK

Server-Timing: miss, db;dur=53, app;dur=47.2

Ardından, sayfalarınızdan bu verileri Kaynak Zamanlama ve Gezinme Zamanlama API'lerinden gelen resource veya navigation girişlerinde okuyabilirsiniz.

// Create the performance observer.
const po = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    // Logs all server timing data for this response
    console.log('Server Timing', entry.serverTiming);
  }
});

// Start listening for `navigation` entries to be dispatched.
po.observe({type: 'navigation', buffered: true});