Bu sitenin, yani kymcu.com'un mobil PageSpeed Insights skoru bir noktada 40'tı. Performans dışında erişilebilirlik 95, best practices 93 — kötü değil ama iyi de değil. Bugün dördü de 100.
Bu yazı bir "10 ipucu" listesi değil. Gerçek bir vakanın, kendi sitemizde adım adım yaptığımız düzeltmelerin kaydı — hangi ölçümün neden düştüğünü, hangi düzeltmenin gerçekten işe yaradığını, hangisinin görünüşte mantıklı ama etkisiz olduğunu anlatıyor.
Skorlar ve ölçümler
| Metrik | Önce | Sonra |
|---|---|---|
| Performans | 40 | 100 |
| Erişilebilirlik | 95 | 100 |
| Best Practices | 93 | 100 |
| SEO | 100 | 100 |
| LCP | 4.8s | ~0.5s |
| TBT | 6.200 ms | 0–200ms |
| FCP | 4.0s | ~0.4–2.7s |
| CLS | 0.019 | 0–0.043 |
Hem mobil hem masaüstü taramada 100/100/100/100 — gerçek Google PSI sunucusunda, ekran görüntüsüyle doğrulanmış.
Asıl darboğaz: font CDN'i
En büyük LCP kazancı beklenmedik bir yerden geldi. Google Fonts CDN'inden çekilen fontlar sayfanın büyük başlığını (LCP elemanı) bekletiyordu — DNS çözümleme, TLS el sıkışması, ekstra bir round-trip. preload + media="print" gibi non-blocking yükleme numaraları bile bu maliyeti tamamen ortadan kaldıramadı.
Çözüm kaba ama kesin: Bebas Neue, Manrope (variable, tüm ağırlıklarıyla tek dosyada) ve JetBrains Mono'yu (variable) latin + latin-ext alt kümeleriyle indirip public/assets/fonts/ altında kendi sunucumuzdan servis etmeye başladık. Türkçe karakterler (ı, ş, ğ) için latin-ext alt kümesi şart — sadece latin kullanırsan başlıklar bozuk görünür.
Kritik 6 font dosyasını <head> içinde <link rel="preload" as="font"> ile önceliklendirdik, CSP'den fonts.googleapis.com ve fonts.gstatic.com'u kaldırdık. Sonuç: LCP dökümündeki "öğe oluşturma gecikmesi" tamamen ortadan kalktı.
Gizli bir bug: elemanlar iki kez animasyonlanıyordu
Kod incelemesi sırasında ilginç bir şey bulduk: scroll-reveal animasyon script'i, aynı elemanları hem tekil döngüde hem grup (data-stagger) döngüsünde iki kez işliyordu. Servis satırları ve blog kartları çift animasyon tetikliyordu — görsel olarak fark edilmiyordu ama main thread'e gereksiz iş yüklüyordu.
Bu, "her şeyi kütüphaneyle çöz" yaklaşımının bir tuzağı: GSAP ScrollTrigger'ın kendi scroll-polling maliyeti sürekli main thread'i meşgul ediyordu, Total Blocking Time'a "uzun görev" olarak yansıyordu. Çözüm ScrollTrigger'ı tamamen kaldırıp scroll-reveal mantığını native IntersectionObserver + CSS transition'a taşımaktı. Kütüphaneyi tamamen sildik — dosya hem repodan hem sunucudan gitti.
TBT için görev bölme
Sayfa yüklenirken çalışan JS başlatma sekansları (cursor takibi, hover efektleri, partikül canvas'ı, skyline reveal) tek büyük bir görev olarak çalışıyordu. Lighthouse 50ms üstü her görevi TBT'ye yazıyor; tek büyük görev yerine bunları zincirleme requestAnimationFrame çağrılarıyla ayrı frame'lere böldük. Kritik olmayan hiçbir şey artık ilk frame'i bloklamıyor.
Kontrast düzeltmeleri (WCAG AA)
Erişilebilirlik skorunu 95'ten 100'e taşıyan şey kontrast oranlarıydı: birincil buton arka planı biraz koyulaştırıldı (kontrast 3.75 → 5.44), hero ve footer'daki kayan yazı metinlerinin rengi güncellendi (2.97 → 4.71). Bonus bulgu: CSS dosyasının en üstünde unutulmuş bir @import url(fonts.googleapis...) satırı, font self-host çalışmamızı sessizce geçersiz kılıyordu — silinince fark hemen görüldü.
Yapmadığımız bir şey: kritik CSS'i inline etmek
Render-blocking CSS uyarısını (zaten puanlanmayan, 150ms'lik bir uyarı) tamamen sıfırlamanın yolu kritik CSS'i <head> içine inline etmekti. Bilinçli olarak yapmadık — çok sayfalı bir sitede bu, CSS'in sayfalar arası tarayıcı cache'inde paylaşılmasını engeller. Puanlanmamış bir uyarı için gerçek bir performans avantajından vazgeçmek mantıklı değildi.
Çıkarımlar
- En büyük kazanç genelde en az beklediğin yerden gelir. Burada üçüncü parti font CDN'i, tahmin edilenden çok daha büyük bir maliyetti.
- Kütüphaneler ücretsiz değildir. ScrollTrigger'ın kendi maliyeti, çözdüğü sorunun (basit scroll-reveal) karmaşıklığına değmiyordu.
- Yerel ölçüm gürültülüdür. Aynı makinede art arda taramalar 29 ile 42 arasında sıçrayabiliyor — kesin rakam her zaman gerçek Google PSI sunucusundaki tarama.
- Kontrast, erişilebilirlik skorunun çoğu zaman tamamı demek. İki renk değişikliği 95'i 100 yaptı.
PageSpeed 100 bir amaç değil, bir belirti. Buradaki her düzeltme aynı zamanda gerçek kullanıcının daha hızlı gördüğü, daha az veri indirdiği, daha az pil harcayan bir site anlamına geliyor. Kendi sitenizde benzer bir iyileştirme yapmak isterseniz, bize yazın — bu süreci sizin altyapınızda da uygularız.