Yük altında Web Vitals: kullanıcı gerçekte ne görüyor?
Bir yük testi API'nin p95'ini söyler; kullanıcının ekranında neler olduğunu söylemez. Sayfa, API cevap verdikten sonra da JavaScript çalıştırır, görselleri indirir, içeriği yerleştirir. Sunucu yük altında 200 ms'den 600 ms'ye çıktığında sayfanın ana içeriği 1,8 saniyeden 4 saniyeye de çıkabilir, hiç değişmeyebilir de. Bunu ancak yük sürerken gerçek bir tarayıcıyla sayfayı açarak görürsünüz.
Neyi ölçüyoruz?
Google'ın Core Web Vitals ölçütleri kullanıcı deneyimini üç sayıyla özetler; tarayıcı bunları kendisi ölçer:
- LCP (Largest Contentful Paint): sayfadaki en büyük içeriğin (ana görsel, başlık bloğu) ekranda göründüğü an. 2,5 saniye ve altı iyi, 4 saniyenin üstü zayıf sayılır.
- INP (Interaction to Next Paint): bir tıklamadan ya da tuşa basmaktan ekranın değiştiği ana kadar geçen süre. 200 ms ve altı iyi, 500 ms'nin üstü zayıf.
- CLS (Cumulative Layout Shift): içeriğin kullanıcının gözü önünde ne kadar kaydığı. Geç gelen bir banner metni aşağı iterse CLS artar. 0,1 ve altı iyi, 0,25'in üstü zayıf.
- TTFB ve yükleme süresi: ilk baytın gelmesi ve sayfanın yükleme olayı. TTFB'nin artıp LCP'nin onunla birlikte artması sorunun sunucuda olduğunu; TTFB sabitken LCP'nin artması ön yüzde ya da başka bir kaynakta olduğunu gösterir.
Yükü tarayıcıyla üretmeyin
Gerçek bir tarayıcı pahalıdır: gerçek bir sayfada tarayıcı başına yaklaşık 350 MB bellek ve bir çekirdeğin beşte biri. Bin kullanıcıyı tarayıcıyla taklit etmek düzinelerce makine ister ve yük, sistemin değil yük üreticilerinin sınırına takılır. Doğru düzen hibrittir: yükü protokol düzeyinde (HTTP, gRPC, mesaj kuyrukları) üretin, yanında birkaç tarayıcı kullanıcısı aynı yolculuğu yapıp ölçsün. Tarayıcılar yük için değil, termometre olarak oradadır.
Termometrenin kendisi ısınmamalı: tarayıcıyı çalıştıran makine doyarsa ölçümler gerçekte olduğundan kötü görünür. Tarayıcıları protokol yükünden ayrı makinelerde çalıştırın ve makinenin meşguliyetini ölçümle birlikte izleyin.
Sık yapılan hatalar
- Yükten önce ölçmemek. Yüksüz bir taban ölçümü olmadan "LCP 3 saniye" bir şey söylemez. Testin ilk dakikalarını düşük yükte tutun ya da yükü basamaklarla artırın; Web Vitals'ın hangi basamakta bozulduğu asıl bilgidir.
- Ortalamaya bakmak. Google da Web Vitals'ı yüzdelikle değerlendirir; p75 ya da p90'a bakın (p95 ve p99 rehberi).
- Erken tıklamak. Kullanıcı girdisi LCP ölçümünü durdurur ve girdiden sonraki 500 ms içindeki kaymalar CLS'ye sayılmaz. Yolculukta sayfanın oturmasını bekleyin (bir öğenin görünmesini ya da bir metni beklemek gibi), sonra tıklayın.
- Önbelleği unutmak. Aynı tarayıcı sekmesi ikinci ziyarette görselleri ve betikleri önbellekten alır; bu, geri dönen bir kullanıcıdır. İlk ziyareti ölçmek istiyorsanız bunu sonuçları okurken hesaba katın.
Spitfire ile
Spitfire'da bu düzen tek bir testtir. Protokol adımları yükü üretir; Tarayıcı adımı olan küçük bir senaryo, aynı anda headless Chromium ile bir kullanıcı yolculuğu yapar. Yolculuk eylemlerden oluşur ve ilk eylem sayfayı açmaktır:
- Sayfayı aç (
goto): adrese gider, yükleme olayını bekler. - Tıkla (
click) ve Görünene kadar bekle (wait): CSS seçiciyle; öğe görünene kadar bekler. - Yaz (
type): bir alana metin yazar;{{değişken}}ve CSV verisi kullanılabilir. - Metni doğrula (
expect): metin süre içinde sayfada (ya da bir öğede) görünmezse adım başarısız olur. - Bekle (
sleep): okuma süresi. Her eylemin kendi zaman aşımı vardır (varsayılan 30 sn).
Her VU'nun kendi sekmesi ve çerezleri vardır, gizli pencere gibi; oturum adımlar ve iterasyonlar arasında korunur. Adım şu metrikleri üretir: browser_lcp, browser_cls, browser_inp, browser_ttfb, browser_load ve yolculuğun tamamı için req_duration. Bunlara diğer metrikler gibi eşik yazılır; eşik kırılırsa koşu "kaldı" biter, CI'da da (CI/CD rehberi).
400 VU'nun ürün API'sini zorladığı 14 dakikalık bir test; yanında 3 tarayıcı kullanıcısı sepetten ödeme sayfasına gider. API'nin p95'i 300 ms'nin, sayfanın LCP p90'ı 2,5 saniyenin, INP p90'ı 200 ms'nin altında kalmalı. Test spitfire validate ile doğrulandı.
{
"name": "Mağaza: API yükü ve kullanıcı deneyimi",
"variables": { "base": "https://staging.example.com" },
"scenarios": [
{ "name": "api",
"executor": { "type": "ramping-vus", "startVUs": 0,
"stages": [ { "duration": "3m", "target": 400 }, { "duration": "10m", "target": 400 },
{ "duration": "1m", "target": 0 } ] },
"steps": [ { "id": "list", "name": "Ürünler", "request": { "method": "GET", "url": "{{base}}/api/products" },
"thinkTime": { "min": "1s", "max": "3s" } } ] },
{ "name": "kullanicilar",
"executor": { "type": "constant-vus", "vus": 3, "duration": "14m" },
"steps": [ { "id": "buy", "name": "Sepetten ödemeye", "protocol": "browser",
"browser": { "actions": [
{ "do": "goto", "url": "{{base}}/sepet" },
{ "do": "click", "selector": "#checkout" },
{ "do": "expect", "text": "Ödeme bilgileri", "timeout": "10s" } ] },
"thinkTime": { "min": "5s", "max": "10s" } } ] }
],
"thresholds": [
{ "metric": "req_duration", "filter": { "step": "list" }, "expr": "p(95)<300" },
{ "metric": "browser_lcp", "expr": "p(90)<2500" },
{ "metric": "browser_inp", "expr": "p(90)<200" }
]
}Koşu sayfasındaki Tarayıcı kartı her adımın p90 değerlerini Google'ın eşikleriyle renklendirir. Termometrenin ısınmasını da ölçer: browser_lag, runner'ın kendi zamanlayıcısının ne kadar geciktiğidir; p95'i 100 ms'yi aşarsa kart ölçümlerin güvenilir olmadığını söyler ve tarayıcı VU'larını azaltmanızı ya da ayrı bir runner vermenizi önerir.
Tarayıcı adımı Chromium'lu bir runner ister: algebransoft/spitfire:<sürüm>-browser imajı. Runner'lar sayfasındaki Tarayıcı adımları için seçeneği komutu bu imajla hazırlar. Böyle bir runner kendini browser etiketiyle bildirir ve Spitfire tarayıcı adımı olan senaryoları yalnız bu runner'lara verir; protokol yükü diğer runner'larda kalır. 4 vCPU ve 8 GB'lık bir runner yaklaşık 10 tarayıcı VU'su taşır.
Bir koşudaki tarayıcı VU'su sayısı lisansa bağlıdır: ücretsiz sürümde 1, Growth'ta 5, Scale'de 20, Enterprise'da sınırsız. Termometre için çoğu zaman birkaç tarayıcı yeter.
Spitfire tek komutla Docker'a ya da Kubernetes'e kurulur; ücretsiz sürümde bir tarayıcı VU'suyla Web Vitals ölçebilirsiniz.