Bir sayfanın performansı, onu yayına aldığınız gün değil, sonraki altı ay boyunca sürekli değişen bir değerdir. Üçüncü taraf bir etiket ekler, bir font daha yüklenir, bir bileşen kütüphanesi güncellenir, bir görsel yeniden boyutlandırılır. Hiçbiri kırılma değildir. Ama toplamları, hiçbirinin tek başına vermediği bir bozulma yapabilir.
Ve bu bozulma genellikle fark edilmez. Çünkü sayfa açılıyor, hata vermiyor, sonuç sayısı değişmiyor. Sadece yavaşlıyor.
Üç metrik, üç farklı soru
LCP (Largest Contentful Paint) — Sayfanın en büyük görsel öğesi ne zaman göründü? Kullanıcının "sayfa açıldı" hissi buna bağlıdır.
Bozulduğunda genellikle suçlu: kahraman görseli optimize edilmemiş, yeni bir font yukarıda yükleniyor, gereksiz bir JavaScript paketi eklendi.
CLS (Cumulative Layout Shift) — İçerik yüklenirken sayfa ne kadar zıpladı? Kullanıcının yanlış yere tıklamasının ana nedenidir.
Bozulduğunda genellikle suçlu: boyutu belirtilmemiş bir görsel, geç yüklenen bir reklam, sonradan enjekte edilen bir banner.
INP (Interaction to Next Paint) — Kullanıcı bir şeye tıkladıktan sonra arayüz ne kadar sürede tepki verdi?
Bozulduğunda genellikle suçlu: ana iş parçacığını (main thread) meşgul eden işlemler, olay dinleyicileri, ağır kütüphaneler.
Neden "sürekli" ölçüm gerekiyor?
Klasik yaklaşım: PageSpeed Insights'a bağlantıyı yapıştırın, skoru alın. Bu tek bir ölçümdür ve üç sorunlu vardır.
1. Tek an, tek ölçüm. Gerçek kullanıcılar farklı cihazlardan, farklı ağlardan, farklı saatlerde girer. Laboratuvar skoru tek bir senaryonun sonucudur ve gerçek dağılımı göstermez.
2. Kırılma anını kaçırırsınız. Metrik, bir düğmeyle bozuldu. Kimse o anda bakmadı. Bozulma fark edildiğinde hangi değişikliğin yaptığı belli değildir.
3. Sunucudan bakmak yetmez. Metrikler kullanıcının cihazında ölçülür. Sunucunuz sağlıklıyken de metrik bozulmuş olabilir.
Sürekli ölçümün çözdüğü şey ikincisidir: her değişiklikten sonra metriğin gerçekten değişip değişmediği görülür.
Bozulmayı nasıl yakalarsınız?
1. Değişiklikle ölçümü eşleştirin
Bir sayfa değişti, LCP kötüleşti. Bu ilişkiyi kuramazsanız, her zaman "muhtemelen şu değişiklik" dersiniz.
Pratikte çalışan yöntem: her değişiklik kaydı, o sayfanın o andaki metrik değerini de taşır. Bir hafta sonra geriye bakarsınız ve hangi değişikliğin metriği ne kadar etkilediğini görürsünüz.
Bunun için değişiklik geçmişinizin neden bilgisini taşıması gerekir — sadece "bir şey değişti" değil. Kanıt arşivi tam olarak bunun için işe yarar.
2. Sayfa bazında takip edin, site bazında değil
Site ortalaması yanıltıcıdır. Ana sayfanız hızlandıysa, ürün sayfalarınız yavaşladıysa ortalamanız değişmeyebilir.
Sayfa bazında takip edin. Çünkü bozulan sayfa genellikle tek sayfadır ve dönüşüm de oradadır.
3. Eşiği gerçek veriden belirleyin
Bir sayfanın LCP'si 2.4 saniyeyse ve sınır 2.5 ise, her değişiklik sınırın hemen altında kalır. Bir sonraki küçük değişiklik sınırı aşar ve alarm çalar — ama gerçekte bir şey değişmedi.
Bu, alarm yorgunluğunun klasik bir örneğidir: eşik, "değişti" eşiği olarak kalırsa, sisteminiz değişikliği değil gürültüyü izliyor demektir.
Dönüşüm ne zaman yavaşlatır?
Metrikler neden bozulduğunu gösterir, ama düzeltmek için bir iş listesi vermez. Bu, kasıtlıdır: metrik bir teşhistir, tedavi değildir.
Pratikte en sık görülen ve en sık ertelenen dört durum:
Görseller. En sık. Boyut belirtilmemiş, yeni formatlara geçilmemiş, gereksiz yere büyük. Tek başına LCP'nin en yaygın nedenidir.
JavaScript paketleri. Her eklenen kütüphane ana iş parçacığında yer alır. INP'yi ve dolayısıyla LCP'yi birlikte bozar.
Yazı tipleri. Her yeni aile, her yeni ağırlık, ayrı dosya demek. Üstüne
display=swap yoksa, yazı tipi yüklenene kadar metin görünmez.
Reklam ve üçüncü taraf betikler. Kontrolünüz dışında, performansı doğrudan etkileyen, sonradan eklenebilen tek şey.
React ve Next.js projelerinde INP neden kötüdür?
INP'nin tek bir sebebi vardır: ana iş parçacığının bloke olması. Yavaş bir ağ INP'yi etkilemez — ağ yavaşsa LCP kötüleşir. INP, kullanıcı bir şeye tıkladıktan sonra tarayıcının bir sonraki karesini ne kadar geç çizdiğidir. Bu tamamen JavaScript'in işi.
Modern React ve Next.js uygulamalarında ana iş parçacığını üç şey bloke eder:
Fazla yeniden çizim. Bir bileşen durumu değiştiğinde, o duruma bağlı olmayan bölümler de yeniden çizilir. Küçük bir değişiklik, tüm sayfayı yeniden çizerse kullanıcı tıklamasını hisseder.
Hydration. Sunucudan gelen HTML'i istemcide etkileşimli hâle getirmek JavaScript'in çalışmasını gerektirir. Bu süreç ne kadar büyükse, tıklamaya geç yanıt o kadar geç gelir.
Üçüncü taraf betikler. Reklam, izleme ve sohbet widget'ları ana iş parçacığında yer alır. Sizin kodunuz olmadan, sizin kodunuzu yavaşlatırlar.
Üçü de aynı sonuca çıkar ve üçü farklı çözüm ister: yeniden çizim için bileşen sınırları, hydration için paket boyutu, üçüncü taraf için ise yükleme sıralaması. Yani INP'yi düzeltmek, tek bir ayarı değiştirmek değil; üç ayrı yolculuk yürümek demek.
Bu yüzden INP'yi izlemek, diğer metriklere göre daha çok zaman ister. LCP'yi görüntü boyutunu küçülterek halledebilirsiniz; INP için bileşen mimarisine dokunmanız gerekir.
Nerede başlanır?
Dört adım, bu sırayla:
- Ana sayfa, listeleme ve ürün sayfalarını seçin. Gerçek dönüşümün olduğu sayfalar. Hepsini değil.
- Bir hafta boyunca yalnızca ölçün, müdahale etmeyin. Bu, gerçek değerlerin ne olduğunu gösterir.
- Metrikler, mevcut sayfa yapınıza göre eşik belirleyin. Her sayfa için farklı olabilir.
- Sonra değişiklik izlemeyi bağlayın. Artık "metrik bozuldu" dendiğinde "hangi değişiklik yaptı" sorusu cevaplanabilir.
Süreç, araç seçerken sorulan soruların web vitals karşılığıdır: hangi metrikleri ölçer, ne kadar geçmişi tutar, eşiği ayarlanabilir mi.
Özet
- Web vitals metrikleri sürekli bozulur; bozulma genellikle fark edilmez çünkü sayfa çalışmaya devam eder.
- Tek seferlik ölçüm kırılma anını kaçırır; sürekli ölçüm onu yakalar.
- Sayfa bazında takip edin, site ortalaması değil.
- Metrik teşhistir, tedavi değildir. En sık dört neden: görseller, JavaScript paketleri, yazı tipleri, üçüncü taraf betikler.
Bir sayfanın görsel olarak neye benzediğini izlemenin aynı mantığını görsel regresyon testinde ele alıyoruz.