Bir sayfanın başlangıçta arka planda yüklenip yüklenmediğini (ör. yeni bir arka plan sekmesinde açılıp açılmadığını) belirlemek, doğru performans izleme için çok önemlidir. Arka planda yüklenen sayfaların oluşturulması genellikle gecikir ve metrik süreleri (ör. First Contentful Paint) daha uzun olur. Bu sayfaları belirleyerek performans analizlerinden filtreleyebilir ve verilerin çarpıtılmasını önleyebilirsiniz.
Bunu ölçmenin en doğru yolu, komut dosyanızın ne zaman yürütüldüğünden bağımsız olarak tarayıcının performans zaman çizelgesindeki görünürlük değişikliklerini güvenilir bir şekilde kaydeden VisibilityStateEntry API'yi kullanmaktır.
İlk görünürlük ve arka plan süresini algılama
ZORUNLU: Tam görünürlük geçmişine erişmek için performance.getEntriesByType('visibility-state') kullanın. Yürütme sırasında yalnızca document.visibilityState kontrolüne güvenmeyin. Bu kontrol, yarışma durumlarına karşı hassastır.
/**
* Accurately determines visibility state history using the Performance API.
*/
function getVisibilityInfo() {
// Retrieve VisibilityStateEntry members:
const entries = performance.getEntriesByType('visibility-state');
if (entries.length > 0) {
const firstEntry = entries[0];
// If the first performance entry for visibility is 'hidden',
// the page was loaded in the background.
const initiallyBackgrounded = firstEntry.name === 'hidden';
// Find the precise, high-resolution timestamp of when the page
// was first backgrounded.
let timeBackgrounded = null;
for (const entry of entries) {
if (entry.name === 'hidden') {
// entry.startTime is used because it provides the exact browser
// timestamp of the visibility change, which is required for precision
timeBackgrounded = entry.startTime;
break;
}
}
return {
initiallyBackgrounded,
timeBackgrounded
};
}
}
Yedek stratejiler
Desteklenmeyen ortamlarda, document.visibilityState özelliğini kontrol etmeye veya visibilitychange etkinliğini dinlemeye geri dönebilirsiniz.
ZORUNLU: Bu yedek yaklaşımın genellikle ilk arka plan durumunu belirleme konusunda son derece hatalı olduğunu anlamanız gerekir. Komut dosyaları eşzamansız olarak yüklenip yürütülebildiğinden, bir sayfa arka plan sekmesinde açılabilir ve ardından komut dosyanızın indirilmesi ve yürütülmesi tamamlanmadan önce kullanıcı tarafından ön plana getirilebilir. Komut dosyanız nihayet çalıştığında document.visibilityState, eşzamanlı olarak 'visible' şeklinde okunur ve sayfanın ön planda yüklendiğini yanlış bir şekilde varsayarak sayfanın ilk gizli durumunu tamamen kaçırırsınız. Ayrıca, yedek zaman damgası Performance API'nin dahili hassasiyetine sahip değildir. Hassasiyet yüksek öncelikliyse yedek reklamı kullanmayın.
/**
* Fallback implementation using document.visibilityState.
* This approach is prone to race conditions if the script loads asynchronously.
*/
function getFallbackVisibilityInfo() {
// Check the state exactly when this script executes.
// This will fail to detect an initial background state if the user
// foregrounded the page before this script executed.
let initiallyBackgrounded = document.visibilityState === 'hidden';
// If it's hidden now, we approximate that it was hidden from load (time 0).
let timeBackgrounded = initiallyBackgrounded ? 0 : null;
// Listen for future visibility changes to capture if it is backgrounded later.
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'hidden' && timeBackgrounded === null) {
// performance.now() is used here as a fallback, but it only gives
// us the time the event listener fired, not the precise internal
// browser time the visibility actually changed.
timeBackgrounded = performance.now();
}
});
return {
get initiallyBackgrounded() { return initiallyBackgrounded; },
get timeBackgrounded() { return timeBackgrounded; }
};
}
// Modern implementation using VisibilityStateEntry API.
function getVisibilityInfo() {
// Code omitted here would be the same modern
// implementation shown earlier in this guide
// ...
}
// DO: Detect if the VisibilityStateEntry API is available
if ('VisibilityStateEntry' in window) {
// DO: If VisibilityStateEntry is available, use it first:
getVisibilityInfo();
} else {
// DO: If VisibilityStateEntry is unavailable, fall back to `document.visibilityState`:
getFallbackVisibilityInfo();
}