Web sitesini yavaşlatan 8 yaygın hata ve her birinin düzeltmesi
Yavaş bir sitede sorun neredeyse hiçbir zaman tek bir büyük hata olmuyor. Birkaç yıl içinde eklenmiş eklentiler, "şimdilik böyle kalsın" denmiş görseller, pazarlama ekibinin eklediği etiketler üst üste biniyor. İyi haber şu: bu hataların çoğu tekrar eden kalıplar ve düzeltmeleri de belli.
Aşağıdaki listede sitelerde en sık görülen hatalar toplandı. Örneklerin bir kısmı portföyümdeki kurumsal site hız çalışmasından: 2018 tarzı bir WordPress temasını aynı içerikle yeniden kurup iki sürümü ölçtüğüm proje. Metriklerin kendisini (LCP, INP, CLS) ayrı bir yazıda anlattım; burada odak hatalarda.
Ağır ve yanlış sırayla yüklenen dosyalar
1. Telefona masaüstü boyutunda görsel göndermek
En yaygın ve en kolay düzeltilen hata. 4000 px genişliğinde, 3 MB'lık bir fotoğraf yüklenir, CSS onu 360 px'e küçültür, telefon yine de 3 MB'ı indirir. Lojistik firması sitesinin eski sürümünde 1600 px JPEG'ler (her biri yaklaşık 300 KB) hem slider'da hem galeride kullanılıyordu; sayfa toplamda 3,6 MB taşıyordu.
Düzeltme: her görselin birkaç genişlikte kopyasını üretin, modern formatlara (AVIF, WebP) çevirin, srcset ve sizes ile tarayıcıya seçim yaptırın. Ekranın altında kalanlara loading="lazy" ekleyin. Bu konuyu görsel optimizasyonu yazısında ayrıntılı anlattım; burada sadece şunu söyleyeyim: görsel neredeyse her sitede ağırlığın en büyük kalemi, ilk bakılacak yer burası.
2. Render'ı engelleyen CSS ve JavaScript
Tarayıcı <head> içindeki her stil dosyasını indirip işlemeden sayfayı çizmez. defer ya da async olmayan her <script> da HTML ayrıştırmasını durdurur. Lojistik firması sitesinin eski sürümünde <head> bölümünde 6 bloklayıcı stil dosyası ve 4 senkron betik vardı: jQuery, jQuery Migrate, slider ve WordPress'in emoji betiği. Stil dosyalarından biri başka dosyaları @import ile çağırıyordu; bu da tarayıcının önce bir dosyayı indirip içinde ne olduğunu gördükten sonra diğerini istemesi demek, yani sıralı bir bekleme zinciri.
Lighthouse bu sayfa için "kullanılmayan CSS'i azalt" fırsatını yaklaşık 4,7 saniye, "kullanılmayan JavaScript'i azalt" fırsatını yaklaşık 2,3 saniye olarak tahmin ediyordu. Yani indirilen kodun büyük kısmı o sayfada hiç kullanılmıyordu.
Düzeltme:
@importkullanmayın; gerekiyorsa dosyaları derleme aşamasında birleştirin.- İlk ekranı çizmek için gereken stili satır içine alın, gerisini sonradan yükleyin. Bu projede sayfanın tüm stili 5 KB satır içi CSS'e sığdı.
- Betiklere
deferekleyin. Yalnızca birkaç satırlık iş için jQuery yüklemeyin. - Eklentilerin her sayfaya bastığı dosyaları gözden geçirin. İletişim formu eklentisinin stili, formun olmadığı sayfalarda da yükleniyor olabilir.
Lojistik firması sitesinde 1,2 MB'lık bloklayıcı CSS ve JavaScript kaldırıldı, geriye defer ile yüklenen 0,5 KB'lık tek bir betik kaldı.
3. Fontları yanlış formatta ve yanlış biçimde yüklemek
TTF ya da OTF dosyalarını web'de doğrudan kullanmak hâlâ çok yaygın. Aynı sitenin eski sürümünde 3 TTF dosyası toplam 1,3 MB civarındaydı ve font-display tanımı yoktu; font inene kadar metin görünmüyordu.
Düzeltme:
@font-face {
font-family: Inter;
src: url(/fonts/inter-400.woff2) format("woff2");
font-weight: 400;
font-display: swap;
}
<link rel="preload" as="font" type="font/woff2"
href="/fonts/inter-700.woff2" crossorigin>
- woff2 kullanın. Bütün modern tarayıcılar destekliyor ve TTF'ye göre çok daha küçük.
- Alt küme (subset) alın. Türkçe site için latin ve latin-ext yeterli; Kiril ya da Yunan karakterlerini taşımanıza gerek yok.
- Gerçekten kullandığınız ağırlıkları yükleyin. Beş ağırlık yerine iki ağırlık çoğu site için yeterli.
- En önemli ağırlığı preload edin. Font preload'unda
crossoriginözniteliği aynı alan adında bile gerekli; unutursanız font iki kez iner.
Lojistik firması sitesinde bu adımlarla 1,3 MB'lık font yükü 70 KB'a indi (latin-ext, 2 ağırlık).
Başkasının kodu ve açılışta çalışan betikler
4. Üçüncü parti script'leri düşünmeden eklemek
Canlı sohbet balonu, ısı haritası aracı, üç farklı analitik etiketi, sosyal medya pikselleri, gömülü YouTube videosu. Her biri tek satır kodla ekleniyor ama arkasında onlarca istek ve yüzlerce KB JavaScript getirebiliyor. Üstelik bu kodu siz kontrol etmiyorsunuz; sağlayıcı yarın dosyayı büyütürse siteniz yavaşlar.
Düzeltme:
- Envanter çıkarın. Chrome DevTools'ta Network sekmesinde üçüncü parti alan adlarına göre filtreleyin, her birinin ne işe yaradığını ve hâlâ kullanılıp kullanılmadığını sorun. Kimsenin bakmadığı bir ısı haritası aracı en kolay kazanılan puandır.
- Gömülü videolar için "cephe" (facade) kullanın: sayfada yalnızca önizleme görseli ve oynat düğmesi dursun, oyuncu tıklanınca yüklensin.
- Sohbet balonunu sayfa açılışında değil, kullanıcı etkileşiminde ya da sayfa tamamen yüklendikten sonra başlatın.
- Etiket yöneticisi kullanıyorsanız içine eklenenleri düzenli temizleyin; zamanla unutulmuş etiketlerle dolar.
// Sohbet aracını ilk etkileşimde, bir kez yükle
let yuklendi = false;
const yukle = () => {
if (yuklendi) return;
yuklendi = true;
const s = document.createElement('script');
s.src = 'https://sohbet-saglayici.example/widget.js';
s.async = true;
document.body.appendChild(s);
};
['pointerdown', 'keydown', 'scroll'].forEach((olay) =>
addEventListener(olay, yukle, { once: true, passive: true })
);
Kullanıcı sayfayla hiç etkileşime girmezse sohbet aracı hiç yüklenmez; zaten ona ihtiyacı yoktu.
5. Açılışta ana iş parçacığını kilitleyen kod
Slider başlatma, animasyon kütüphaneleri, açılış popup'ları. Bunların ortak özelliği sayfa açılır açılmaz çalışıp tarayıcıyı meşgul etmeleri. Lojistik firması sitesinin eski sürümünde 600 ms boyunca ana iş parçacığını kilitleyen bir başlangıç betiği ve bir açılış popup'ı vardı. İkisi kaldırıldı ve Total Blocking Time sıfıra indi. Bir işlevin sayfa açıldığı anda gerçekten gerekip gerekmediğini sormak, çoğu zaman onu optimize etmekten daha fazla kazandırıyor.
Sunucu, gözden kaçan ayrıntılar ve takip
6. Sunucuda sıkıştırma ve önbellek olmaması
HTML, CSS ve JavaScript metin dosyaları; sıkıştırıldığında boyutları ciddi oranda düşer. Yine de sıkıştırması kapalı sunucular hâlâ çok yaygın. Aynı şekilde önbellek başlığı olmayan varlıklar her ziyarette yeniden indirilir.
Lojistik firması sitesinin yeni sürümünde sunucu şu kurallarla çalışıyor:
| Dosya | Cache-Control | Neden |
|---|---|---|
| HTML | no-cache | Her ziyarette sunucuya sorulsun, içerik güncel kalsın |
| CSS, JS, görsel, font | public, max-age=31536000, immutable | Bir yıl boyunca tekrar indirilmesin |
Metin dosyaları Brotli ile sıkıştırılıyor. Bir yıllık immutable önbellek yalnızca dosya adları sürümlüyse güvenli; dosyayı değiştirdiğinizde adı da değişmeli (site.3f2a.js gibi), yoksa kullanıcılar eski dosyayı görmeye devam eder. Next.js, Vite gibi araçlar bunu zaten yapıyor.
7. Küçük ama sürekli tekrar eden hatalar
Aynı sitenin eski sürümünde favicon.ico her ziyarette 404 veriyordu. Tek başına sayfayı yavaşlatmaz, ama her ziyarette boşa giden bir istek ve sunucu günlüğünde gürültü demek. Benzer şekilde kırık bağlantılar, yönlendirme zincirleri (http → https → www → sondaki eğik çizgi) ve hiç kullanılmayan eklentiler de birikerek siteyi ağırlaştırıyor. Yönlendirme zincirlerini tek adıma indirmek, özellikle mobilde her adımın maliyetli olduğu düşünülürse, kolay bir kazanç.
8. Düzelttikten sonra takip etmemek
Hız bir kere düzeltilip bırakılan bir şey değil. Yeni bir kampanya görseli, yeni bir eklenti ya da yeni bir etiket haftalar içinde her şeyi geri alabilir. Kurumsal site hız çalışmasında bunun için bir performans bütçesi tanımladım: LCP ≤ 2,5 sn, CLS ≤ 0,1, toplam sayfa ≤ 300 KB, JavaScript ≤ 5 KB, font ≤ 80 KB gibi sınırlar ve bunları denetleyen 24 kurallık bir kontrol betiği. Her değişiklikte çalışacak şekilde tasarlandı; bir sınır aşılırsa kontrol başarısız oluyor.
Bu düzeltmelerin toplam etkisi bu projede şöyle: ziyaret başına aktarılan veri yaklaşık 3,7 MB'tan 111 KB'a indi, 100 bin ziyaretteki trafik hesabı 355 GB'tan 11 GB'a düştü. Aynı makinedeki yük testinde (25 eşzamanlı ziyaretçi) saniyede sunulan sayfa sayısı yaklaşık 9–10 kat arttı. Hızlı site sadece kullanıcıya değil, sunucu faturasına da yansıyor.
Nereden başlamalı?
- PageSpeed Insights'ta mobil raporu açın, "fırsatlar" listesindeki ilk üç maddeye bakın.
- Network sekmesinde sayfayı boyuta göre sıralayın; en ağır beş dosya genellikle hikâyeyi anlatır.
- Üçüncü parti alan adlarını listeleyin, gereksiz olanları çıkarın.
- Sunucu yanıtlarında
content-encodingvecache-controlbaşlıklarını kontrol edin. - Bir bütçe belirleyin ve her yayından önce ölçün.
Siteniz bu listedeki maddelerin birkaçına takılıyorsa ve nereden başlayacağınızı bilemiyorsanız bana yazabilirsiniz.