Bir siteyi açtığınızda metnin önce görünmeyip yarım saniye sonra "pat" diye belirmesi ya da önce sistem fontuyla gelip sonra tasarımın fontuna atlaması, neredeyse her zaman aynı sebepten olur: web font yükleme optimizasyonu yapılmamıştır. Yazı tipleri, tarayıcının metni ekrana basmadan önce beklediği ender kaynaklardandır; bu yüzden birkaç yüz kilobaytlık bir font dosyası, aslında hızlı olan bir sayfayı görsel olarak yavaş gösterebilir. Üstelik bu gecikme Core Web Vitals ölçümlerinde doğrudan LCP ve CLS puanınıza yansır.
Bu rehberde fontların tarayıcı tarafından nasıl keşfedildiğini, hangi formatın gerçekten gerekli olduğunu, Türkçe karakterleri kaybetmeden dosya boyutunu nasıl yarıya indireceğinizi, preload ile kritik fontu nasıl öne alacağınızı ve hangi durumda fontu tamamen bırakmanın daha doğru olduğunu anlatacağım. Örnekler gerçek CSS ve HTML kodu; kopyalayıp kendi projenize uyarlayabilirsiniz.
Web Fontları Neden Sayfayı Yavaşlatır#
Fontun yavaşlatıcı olmasının sebebi boyutundan çok, keşfedilme zamanıdır. Tarayıcı HTML'i indirir, içindeki CSS dosyasını görür, onu indirir, ayrıştırır ve ancak @font-face bloğunu okuduktan sonra font dosyasını istemeye başlar. Yani font isteği, kritik yolun en az üçüncü adımında doğar. Buna bir de CSS'in render engelleyici olması eklenince, metnin ekranda görünmesi kolayca 800-1200 ms gecikebilir.
İkinci sorun, tarayıcının bu bekleme sırasında ne yapacağıdır. Varsayılan davranış çoğu tarayıcıda "block" periyodudur: font gelene kadar metin hiç çizilmez. Buna FOIT (Flash of Invisible Text) denir. Alternatifi FOUT'tur (Flash of Unstyled Text): metin önce yedek fontla çizilir, font gelince değişir. İkisi de kullanıcı deneyimini bozar ama FOIT çok daha zararlıdır, çünkü sayfanın en önemli öğesi olan başlık boş kalır ve LCP ölçümü doğrudan bundan etkilenir. Bu davranışı kontrol eden ayar font-display özelliğidir; ayrıntısını font-display: swap kullanımı yazısında bulabilirsiniz.
Üçüncü ve en sinsi maliyet, üçüncü taraf bağlantılarıdır. Google Fonts gibi harici bir kaynak kullandığınızda tarayıcı yeni bir alan adına DNS çözümlemesi, TCP el sıkışması ve TLS anlaşması yapmak zorunda kalır. Bu üçlü, hızlı bir bağlantıda bile 100-300 ms ek maliyet demektir ve font dosyası daha indirilmeye başlamamıştır bile.
Doğru Format: Sadece WOFF2#
Yıllar önce her tarayıcı için ayrı format sunmak zorunluydu; EOT, TTF, SVG ve WOFF'u üst üste yığan @font-face blokları hâlâ eski temalarda karşımıza çıkıyor. Bugün bu tamamen gereksiz. WOFF2, Brotli tabanlı sıkıştırma kullanır ve aynı fontun TTF haline göre ortalama %30-50 daha küçüktür. Modern tarayıcıların tamamı destekler.
Aşağıdaki tablo aynı bir metin fontunun farklı formatlardaki tipik büyüklüklerini karşılaştırıyor; kesin rakamlar fonta göre değişir ama oranlar tutarlıdır:
| Format | Tipik boyut | Desteklendiği yerler | Kullanmalı mısın |
|---|---|---|---|
| TTF / OTF | En büyük | Her yerde | Hayır, web için değil |
| WOFF | Orta | Eski tarayıcılar dahil | Genellikle gereksiz |
| WOFF2 | En küçük | Tüm modern tarayıcılar | Evet, tek başına yeterli |
| EOT / SVG | Değişken | Ölü formatlar | Kesinlikle hayır |
Bu yüzden @font-face bloğunuz tek satır kaynak içermelidir:
@font-face {
font-family: "Inter";
/* Sadece WOFF2 - başka format eklemeye gerek yok */
src: url("/fonts/inter-regular.woff2") format("woff2");
font-weight: 400;
font-style: normal;
font-display: swap;
}
Elinizde yalnızca TTF varsa dönüştürmek birkaç saniyelik iştir. Google'ın woff2 araçları çoğu dağıtımda paketlidir:
# Debian / Ubuntu üzerinde dönüştürücüyü kur
sudo apt install woff2
# TTF dosyasını WOFF2'ye çevir (yanına .woff2 üretir)
woff2_compress inter-regular.ttf
# Boyutları karşılaştır
ls -lh inter-regular.ttf inter-regular.woff2
Subset ile Gereksiz Karakterleri Atmak#
Bir font dosyasının içinde çoğu zaman Kiril, Yunan, Vietnamca ve yüzlerce sembol bulunur. Türkçe bir site için bunların hiçbirine ihtiyacınız yoktur. Subset, fonttan yalnızca kullandığınız karakter aralığını çıkarmak demektir ve tek başına dosyayı %60-80 küçültebilir. En sık kullanılan araç fonttools paketiyle gelen pyftsubset komutudur:
# Araç kurulumu (Brotli desteğiyle birlikte)
pip install "fonttools[woff]" brotli
# Latin + Türkçe karakterleri koruyarak subset al
pyftsubset inter-regular.ttf \
--output-file=inter-regular.woff2 \
--flavor=woff2 \
--layout-features="kern,liga" \
--unicodes="U+0000-00FF,U+0100-017F,U+0131,U+0130,U+011E,U+011F,U+015E,U+015F,U+2000-206F,U+20BA"
Buradaki unicode aralıklarının anlamı önemli: U+0000-00FF temel Latin ve ek Latin harfleri, U+0100-017F Latin Extended-A (Türkçe'nin ğ, ş, İ, ı harfleri burada), U+20BA ise Türk Lirası sembolüdür. --layout-features ile kerning ve ligatürleri korursunuz; bunları atarsanız metin gözle görülür şekilde kötüleşir.
Subset alırken en sık yapılan hata, Türk Lirası işaretini veya büyük İ harfini listeye eklemeyi unutmaktır. Bu durumda tarayıcı o tek karakter için yedek fonta düşer ve fiyat etiketlerinizde farklı bir yazı tipi belirir. Fontu kestikten sonra sitenizin en karakter yoğun sayfalarını gözle kontrol edin.
Fontu Kendi Sunucundan Servis Etmek#
Google Fonts'u doğrudan CDN'den çağırmak kolaydır ama iki bedeli vardır: ekstra bağlantı kurulumu ve KVKK açısından tartışmalı olan üçüncü taraf IP kaydı. Fontları kendi sunucunuzda barındırmak her iki sorunu da çözer ve genellikle daha hızlıdır, çünkü zaten kurulmuş HTTP/2 bağlantınızı yeniden kullanırsınız.
Kendi sunucunuzdan servis ederken önbellek başlıklarını doğru kurmak şarttır. Font dosyaları içeriği değişmeyen kaynaklardır; dosya adına bir sürüm ya da hash koyup bir yıllık immutable önbellek vermek en doğru yaklaşımdır:
# Font dosyaları için uzun süreli, değişmez önbellek
location ~* \.(woff2|woff)$ {
add_header Cache-Control "public, max-age=31536000, immutable";
add_header Access-Control-Allow-Origin "*";
access_log off;
try_files $uri =404;
}
Access-Control-Allow-Origin satırı gereklidir: fontlar CORS kurallarına tabidir ve farklı bir alt alan adından (örneğin static.firmaniz.com) servis ediliyorsa bu başlık olmadan tarayıcı fontu reddeder. Apache tarafında aynı işi .htaccess ile yaparsınız; genel önbellek kalıplarını .htaccess önbellek ve sıkıştırma yazısında derledik.
Bir uyarı: fontları Brotli veya Gzip ile tekrar sıkıştırmaya çalışmayın. WOFF2 zaten Brotli ile sıkıştırılmıştır; üstüne bir kat daha eklemek CPU harcar ve dosyayı bazen büyütür. Nginx yapılandırmanızdaki gzip_types listesinde font/woff2 varsa çıkarın.
preload ile Kritik Fontu Öne Almak#
Fontu kendi sunucunuza aldıktan sonraki en büyük kazanç, keşif zincirini kısaltmaktır. preload kaynak ipucu, tarayıcıya "CSS'i ayrıştırmayı bekleme, bu dosyayı şimdi indirmeye başla" der. Sayfanın ilk ekranında görünen tek bir font ağırlığı için kullanılır:
Bu satır head içinde, stil dosyasından önce yer almalıdır:
<link rel="preload" href="/fonts/inter-regular.woff2" as="font" type="font/woff2" crossorigin>
Üç ayrıntı burada kritiktir. Birincisi as="font" olmadan tarayıcı kaynağı doğru önceliklendiremez. İkincisi crossorigin niteliği, font kendi sunucunuzda olsa bile zorunludur; fontlar anonim modda istendiği için bu nitelik yoksa dosya iki kez indirilir. Üçüncüsü, preload edilen font 3 saniye içinde kullanılmazsa konsola uyarı düşer, bu da yanlış dosyayı öne aldığınızın işaretidir.
Kaç fontu preload etmelisiniz? Cevap neredeyse her zaman bir ya da iki. Her preload, bant genişliğini ilk ekranın diğer kaynaklarından çalar. Regular ve bold ağırlığı öne alın, italik ve ince varyantları normal akışta bırakın. Diğer kaynak ipuçlarının hangisinin ne zaman kullanılacağını preload, prefetch ve preconnect farkı yazısında ayrıntılı karşılaştırdık.
Değişken Font mu, Ayrı Dosyalar mı#
Değişken fontlar (variable fonts) tek dosyada tüm ağırlıkları taşır. Dört ayrı ağırlık kullanıyorsanız genellikle kazançlıdır; iki ağırlık kullanıyorsanız çoğu zaman zararlıdır, çünkü değişken dosya tek bir statik dosyadan büyüktür. Karar tablosu şöyle:
| Kullandığın ağırlık sayısı | Önerilen yaklaşım | Sebep |
|---|---|---|
| 1-2 ağırlık | Statik WOFF2 dosyaları | Değişken dosya gereksiz yere büyük |
| 3-4 ağırlık | Değişken font (subset alınmış) | Tek istek, toplam boyut daha küçük |
| Animasyonlu ağırlık geçişi | Değişken font | Statik dosyalarla mümkün değil |
Değişken font kullanacaksanız ağırlık aralığını da kısıtlayın; pyftsubset komutuna --variations bayrağı ile yalnızca ihtiyacınız olan eksen aralığını bırakabilirsiniz. Kullanmadığınız 100-300 arası ince ağırlıkları atmak dosyayı belirgin biçimde küçültür.
Sık Yapılan Hatalar#
Sahada en çok karşılaştığım font hatalarını sıraladım; hepsi dakikalar içinde düzelir ama fark edilmezse performans raporunuzu aylarca aşağı çeker.
- Tüm ağırlıkları yüklemek. Tasarımda yalnızca 400 ve 700 kullanılırken CSS'e 100'den 900'e dokuz ağırlık tanımlanmış olur. Her tanım ayrı bir dosya isteği demektir.
@importile font çağırmak. CSS içindeki@import url(...)satırı, tarayıcının fontu ancak dış CSS indikten sonra keşfetmesine yol açar; zinciri bir kat daha uzatır. Bunun yerine HTML'delinketiketi kullanın.- Yedek font listesini boş bırakmak.
font-family: "Inter";yazıp sonunasans-serifeklememek, font gelmezse tarayıcının varsayılan serif fontuna düşmesine ve tasarımın bozulmasına yol açar. - Yedek fontu metrik olarak eşleştirmemek. Yedek font ile asıl fontun x-yüksekliği çok farklıysa, font geldiğinde metin sıçrar ve CLS puanı bozulur.
size-adjustveascent-overrideözellikleri bu farkı kapatır. Düzen kaymasının genel çözümlerini CLS düzen kayması nasıl düzeltilir yazısında bulabilirsiniz. - İkon fontu kullanmak. Yalnızca birkaç simge için 50-100 KB'lık bir ikon fontu indirmek, aynı simgeleri satır içi SVG olarak koymanın yanında büyük israftır.
Yedek fontu metrik olarak hizalamak istiyorsanız yaklaşım şudur:
/* Asıl font gelene kadar kullanılacak, metriği ayarlanmış yedek */
@font-face {
font-family: "Inter Fallback";
src: local("Arial");
size-adjust: 107%; /* x-yüksekliğini asıl fonta yaklaştır */
ascent-override: 90%;
descent-override: 22%;
}
body {
font-family: "Inter", "Inter Fallback", system-ui, sans-serif;
}
Ölçüm: Fontun Gerçekten Yavaşlatıp Yavaşlatmadığı#
Tahminle optimizasyon yapmayın. Tarayıcının geliştirici araçlarında Network sekmesini açıp filtreyi Font yaparsanız, hangi dosyanın ne zaman istendiğini ve ne kadar sürdüğünü görürsünüz. Bakmanız gereken iki sayı vardır: isteğin başlama zamanı (keşif gecikmesi) ve süresi (boyut ve ağ maliyeti). Başlama zamanı 500 ms'nin üstündeyse sorununuz preload eksikliğidir; süre uzunsa sorununuz dosya boyutudur.
Aynı ölçümü sunucu tarafından da doğrulayın. Bir font dosyasının gerçekte kaç bayt indiğini ve önbellek başlıklarının uygulanıp uygulanmadığını görmek için:
# Font dosyasının başlıklarını ve boyutunu kontrol et
curl -sI https://firmaniz.com/fonts/inter-regular.woff2 \
| grep -Ei 'content-length|cache-control|content-encoding'
# Beklenen çıktı örneği:
# content-length: 24136
# cache-control: public, max-age=31536000, immutable
cache-control satırı yoksa tekrar eden ziyaretlerde font her seferinde yeniden indiriliyordur. Sayfa hızını bütünsel olarak ölçmek için GTmetrix ile WordPress hız testi yazısındaki yöntemi izleyebilir, LCP odaklı iyileştirmeler için de LCP nasıl iyileştirilir rehberine bakabilirsiniz.
Sıkça Sorulan Sorular#
Google Fonts kullanmak yerine fontu kendi sunucuma mı almalıyım#
Çoğu durumda evet. Kendi sunucunuzdan servis ettiğinizde ek DNS çözümlemesi, TCP el sıkışması ve TLS anlaşması maliyetlerinden kurtulur, mevcut HTTP/2 bağlantınızı yeniden kullanırsınız. Ayrıca ziyaretçinin IP adresi üçüncü tarafa gitmediği için KVKK açısından da daha rahat bir konumda olursunuz. Tek şart, önbellek başlıklarını doğru kurmanız ve WOFF2 formatını kullanmanızdır.
Kaç font dosyası yüklemek normaldir#
Pratik sınır iki aileden fazlasına çıkmamaktır ve toplam dört-beş dosyayı geçmemektir. Genellikle bir metin fontunun regular ve bold ağırlığı ile bir başlık fontu yeterlidir. Her ek ağırlık ayrı bir HTTP isteği ve ek bant genişliği demektir; tasarımda gerçekten kullanılmayan ağırlıkları CSS'ten silmek çoğu sitede tek başına 100 KB üzerinde kazanç sağlar.
Font subset almak Türkçe karakterleri bozar mı#
Doğru unicode aralıklarını verirseniz bozmaz. Türkçe için U+0100-017F aralığını mutlaka dahil edin; ğ, Ğ, ş, Ş, İ ve ı harfleri bu blokta yer alır. Ayrıca Türk Lirası sembolü için U+20BA kodunu eklemeyi unutmayın. Subset aldıktan sonra sitenizin fiyat listesi ve iletişim gibi karakter yoğun sayfalarını gözle kontrol edin; eksik bir karakter varsa hemen fark edilir.
preload eklediğim halde neden font hâlâ geç geliyor#
En yaygın sebep crossorigin niteliğinin eksik olmasıdır. Bu nitelik olmadan tarayıcı preload edilen dosyayı ayrı bir istek olarak kabul eder ve fontu ikinci kez indirir; sonuç hiç preload yapmamışsınız gibi olur. İkinci sebep, preload satırının stil dosyasından sonra yerleştirilmesidir. Üçüncü sebep ise yanlış dosyayı öne almanızdır; konsolda "preloaded but not used" uyarısı varsa yol veya ağırlık hatalıdır.
Değişken font her zaman daha mı iyidir#
Hayır. Değişken font, tek dosyada birçok ağırlık taşıdığı için üç veya daha fazla ağırlık kullanan projelerde kazançlıdır. Yalnızca regular ve bold kullanıyorsanız iki küçük statik WOFF2 dosyası neredeyse her zaman daha hafiftir. Karar vermeden önce her iki senaryonun toplam bayt maliyetini ölçün; tahminle seçilen değişken font çoğu küçük sitede boyutu artırır.
Font yüklenirken metnin kaybolmasını nasıl engellerim#
@font-face bloğuna font-display: swap ekleyin. Bu değer, font gelene kadar metnin yedek fontla çizilmesini sağlar; böylece görünmez metin dönemi ortadan kalkar. Yan etki olarak font geldiğinde küçük bir sıçrama olur; bunu da yedek fontun metriklerini size-adjust ile asıl fonta yaklaştırarak neredeyse tamamen yok edebilirsiniz.
Kapanış#
Font optimizasyonu, birkaç saatlik işle kalıcı kazanç sağlayan ender konulardan biridir. Aklınızda kalması gereken dört alışkanlık şunlar: yalnızca WOFF2 servis edin ve eski formatları CSS'ten silin; kullanmadığınız karakterleri ve ağırlıkları subset ile atın; ilk ekranda görünen tek fontu crossorigin niteliğiyle birlikte preload edin; font-display: swap ile görünmez metni tamamen ortadan kaldırın. Bu dördü uygulandığında tipik bir kurumsal sitede font kaynaklı gecikme 700-800 ms seviyesinden 100 ms'nin altına iner.
Fontlarınızı kendi sunucunuzdan servis etmek ve önbellek başlıklarını doğru kurmak istiyor ama yapılandırmayla uğraşmak istemiyorsanız Clou.TR bu işi devralabilir. LiteSpeed ve Brotli desteğiyle gelen web hosting ve WordPress hosting paketlerimizde statik kaynak önbelleği hazır gelir; tam kontrol isterseniz VDS sunucu üzerinde kendi Nginx yapılandırmanızı kurabilir, yapılandırmayı bize bırakmak isterseniz sunucu yönetimi hizmetimizden yararlanabilirsiniz.