Herhangi bir web sitesinde evrensel olarak ölçebileceğiniz kullanıcı odaklı metriklere sahip olmak çok değerlidir. Bu metrikler sayesinde şunları yapabilirsiniz:
- Gerçek kullanıcıların web'i bir bütün olarak nasıl deneyimlediğini anlayın.
- Sitenizi bir rakip siteyle karşılaştırın.
- Özel kod yazmanıza gerek kalmadan analiz araçlarınızda faydalı ve işlem yapılabilir verileri izleyin.
Evrensel metrikler iyi bir referans noktası sunar ancak çoğu durumda, belirli bir sitenizin deneyimini tam olarak yakalamak için bu metriklerden daha fazlasını ölçmeniz gerekir.
Özel metrikler, sitenizdeki deneyimin yalnızca siteniz için geçerli olabilecek yönlerini ölçmenize olanak tanır. Örneğin:
- Tek sayfalık bir uygulamanın (SPA) bir "sayfada"n diğerine geçişi için geçen süre.
- Bir sayfanın, oturum açmış kullanıcılar için veritabanından alınan verileri göstermesi ne kadar sürer?
- Sunucu tarafında oluşturulan (SSR) bir uygulamanın etkinleştirilmesi için gereken süre.
- Geri gelen ziyaretçiler tarafından yüklenen kaynakların önbelleğe isabet oranı.
- Bir oyundaki tıklama veya klavye etkinliklerinin etkinlik gecikmesi.
Özel metrikleri ölçmek için API'ler
Geçmişte web geliştiricilerinin performansı ölçmek için çok fazla düşük düzey API'si yoktu. Bu nedenle, bir sitenin iyi performans gösterip göstermediğini ölçmek için hilelere başvurmak zorunda kalıyorlardı.
Örneğin, bir requestAnimationFrame
döngüsü çalıştırıp her kare arasındaki farkı hesaplayarak ana iş parçacığının uzun süre çalışan JavaScript görevleri nedeniyle engellenip engellenmediğini belirlemek mümkündür. Delta, ekranın kare hızından çok daha uzunsa bunu uzun görev olarak bildirebilirsiniz. Ancak bu tür hilelerin performansı etkilediği (ör. pili tüketerek) için önerilmez.
Etkili performans ölçümünün ilk kuralı, performans ölçüm tekniklerinizin performans sorunlarına neden olmadığından emin olmaktır. Bu nedenle, mümkünse sitenizde ölçtüğünüz tüm özel metrikler için aşağıdaki API'lerden birini kullanmak en iyisidir.
Performance Observer API
Performans Gözlemleyici API'si, bu sayfada açıklanan diğer tüm performans API'lerinden gelen verileri toplayıp görüntüleyen mekanizmadır. İyi veriler elde etmek için bu konuyu anlamak çok önemlidir.
Performansla ilgili etkinliklere pasif olarak abone olmak için PerformanceObserver
değerini kullanabilirsiniz. Bu, API geri çağırmalarının boş zamanlarda etkinleşmesini sağlar. Yani genellikle sayfa performansını etkilemezler.
PerformanceObserver
oluşturmak için yeni performans girişleri gönderildiğinde çalıştırılacak bir geri çağırma işlevi iletin. Ardından, observe()
yöntemini kullanarak gözlemciye ne tür girişleri dinlemesi gerektiğini bildirirsiniz:
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özlemlenebilir tüm giriş türleri listelenmektedir. Ancak yeni tarayıcılarda, statik PerformanceObserver.supportedEntryTypes
mülkü aracılığıyla hangi giriş türlerinin kullanılabileceğini inceleyebilirsiniz.
Geçmişte gerçekleşen girişleri gözlemleme
Varsayılan olarak, PerformanceObserver
nesneleri yalnızca girişleri gerçekleştikçe gözlemleyebilir. Bu durum, performans analizleri kodunuzu daha yüksek öncelikli kaynakları engellememesi için yavaş yüklemek isterseniz sorunlara neden olabilir.
Geçmiş girişleri almak için (gerçekleştikten sonra) 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ş arabelleğindeki geçmiş girişleri bu tür için maksimum arabellek boyutuna kadar dahil eder.
po.observe({
type: 'some-entry-type',
buffered: true,
});
Kullanılmaması 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 vermedikleri için kullanılmaları önerilmez. Ayrıca, birçok yeni API (largest-contentful-paint
gibi) performance
nesnesi üzerinden değil, yalnızca PerformanceObserver
üzerinden gösterilir.
Özellikle Internet Explorer ile uyumluluğu desteklemeniz gerekmiyorsa kodunuzda bu yöntemlerden kaçınmanız ve bundan sonra PerformanceObserver
kullanmaya başlamanız en iyisidir.
User Timing API
User Timing API, zamana dayalı metrikler için genel amaçlı bir ölçüm API'sidir. Zaman içinde istediğiniz 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 size benzer özellikler sunsa da User Timing API'yi kullanmanın avantajı, performans araçlarıyla iyi entegre olmasıdır. Örneğin, Chrome DevTools Performans panelinde kullanıcı zamanlama ölçümlerini görselleştirir. Ayrıca birçok analiz sağlayıcı, yaptığınız tüm ölçümleri otomatik olarak izler ve süre verilerini kendi analiz arka uçlarına gönderir.
Kullanıcı zamanlaması ölçümlerini bildirmek için PerformanceObserver'ı kullanabilir ve measure
türündeki girişleri gözlemlemek için 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
Long Tasks API, tarayıcının ana iş parçacığının kare hızını veya giriş gecikmesini etkileyecek kadar uzun süre engellendiğini öğrenmek için kullanışlıdır. API, 50 milisaniyeden uzun süren tüm görevleri bildirir.
Pahalı 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ı engelleyip engellemediğini izlemek faydalıdır. Aslında, birçok üst düzey metrik (ör. Etkileşime Hazır Olma Süresi (TTI) ve Toplam Engelleme Süresi (TBT)) Long Tasks API'nin üzerine inşa edilmiştir.
Uzun görevlerin ne zaman gerçekleştiğini belirlemek için PerformanceObserver'ı kullanabilir ve longtask
türündeki girişleri gözlemlemek için kaydolun:
// 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
Long Animation Frames API, 50 milisaniyeden uzun uzun görevler yerine uzun kareleri inceleyen Long Tasks API'nin yeni bir iterasyonudur. Bu sayede, daha iyi ilişkilendirme ve soruna yol açabilecek gecikmeler için daha geniş bir kapsam da dahil olmak üzere Long Tasks API'nin bazı eksiklikleri giderilir.
Uzun karelerin ne zaman gerçekleştiğini belirlemek için PerformanceObserver'ı kullanabilir ve long-animation-frame
türündeki girişleri gözlemlemek için 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
Largest Contentful Paint (LCP) metriği, en büyük resmin veya metin bloğunun ekrana ne zaman çizildiğini öğrenmek için kullanışlıdır ancak bazı durumlarda farklı bir öğenin oluşturma süresini ölçmek istersiniz.
Bu durumlarda Element Timing API'yi kullanın. LCP API aslında Element Timing API'nin üzerine inşa edilmiştir ve en büyük içerikli öğenin otomatik raporlamasını ekler. 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
Interaction to Next Paint (INP) metriği, sayfanın kullanım süresi boyunca tüm tıklama, dokunma ve klavye etkileşimlerini gözlemleyerek sayfanın genel duyarlılığını değerlendirir. Bir sayfanın INP'si genellikle kullanıcının etkileşimi başlattığı andan, tarayıcı kullanıcının girişinin görsel sonucunu gösteren bir sonraki kareyi boyadığı ana kadar geçen süredir.
INP metriği, Event Timing API tarafından sağlanır. Bu API, etkinlik yaşam döngüsü sırasında gerçekleşen bir dizi zaman damgasını gösterir. Örneğin:
startTime
: Tarayıcının etkinliği aldığı zaman.processingStart
: Tarayıcının etkinlik için etkinlik işleyicilerini işlemeye başlayabileceği zaman.processingEnd
: Tarayıcının, bu etkinlik için etkinlik işleyicilerden başlatılan tüm eşzamanlı kodu yürütmeyi tamamladığı zaman.duration
: Tarayıcının etkinliği aldığı andan, etkinlik işleyicilerden başlatılan tüm senkronize kodun yürütülmesini tamamladıktan sonra bir sonraki kareyi boyayabildiği ana kadar geçen 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
Resource Timing API, geliştiricilere belirli bir sayfanın kaynakları nasıl yüklendiğini ayrıntılı olarak gösterir. API'nin adına rağmen sağladığı bilgiler yalnızca zamanlama verileriyle sınırlı değildir (bununla birlikte çok sayıda zamanlama verisi vardır). Erişebileceğiniz diğer veriler şunlardır:
initiatorType
: Kaynağın getirilme şekli:<script>
veya<link>
etiketi ya dafetch()
çağrısı gibi.nextHopProtocol
: Kaynağı getirmek için kullanılan protokol (ör.h2
veyaquic
).encodedBodySize
/decodedBodySize]: Kaynak, kodlanmış veya kod çözülmüş biçimde (sırasıyla)transferSize
: Ağ üzerinden gerçekte aktarılan kaynağın boyutu. Kaynaklar önbellek tarafından karşılandığında bu değerencodedBodySize
değerinden çok daha küçük olabilir ve bazı durumlarda sıfır olabilir (önbellek yeniden doğrulaması gerekmiyorsa).
Önbellek isabet oranı metriğini veya önbelleğe alınan toplam kaynak boyutu metriğini ölçmek için kaynak zamanlama girişlerinin transferSize
mülkünü kullanabilirsiniz. Bu metrik, kaynak önbelleğe alma stratejinizin tekrar ziyaret eden kullanıcıların performansını nasıl etkilediğini anlamanıza yardımcı olabilir.
Aşağıdaki örnekte, sayfa tarafından istenen tüm kaynaklar günlüğe kaydedilir ve her bir kaynağın önbelleğe alınıp alınmadığı belirtilir.
// 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});
Navigation Timing API
Navigation Timing API, Resource Timing API'ye benzer ancak yalnızca gezinme isteklerini raporlar. navigation
giriş türü de resource
giriş türüne benzer ancak yalnızca gezinme isteklerine özgü bazı ek bilgiler içerir (ör. DOMContentLoaded
ve load
etkinliklerinin tetiklendiği durumlar).
Birçok geliştiricinin sunucu yanıt süresini (ilk bayt zamanı (TTFB)) anlamak için izlediği bir metrik, Gezinme Zamanlaması API'si (özellikle de girişinin responseStart
zaman damgası) kullanılarak kullanılabilir.
// 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 dikkate alabileceği bir diğer metrik de gezinme isteklerine yönelik hizmet çalışanı başlatma süresidir. Bu, tarayıcı tarafından getirme etkinliklerini durdurmaya başlamadan önce hizmet çalışanı iş parçacığının başlatılması için gereken süredir.
Belirli bir gezinme isteği için hizmet çalışanının başlangıç zamanı, 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
Sunucu Zamanlama API'si, isteklere özgü zamanlama verilerini sunucunuzdan yanıt üstbilgileri aracılığıyla tarayıcıya iletmenize olanak tanır. Örneğin, belirli bir istek için veritabanında verilerin aranmasının ne kadar sürdüğünü belirtebilirsiniz. Bu, sunucudaki yavaşlıktan kaynaklanan performans sorunlarını gidermede yararlı olabilir.
Üçüncü taraf analiz sağlayıcıları kullanan geliştiriciler için sunucu performansı verilerini bu analiz araçlarının ölçebileceği diğer işletme metrikleriyle ilişkilendirmenin tek yolu Sunucu Zamanlaması API'sidir.
Yanıtlarınızda sunucu zamanlama 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 Resource Timing ve Navigation Timing API'lerindeki hem resource
hem de 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});