Performans toplantılarında en sık düşülen tuzaklardan biri, geciken her dosyanın <link rel="..."> etiketleriyle işaretlenip tarayıcının ağ kuyruğuna (network queue) hesapsızca yığılmasıdır. Preload ve prefetch kavramları, sadece bir indirme direktifi değildir; aynı zamanda zamanlama kararıdır. İkisi de tarayıcıya "bu dosyayı indir" der, ancak verdikleri aciliyet ve kullandıkları bant genişliği stratejisi birbirinden belirgin biçimde ayrılır. Birbirine karıştırıldığında ne site hızlanır ne ağ trafiği rahatlar; sadece darboğazın yeri değişmiş olur.

Doğru yaklaşım kaba kuvvet değildir. Asıl odaklanılması gereken problem kaynağın "ne zaman" istendiğidir. İlgili veri o anda sayfanın boyanması için farz mıdır, yoksa 10 saniye sonra yaşanacak bir sekme geçişi için yedek akçe midir? Tarayıcıyı kendi lehine çalıştırmak isteyen her sistem, bu ikisi arasındaki ağ sırasını (network hierarchy) kati hatlarla ayırmak zorundadır.

Preload hangi durumda gerçekten gereklidir?

Preload (rel="preload"), tarayıcıya "HTML okumasını (parse) bekleme, bu kaynağa derhal ihtiyacım var, bunu her şeyden önce yüksek öncelikle (high priority) indir" talimatı verir. Ziyaretçinin ilk saniyede göreceği hero (ana) görsel veya Critical CSS kurgusunda sisteme entegre edilen hayati .woff2 fontlar bu sınıfa girer. Tarayıcı o emri aldığında diğer arka plan işlemlerini duraklatıp bütün TCP borusunu ona açar.

Prefetch (rel="prefetch") ise hiyerarşide tam ters köşede bekler. "Bu dosyaya şu an ihtiyacım yok, fakat kullanıcı başka bir butona tıkladığında isteyecek. Tarayıcı boşta (idle) bir zaman yakaladığında düşük öncelikle arkadan indir" manasına gelir. Bu yüzden prefetch, şu anki LCP skorunu iyileştirmez; ancak sonraki sayfanın interaksiyonunu güvence altına alır.

Bir e-ticaret sitesinde ürün detaylarındaki ilk görsel "preload" ile öne alınmalı; aynı lisedeki "benzer ürünler" geçişine ait kütüphane ise "prefetch" ile arkadan hazırlanmalıdır. Her iki etiketi aynı amaca veya farklı süreçlere bocalayarak atarsanız, donanımda bir trafik ışığı arızası yaratırsınız.

Preload ne zaman ters etki üretir?

İskelet kurgulanamadığında başvurulan ilk çaresizlik, fonttan JavaScript'e kadar ele geçen her ağırlığı preload etmektir. Bir HTTP/2 bağlantısında tarayıcıya ayni anda 15 farklı dosyayı "Bana hemen lazım" diye işaretlerseniz, tarayıcı hiçbirine acil davranmaz. Bütün aciller aslında rutine döner. Daha tehlikelisi; preload edilen 1 MB'lık bir izleme scripti (analytics), sitenin o anda ekrana çizeceği ana DOM inşasını bloke edip render döngüsünü felç edebilir.

Bunun somut ölçütü çok nettir: Kaynak ilk iki saniyede görsel bir çizimi birebir etkiliyor mu? Eğer yanıt negatifse, o dosyayı preload etmek ağ sırasındaki gerçek değerli kahraman görselleri arkaya atmaktır.

<!-- LCP'yi kurtaran doğru preload kullanımı -->
<link rel="preload" as="image" href="/hero-cover-1920.webp" fetchpriority="high">

<!-- LCP'yi katleden, ağ kuyruğunu felç eden aşırı kullanım -->
<link rel="preload" as="script" href="/analytics-tracker.js">
<link rel="preload" as="script" href="/support-chat.js"> 
<!-- Chat uygulamasını asil yük kabul etmek iskeleti çökertir -->

Prefetch gelecekteki yükü nasıl hazırlar?

Prefetch işlemi projenin canlı bellek ağacına (DOM) hemen karışmadığından risksiz bir strateji gibi okunabilir. Ancak asıl veri faturası mobil kullanıcı tarafında belirir. Bir haber sitesinde tıklanması ihtimal dahilindeki ilk 5 videoyu "prefetch" komutuyla arkadan hazırlatmaya kalkarsanız, cihaz ekranı okurken kullanmadığı 25 MB'lık veriyi de taşımış olur.

Ekipler genellikle testlerini sınırsız bant genişliklerinde laboratuvar (lighthouse) ortamında kurgular. Oysa 3G bandında hücresel verisiyle savaşan bir telefon, arkada dönen sonsuz prefetch döngüsü yüzünden o an üzerinde olduğu sayfanın AJAX paketlerini bile HTTP havuzuna sokmakta zorlanacaktır.

