Merhaba arkadaşlar, bugün başımı çok ağrıtan bir sorunu ve nasıl çözdüğümü anlatacağım. Bir Next.js projesinde Google Fonts kullanıyordum ve Lighthouse skorlarımda "Reduce unused CSS" ve "Ensure text remains visible during webfont load" uyarıları canımı sıkıyordu. `next/font` modülünü kullanmaya başladığımda ise, fontların tam olarak optimize edilmediğini, bazen FOUT (Flash of Unstyled Text) yaşadığımı fark ettim. İşte benim bulduğum en temiz çözüm.
Sorunun Kökeni: Font Dosyaları ve Preload
`next/font` otomatik olarak fontları preload eder ve inline CSS olarak enjekte eder. Ancak, özellikle birden fazla font ağırlığı (weight) veya stil (italic) kullandığınızda, tüm varyantların yüklenmesini beklemek "ilk anlamlı çizim" (FCP) süresini uzatabiliyordu. Font tanımınız global bir CSS dosyasında (`globals.css`) yapılıyorsa, bu dosyanın yüklenip parse edilmesi de ekstra bir adım oluşturuyor.
Çözüm: Stratejik Import ve Variable Fontlar
İlk adım olarak, mümkün olduğunca "variable font" kullanmaya karar verdim. Variable fontlar, tek bir dosyada birçok ağırlık ve stili barındırarak HTTP istek sayısını ciddi oranda azaltıyor.
İkinci ve en kritik adım ise, fontu doğrudan kullanacağım layout veya component içerisinden import etmek oldu. Böylece font tanımı ve preload bağlantısı, o sayfaya özel hale geliyor ve gereksiz global yükten kurtuluyor.
Ekstra Performans Hamlesi: Fallback'leri Özelleştir
`adjustFontFallback: false` ayarını yapmak, Next.js'in otomatik oluşturduğu fallback font CSS kurallarını kaldırır. Bu, küçük de olsa inline CSS boyutunu azaltır. Ancak, bu durumda kendiniz manuel bir fallback stratejisi belirlemelisiniz. Ben `font-display: swap` ile zaten metnin hemen görüneceğini garanti altına aldığım için bu riski aldım.
Eğer farklı bir component'ta özel bir font kullanmanız gerekiyorsa, onu da aynı component içinde tanımlayabilirsiniz. Bu, fontun sadece o component ihtiyaç duyulduğunda yüklenmesini sağlar.
Bu yöntemleri uyguladıktan sonra, projemdeki "Cumulative Layout Shift" (CLS) tamamen sıfırlandı ve "First Contentful Paint" (FCP) süresinde gözle görülür bir iyileşme oldu. Font optimizasyonu, küçük gibi görünen ama toplam kullanıcı deneyimine büyük etki eden bir detay.
Siz Next.js projelerinizde font yükleme performansı için farklı taktikler denediniz mi? `next/font` dışında bir paket veya manuel bir yöntem kullanan var mı? Yorumlarda deneyimlerinizi paylaşın!
`next/font` otomatik olarak fontları preload eder ve inline CSS olarak enjekte eder. Ancak, özellikle birden fazla font ağırlığı (weight) veya stil (italic) kullandığınızda, tüm varyantların yüklenmesini beklemek "ilk anlamlı çizim" (FCP) süresini uzatabiliyordu. Font tanımınız global bir CSS dosyasında (`globals.css`) yapılıyorsa, bu dosyanın yüklenip parse edilmesi de ekstra bir adım oluşturuyor.
İlk adım olarak, mümkün olduğunca "variable font" kullanmaya karar verdim. Variable fontlar, tek bir dosyada birçok ağırlık ve stili barındırarak HTTP istek sayısını ciddi oranda azaltıyor.
İkinci ve en kritik adım ise, fontu doğrudan kullanacağım layout veya component içerisinden import etmek oldu. Böylece font tanımı ve preload bağlantısı, o sayfaya özel hale geliyor ve gereksiz global yükten kurtuluyor.
JavaScript:
// app/layout.jsx veya app/layout.tsx
import { Inter } from 'next/font/google';
// Variable font olarak Inter'ı tanımla
const inter = Inter({
subsets: ['latin', 'latin-ext'],
display: 'swap', // Font yüklenirken metnin görünür kalmasını sağla
adjustFontFallback: false, // Gereksiz fallback CSS'ini devre dışı bırak
});
export default function RootLayout({ children }) {
return (
<html lang="tr" className={inter.className}>
<body>{children}</body>
</html>
);
}
`adjustFontFallback: false` ayarını yapmak, Next.js'in otomatik oluşturduğu fallback font CSS kurallarını kaldırır. Bu, küçük de olsa inline CSS boyutunu azaltır. Ancak, bu durumda kendiniz manuel bir fallback stratejisi belirlemelisiniz. Ben `font-display: swap` ile zaten metnin hemen görüneceğini garanti altına aldığım için bu riski aldım.
Eğer farklı bir component'ta özel bir font kullanmanız gerekiyorsa, onu da aynı component içinde tanımlayabilirsiniz. Bu, fontun sadece o component ihtiyaç duyulduğunda yüklenmesini sağlar.
JavaScript:
// components/HeroBanner.jsx
import { Playfair_Display } from 'next/font/google';
const playfair = Playfair_Display({
subsets: ['latin'],
weight: ['700'], // Sadece ihtiyacım olan kalın ağırlığı yükle
display: 'swap',
});
export default function HeroBanner() {
return (
<h1 className={playfair.className}>
Şık ve Hızlı Başlık
</h1>
);
}
Bu yöntemleri uyguladıktan sonra, projemdeki "Cumulative Layout Shift" (CLS) tamamen sıfırlandı ve "First Contentful Paint" (FCP) süresinde gözle görülür bir iyileşme oldu. Font optimizasyonu, küçük gibi görünen ama toplam kullanıcı deneyimine büyük etki eden bir detay.
Siz Next.js projelerinizde font yükleme performansı için farklı taktikler denediniz mi? `next/font` dışında bir paket veya manuel bir yöntem kullanan var mı? Yorumlarda deneyimlerinizi paylaşın!