Hız testi sayfasında 95 puan alıp, aynı gün "siteniz çok yavaş açılıyor" mesajı almak sandığından daha yaygın bir durumdur. Sebebi basit: o test, güçlü bir sunucudan, hızlı bir bağlantıyla, temiz bir tarayıcıda, tek seferlik yapıldı. Senin gerçek ziyaretçin ise üç yaşında bir telefonda, otobüste, zayıf bir mobil bağlantıda, üstelik reklam engelleyicisi olan bir tarayıcıda siteyi açtı. RUM (Real User Monitoring), yani gerçek kullanıcı ölçümü, tam olarak bu boşluğu kapatmak için var: laboratuvar tahmini yerine sahadaki asıl deneyimi ölçer.
Bu rehberde RUM'un ne olduğunu, sentetik testten hangi noktalarda ayrıldığını, tarayıcının sana hangi metrikleri ücretsiz olarak verdiğini ve bunları kendi sunucuna toplayan basit bir toplayıcının nasıl yazılacağını anlatacağım. Ayrıca en kritik konuya, yani ortalama yerine yüzdelik dilimlerle düşünmeye ve verinin nasıl segmentlere ayrılacağına ayrı bir bölüm ayırdım; çünkü RUM verisini yanlış okumak, hiç ölçmemekten daha kötü kararlar aldırır.
RUM Nedir ve Sentetik Testten Farkı Nedir#
RUM, sitene giren her gerçek ziyaretçinin tarayıcısında performans verisi toplayıp bunu bir toplama noktasına gönderme yöntemidir. Sayfaya küçük bir JavaScript parçası koyarsın, tarayıcı zaten tuttuğu zamanlama verilerini bu betiğe verir, betik de bu verileri senin sunucuna ya da bir analiz servisine iletir. Sonuçta binlerce farklı cihaz, ağ ve coğrafyadan gelen gerçek ölçümlerin oluşturduğu bir dağılım elde edersin.
Sentetik test ise kontrollü bir laboratuvar ölçümüdür: sen bir adres verirsin, servis belirli bir konumdan belirli bir cihaz profiliyle sayfayı açar ve rapor üretir. İkisi rakip değil, tamamlayıcıdır. Farkı şu tabloda net görürsün.
| Özellik | Sentetik test | RUM |
|---|---|---|
| Veri kaynağı | Test sunucusu | Gerçek ziyaretçi tarayıcısı |
| Tekrarlanabilirlik | Yüksek, kontrollü | Düşük, gerçekçi |
| Regresyon yakalama | Deploy öncesi ideal | Deploy sonrası ideal |
| Cihaz/ağ çeşitliliği | Tek profil | Sahadaki tüm çeşitlilik |
| Trafik gerektirir mi | Hayır | Evet, anlamlı hacim gerekir |
| Sorunun nedenini gösterir mi | Evet, ayrıntılı döküm | Kısmen, daha çok "kimde ve nerede" |
Bu tablodaki son satır önemlidir ve çoğu kişi yanlış anlar: RUM sana "neden yavaş" sorusunun cevabını nadiren verir; "kimde, hangi sayfada, hangi cihazda, hangi ülkede yavaş" sorusunun cevabını verir. Nedeni bulmak için oradan sentetik teste ve sunucu tarafı incelemesine geçersin. Yani RUM teşhisin başlangıcıdır, sonu değil; genel akış için yavaş site teşhis akışı yazısındaki katman ayrımıyla birlikte kullan.
Tarayıcı Sana Hangi Metrikleri Veriyor#
Modern tarayıcılar performans verisini ek bir kütüphane olmadan, standart API'ler üzerinden sunar. Toplaman gereken metrikler iki gruba ayrılır: yükleme zamanlamaları ve kullanıcı deneyimi metrikleri.
Yükleme zamanlamaları Navigation Timing API'sinden gelir ve sayfanın ağ seviyesindeki dökümünü verir: DNS çözümleme, TCP bağlantısı, TLS, isteğin gönderilmesi, ilk baytın gelmesi ve belge yüklenmesinin bitmesi. Bunlar sunucu tarafı sorunlarını yakalamak için kritiktir.
Kullanıcı deneyimi metrikleri ise Core Web Vitals olarak bilinen üçlüdür ve kullanıcının gerçekten ne hissettiğini ölçer.
| Metrik | Neyi ölçer | İyi eşik | Kötüyse ilk bakılacak yer |
|---|---|---|---|
| LCP | En büyük içerik ne zaman çizildi | 2,5 sn altı | Hero görseli, TTFB, engelleyen CSS |
| INP | Etkileşime yanıt gecikmesi | 200 ms altı | Ağır JavaScript, uzun görevler |
| CLS | Görsel düzen kayması | 0,1 altı | Boyutsuz görseller, geç yüklenen reklam |
| TTFB | Sunucunun ilk bayt süresi | 800 ms altı | Uygulama, veritabanı, önbellek |
Bu dört metriği toplarsan performans sorunlarının büyük çoğunluğunu yakalarsın. LCP değerlerin kötü çıkıyorsa LCP nasıl iyileştirilir, CLS tarafında sorun görüyorsan CLS düzen kayması nasıl düzeltilir yazıları düzeltme adımlarını veriyor. TTFB kötüyse sorun tarayıcıda değil sunucudadır ve o zaman sunucu yanıt süresi izleme tarafına geçmen gerekir.
Kendi RUM Toplayıcını Kurmak#
RUM için mutlaka bir ücretli servis kullanman gerekmiyor. Küçük ve orta ölçekli bir sitede kendi topladığın veri fazlasıyla yeterli olur. Mantık üç parçadan oluşur: tarayıcıda ölçüm, sunucuya gönderim, veritabanında saklama.
Tarayıcı tarafında PerformanceObserver ile metrikleri dinlersin. Aşağıdaki parça LCP, CLS ve navigasyon zamanlamalarını toplayıp sayfa kapanırken tek seferde gönderir:
// Basit RUM toplayıcı - sayfanın sonuna koy
(function () {
var veri = { yol: location.pathname, lcp: 0, cls: 0, ttfb: 0 };
// Navigation Timing: TTFB ve toplam yükleme
var nav = performance.getEntriesByType("navigation")[0];
if (nav) {
veri.ttfb = Math.round(nav.responseStart);
veri.yukleme = Math.round(nav.loadEventEnd);
}
// LCP: en son bildirilen değer geçerlidir
new PerformanceObserver(function (list) {
var girisler = list.getEntries();
veri.lcp = Math.round(girisler[girisler.length - 1].startTime);
}).observe({ type: "largest-contentful-paint", buffered: true });
// CLS: kullanıcı etkileşimi olmadan gerçekleşen kaymaları topla
new PerformanceObserver(function (list) {
list.getEntries().forEach(function (g) {
if (!g.hadRecentInput) veri.cls += g.value;
});
}).observe({ type: "layout-shift", buffered: true });
// Sayfa gizlenirken tek seferde gönder - unload güvenilir değildir
addEventListener("visibilitychange", function () {
if (document.visibilityState === "hidden") {
veri.cls = Math.round(veri.cls * 1000) / 1000;
navigator.sendBeacon("/rum", JSON.stringify(veri));
}
}, { once: true });
})();
Buradaki iki detay önemlidir. Birincisi buffered: true seçeneği: betiğin çalışmasından önce gerçekleşmiş olayları da alır, yoksa erken LCP'leri kaçırırsın. İkincisi visibilitychange kullanımı: mobil tarayıcılarda unload olayı çoğu zaman hiç tetiklenmez, bu yüzden veriyi sayfa gizlenirken göndermek tek güvenilir yöntemdir. sendBeacon isteği sayfa kapansa bile arka planda tamamlar.
Sunucu tarafında gelen veriyi kabul edip yazan uç nokta çok basit olabilir. Kritik olan, bu uç noktanın hızlı olması ve ağır bir uygulama çatısını çalıştırmamasıdır; her sayfa görüntüleme başına bir istek geleceğini unutma. Toplanan satırları şöyle bir tabloda saklayabilirsin:
CREATE TABLE rum_olcumleri (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
olcum_ts DATETIME NOT NULL,
yol VARCHAR(255) NOT NULL,
ttfb_ms INT,
lcp_ms INT,
cls_x1000 INT,
cihaz VARCHAR(16), -- mobil / masaustu / tablet
ulke CHAR(2),
INDEX idx_ts_yol (olcum_ts, yol)
);
Ham satırları sonsuza kadar tutma; 30–60 gün sakla, öncesini saatlik özetlere indir. Aksi hâlde RUM tablosu birkaç ayda veritabanının en büyük tablosu hâline gelir ve kendisi bir performans sorununa dönüşür.
Ortalama Yalan Söyler: Yüzdelik Dilimlerle Düşün#
RUM verisini yorumlarken yapılabilecek en büyük hata ortalama almaktır. Performans dağılımları simetrik değildir; sağa çok uzun bir kuyrukları vardır. Yüz kullanıcının doksanı 1 saniyede, onu 12 saniyede sayfa açıyorsa ortalama 2,1 saniye çıkar ve tablo gayet iyi görünür. Oysa her on kullanıcıdan biri siteyi kullanılamaz buluyordur.
Bu yüzden RUM'da yüzdelik dilimlerle çalışılır. p75 değeri, "kullanıcıların yüzde 75'i bu değerden daha iyi bir deneyim yaşadı" demektir. Core Web Vitals eşikleri de p75 üzerinden değerlendirilir.
| Ölçüt | Ne söyler | Ne için kullanılır |
|---|---|---|
| p50 (medyan) | Tipik kullanıcı deneyimi | Genel gidişat takibi |
| p75 | Web Vitals resmi eşiği | Hedef belirleme, raporlama |
| p95 | Kötü uçtaki deneyim | Kapasite ve kuyruk sorunları |
| p99 | En kötü senaryo | Nadir ama ciddi hataları yakalama |
Pratikte p75'i hedef olarak, p95'i erken uyarı olarak kullan. p95 bozulmaya başladığında p75 genelde hâlâ iyidir; yani p95, sorunun kullanıcı kitlesinin geneline yayılmadan önce sana haber veren ölçüttür. Sunucu tarafında da aynı mantık geçerlidir: yanıt süresi ortalaması sabit dururken p95'in tırmanması, kaynak doygunluğunun ilk işaretidir ve genelde load average nasıl okunur yazısındaki normalize yük değeriyle birlikte yükselir.
Veriyi Segmentlere Ayırmadan Anlam Çıkmaz#
Tek bir toplam p75 sayısı, ilginç olan her şeyi gizler. Aynı sitede masaüstü kullanıcıların LCP'si 1,4 saniye, mobil kullanıcıların 4,8 saniye olabilir; toplamda 2,6 saniye görürsün ve hiçbir şey anlamazsın. RUM verisini en az şu dört boyutta ayır.
- Cihaz tipi — mobil ile masaüstü arasındaki fark neredeyse her zaman en büyük ayrımdır. Mobil CPU'lar JavaScript'i üç dört kat yavaş çalıştırır.
- Sayfa şablonu — ana sayfa, kategori, ürün detayı ve arama sonuçları farklı sorgu yükleri taşır. Yolları şablon bazında grupla, tek tek URL olarak değil.
- Coğrafya — sunucuna uzak ülkelerdeki kullanıcılar sabit bir ağ gecikmesi öder. Bu ayrımı görmeden CDN kararı veremezsin; CDN mi daha iyi hosting mi tartışmasının cevabı senin RUM verinde yazıyordur.
- Bağlantı tipi — tarayıcı bunu her zaman vermez ama verdiğinde 4G ile yavaş bağlantı arasındaki farkı ayırmanı sağlar.
Bir de zaman boyutunu unutma. Aynı segmentin gün içindeki değişimini çizdirdiğinde, belirli saatlerde bozulan bir desen görürsen bu artık ön yüz değil altyapı sorunudur; site belirli saatlerde yavaşlıyor yazısı bu desenin olası nedenlerini tek tek ele alıyor.
Sık Yapılan Hatalar#
RUM betiğini engelleyici biçimde yüklemek. Performansı ölçmek için koyduğun betiğin kendisi performansı bozuyorsa amaç kaybolmuştur. Toplayıcıyı async yükle, sayfanın sonuna koy ve mümkünse üçüncü taraf bir alan adından değil kendi alan adından servis et.
Her metriği ayrı istekle göndermek. LCP, CLS ve INP farklı zamanlarda kesinleşir ama bu üçünü üç ayrı istekle göndermek, sayfa başına üç kat trafik demektir. Verileri bir nesnede biriktir, sayfa gizlenirken tek istekle gönder.
Yetersiz trafikle karar vermek. Günde 200 sayfa görüntülemesi olan bir sitede p95 değeri istatistiksel gürültüdür. Anlamlı bir p75 için sayfa şablonu başına günlük en az birkaç yüz ölçüm gerekir. Altındaysan segmentleri birleştir ve haftalık pencerelerle çalış.
Kişisel veri toplamak. RUM için IP adresine, tam URL sorgu parametrelerine ya da kullanıcı kimliğine ihtiyacın yok. Yolu şablona indirge, ülkeyi ülke kodu olarak sakla, IP'yi hiç yazma. Hem yasal yükümlülüğün hafifler hem de tablon küçülür.
Sadece toplamaya odaklanıp alarm kurmamak. Verinin değeri, biri ona baktığında ortaya çıkar. p75 LCP değeri belirlediğin eşiği aştığında haber veren basit bir kontrol kur; aksi hâlde regresyonu haftalar sonra fark edersin.
Sıkça Sorulan Sorular#
RUM kurmak için ücretli bir servis şart mı#
Hayır. Tarayıcı API'leri ücretsizdir ve yukarıdaki gibi 40 satırlık bir betikle LCP, CLS ve TTFB toplayabilirsin. Ücretli servisler sana hazır panolar, uzun süreli saklama, otomatik segmentasyon ve oturum tekrar oynatma gibi ek özellikler sunar. Küçük ve orta ölçekli sitelerde kendi topladığın veri kararların çoğu için fazlasıyla yeterlidir; ölçek büyüyüp ekip kalabalıklaştığında hazır çözüm işini kolaylaştırır.
RUM verisi ile hız testi puanı neden uyuşmuyor#
Çünkü ikisi farklı şeyi ölçer. Hız testi tek bir sabit senaryodur: belirli bir konum, belirli bir cihaz, temiz bir tarayıcı. RUM ise sahadaki tüm çeşitliliği toplar; içinde eski telefonlar, zayıf bağlantılar, dolu sekmeler ve tarayıcı eklentileri vardır. Uyuşmazlık bir hata değil, beklenen durumdur. Karar verirken sahayı, regresyon takibi yaparken laboratuvarı kullan.
Kaç günlük RUM verisi tutmalıyım#
Ham satırları 30–60 gün tutmak çoğu senaryo için yeterlidir. Bunun ötesini saatlik ya da günlük özetlere indirgeyip sakla: yüzdelik dilimleri önceden hesaplayıp yalnızca özet satırlarını tut. Böylece bir yıllık trendi görebilirken tablo boyutu kontrolden çıkmaz. Ham veriyi süresiz saklamak, RUM sisteminin kendisini bir performans sorununa dönüştürür.
RUM sayfa hızını yavaşlatır mı#
Doğru kurulduğunda ölçülebilir bir etkisi olmaz. Toplayıcı birkaç kilobayttır, ana iş parçacığını yalnızca milisaniyelerle meşgul eder ve veriyi sendBeacon ile arka planda gönderir. Yavaşlatan kurulumlar genelde şu hataları yapar: betiği head içinde engelleyici olarak yüklemek, üçüncü taraf bir alan adından çekmek (ek DNS ve TLS maliyeti) ve her metriği ayrı istekle göndermek.
INP değerini nasıl ölçerim#
INP, kullanıcının tıklama ve tuş girişlerine sayfanın verdiği yanıt gecikmesini ölçer ve ancak etkileşim olduğunda üretilir. PerformanceObserver ile event tipini gözlemleyerek ham veriyi alabilirsin, ancak hesaplama kuralları LCP kadar basit değildir. Pratikte bu metrik için Google'ın yayımladığı küçük ölçüm kütüphanesini kullanmak ya da hazır bir RUM servisinden almak daha güvenilir sonuç verir.
RUM için kullanıcıdan izin almam gerekir mi#
Yukarıdaki gibi yalnızca zamanlama değerleri, sayfa şablonu, cihaz tipi ve ülke kodu topluyorsan kişisel veri işlemiyorsun demektir ve bu genelde meşru menfaat kapsamında değerlendirilir. Ancak IP adresi saklamaya, kalıcı bir ziyaretçi kimliği yazmaya ya da oturum kaydı almaya başladığında durum değişir ve aydınlatma metni ile açık rıza gerekir. En sağlıklısı ölçümü baştan kimliksiz tasarlamaktır.
Kapanış#
RUM, performans çalışmasını fikir tartışmasından veri tartışmasına dönüştürür. Aklında kalması gereken dört şey şu: sentetik test regresyon yakalar, RUM gerçeği söyler ve ikisi birlikte kullanılır; ortalama değil p75 ve p95 ile düşün; veriyi cihaz, şablon ve coğrafya boyutunda ayırmadan hiçbir sonuç çıkarma; ve topladığın veriye bir eşik alarmı bağlamadan iş bitmiş sayılmaz. Bu dördünü uygularsan hangi iyileştirmenin gerçekten işe yaradığını tahmin etmeyi bırakırsın.
RUM verin sunucu tarafında bir darboğaz gösteriyorsa, yani TTFB dağılımın bozuksa, çözüm ön yüzde değil altyapıdadır. Öngörülebilir kaynak isteyen projeler için VDS ve bulut sunucu seçeneklerimize, önbellek katmanı hazır gelen paylaşımlı kurulumlar için web hosting ve WordPress hosting paketlerimize göz atabilirsin. İzleme ve alarm kurulumunu kendin üstlenmek istemiyorsan sunucu yönetimi hizmetimiz bu işi baştan sona kurar.