Prefetch kararı hissiyata değil saf metriğe dayanır. Kullanıcılar bir rotadan diğer rotaya geçişte %70 oranında spesifik bir butonu tercih ediyorsa o modül prefetch edilir. Kullanım oranı %5 olan alt sözleşme menüleri ise sisteme yüklenmez. Bunun yerine dynamic import bloğu hover anında (imleç yaklaştığında) kurgulanarak sadece kesin aksiyonlarda bant genişliği harcanır.

Font önceliklerindeki klasik CORS sendromu

Fontların önceden yüklenmesi pür dikkat gerektiren bir sunucu anlaşmasıdır. Projeye bir font dosyasını önden indirtmek istiyorsaniz, koda crossorigin öz niteliğini eklemek zorundasınızdır. Şayet bunu atlarsanız tarayıcı aynı .woff2 hücresini iki defa (double fetch) indirecektir. Bir defa anonim bir talep olarak, ikincisi ise orijinal font ayarından kaynaklı yetkilendirmeyle. Bu işlem ağ sekmesinde çok ciddi bir kırmızı kalem yemektir.

<!-- Fontlarda crossorigin ihmali double-fetch krizine sebep olur -->
<link rel="preload" href="/fonts/Inter-Regular.woff2" as="font" type="font/woff2" crossorigin>

Doğrulama için hangi ekranlara bakılır?

Tüm bu preload hamlelerinin gerçekten işe yaradığını doğrulamak için tek bir metrik okuması yetmez; Chrome Network Waterfall görünümüne de bakmak gerekir. Preload ile öne çektiğiniz dosya, HTML çözülmeden önce o şelalede yukarı tırmanmış olmalıdır. Hâlâ gecikiyorsa, sorun preload kararından çok sunucu protokollerinde veya bağlantı katmanında olabilir.

Nitelikli bir front-end geliştiricisi tarayıcıya komut verirken diktatörlük yapmaz; iskelete odaklanır, ikincil hamleleri boşluklara (TTFB sonrasına) yedirir.

Preconnect ve modulepreload ile çizgiyi netleştirmek gerekir

Preload ve prefetch kararları çoğu projede iki başka kavramla karışır: preconnect ve modulepreload. Preconnect bir dosyayı indirmez; yalnızca yeni bir origin'e yapılacak DNS, TCP ve TLS hazırlığını erkene çeker. Yani fonts ya da harici API gibi başka bir alan adına birazdan gidileceğini biliyorsanız, tarayıcıyı o bağlantı için önceden ısıtırsınız. Bu komut "kaynağı hemen getir" anlamına gelmez; sadece yol hazırlığı yapar. Bu yüzden preconnect ile preload aynı iş değildir.

Modulepreload ise klasik preload'un JavaScript modül ekosistemine daha yakın çalışan biçimidir. ES module kullanan yapılarda ana modülün yalnızca kendisini değil, onun bağımlılık ağını da erkenden tanıtmaya yarar. Büyük bir uygulamada ana giriş modülünüz kritikse, düz preload yerine modulepreload daha doğru davranış üretir. Çünkü tarayıcı modül zincirini daha tutarlı çözer. Buna karşılık nadir kullanılan bir rota paketini modulepreload ile öne almak, normal preload hatasının daha teknik bir sürümünü üretir: henüz gerekmeyen kod, ilk ağ bütçesine yük olur.

Tarayıcının verdiği uyarılar da karar kalitesini ele verir. DevTools içinde "preloaded but not used" uyarısı görüyorsanız, çoğu zaman gerçekten kritik olmayan bir kaynağı öne çekmişsinizdir. Özellikle font, video poster görseli veya route bazlı JavaScript dosyalarında bu uyarı sık görülür. Kaynak beş saniye sonra ya da bir sonraki sayfada kullanılacaksa, preload değil prefetch veya yalnızca doğal yükleme daha doğru olabilir. Bu uyarıları görmezden gelmek, öncelik sırasını kağıt üzerinde düzeltip sahada bozmak anlamına gelir.

Sağlıklı karar matrisi şudur: İlk ekrandaki görünüm için zorunluysa preload, başka bir origin'e birazdan gidilecekse preconnect, modül zinciri hemen başlayacaksa modulepreload, sonraki olası gezinti için hazırlanıyorsa prefetch. Bu ayrımı net kurduğunuzda tarayıcıyla kavga etmeyi bırakıp onun öncelik sistemiyle uyumlu çalışırsınız. Asıl kazanç da burada oluşur; aynı kaynağa daha fazla komut vermek değil, doğru kaynağa doğru zamanda doğru sinyali vermek.

Mobil kullanıcı tarafında bu kararın bir de veri bütçesi boyutu vardır. Sınırlı bağlantıda çalışan tarayıcılar bazen güç tasarrufu veya veri tasarrufu modları nedeniyle düşük öncelikli istekleri farklı davranışla ele alır. Yani masaüstünde "zararsız" görünen bir prefetch akışı, telefonda gereksiz indirme yükü yaratabilir. Bu yüzden route tahmini zayıf olan ekranlarda otomatik prefetch yağmuru başlatmak yerine, gerçekten yüksek geçiş olasılığı olan adımları seçmek daha güvenlidir.