HTTP Önbelleği ile gereksiz ağ isteklerini önleme

Ağ üzerinden kaynak getirme işlemi hem yavaş hem de pahalıdır:

  • Büyük yanıtlar, tarayıcı ile sunucu arasında çok sayıda gidiş geliş gerektirir.
  • Sayfanız, tüm kritik kaynakları tamamen indirilene kadar yüklenmez.
  • Sitenize sınırlı mobil veri planıyla erişen bir kullanıcı için her gereksiz ağ isteği, parasının boşa harcanmasına neden olur.

Gereksiz ağ isteklerinden nasıl kaçınabilirsiniz? Tarayıcının HTTP önbelleği, ilk savunma hattınızdır. Bu yöntem her zaman en güçlü veya en esnek yaklaşım olmayabilir ve önbelleğe alınan yanıtların ömrü üzerinde sınırlı kontrole sahip olursunuz. Ancak bu yöntem etkilidir, tüm tarayıcılarda desteklenir ve fazla çalışma gerektirmez.

Bu kılavuzda, etkili bir HTTP önbelleğe alma uygulamasının temelleri gösterilmektedir.

Tarayıcı uyumluluğu

Aslında HTTP önbelleği adı verilen tek bir API yoktur. Web platformu API'lerinin koleksiyonunun genel adıdır. Aşağıdaki API'ler tüm tarayıcılarda desteklenir:

Cache-Control

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Source

ETag

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Source

Last-Modified

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Source

HTTP önbelleği nasıl çalışır?

Tarayıcının gönderdiği tüm HTTP istekleri, isteği yerine getirmek için kullanılabilecek geçerli bir önbelleğe alınmış yanıt olup olmadığını kontrol etmek üzere önce tarayıcı önbelleğine yönlendirilir. Eşleşme varsa yanıt önbellekten okunur. Bu sayede hem ağ gecikmesi hem de aktarımın neden olduğu veri maliyetleri ortadan kaldırılır.

HTTP önbelleği, istek üstbilgilerinin ve yanıt üstbilgilerinin bir kombinasyonuyla kontrol edilir. İdeal bir senaryoda hem web uygulamanızın kodu (istek başlıklarını belirleyen) hem de web sunucunuzun yapılandırması (yanıt başlıklarını belirleyen) üzerinde kontrol sahibi olursunuz.

Kavramsal olarak daha ayrıntılı bir genel bakış için MDN'nin HTTP Önbelleğe Alma makalesine bakın.

İstek üst bilgileri: Varsayılanları kullanın (genellikle)

Web uygulamanızın giden isteklerine dahil edilmesi gereken bazı önemli üstbilgiler vardır ancak tarayıcı, istek gönderirken bunları sizin adınıza ayarlama konusunda neredeyse her zaman sorumluluk alır. If-None-Match ve If-Modified-Since gibi yenilik kontrolünü etkileyen istek üstbilgileri, tarayıcının HTTP önbelleğindeki mevcut değerleri nasıl anladığına bağlı olarak görünür.

Bu iyi bir haber. HTML'nize <img src="my-image.png"> gibi etiketler eklemeye devam edebilirsiniz. Tarayıcı, ek çaba harcamadan HTTP önbelleğe alma işlemini sizin için otomatik olarak yapar.

Yanıt üstbilgileri: Web sunucunuzu yapılandırma

HTTP önbelleğe alma ayarının en önemli kısmı, web sunucunuzun her giden yanıta eklediği üstbilgilerdir. Aşağıdaki üstbilgilerin tümü etkili önbelleğe alma davranışını etkiler:

  • Cache-Control. Tarayıcı ve diğer ara önbelleklerin tek bir yanıtı nasıl ve ne kadar süreyle önbelleğe almasını belirtmek için sunucu bir Cache-Control yönergesi döndürebilir.
  • ETag. Tarayıcı, süresi dolmuş bir önbelleğe alınmış yanıt bulduğunda, dosyanın değişip değişmediğini kontrol etmek için sunucuya küçük bir jeton (genellikle dosyanın içeriğinin karması) gönderebilir. Sunucu aynı jetonu döndürüyorsa dosya aynıdır ve yeniden indirmeniz gerekmez.
  • Last-Modified: Bu üstbilgi, ETag ile aynı amaca hizmet eder ancak bir kaynağın değişip değişmediğini belirlemek için ETag'ın içerik tabanlı stratejisinin aksine zamana dayalı bir strateji kullanır.

Bazı web sunucularında bu üstbilgilerin varsayılan olarak ayarlanması için yerleşik destek bulunur. Diğerlerinde ise açıkça yapılandırmadığınız sürece üstbilgiler tamamen atlanır. Başlıkları nasıl yapılandıracağınızla ilgili ayrıntılar, kullandığınız web sunucusuna göre büyük ölçüde değişir. En doğru ayrıntıları almak için sunucunuzun dokümanlarına bakmanız gerekir.

Arama yapmanıza gerek kalmaması için birkaç popüler web sunucusunu yapılandırmayla ilgili talimatları aşağıda bulabilirsiniz:

Cache-Control yanıt başlığı çıkarılırsa HTTP önbelleğe alma devre dışı bırakılmaz. Bunun yerine tarayıcılar, belirli bir içerik türü için en uygun önbelleğe alma davranışını etkili bir şekilde tahmin eder. Bu tekliflerden daha fazla kontrol sahibi olmak istiyorsanız yanıt başlıklarınızı yapılandırmaya zaman ayırın.

Hangi yanıt üstbilgi değerlerini kullanmalısınız?

Web sunucunuzun yanıt üstbilgilerini yapılandırırken dikkate almanız gereken iki önemli senaryo vardır.

Sürümlü URL'ler için uzun ömürlü önbelleğe alma

Sunucunuzun tarayıcılara bir CSS dosyasını 1 yıl boyunca önbelleğe almasını (Cache-Control: max-age=31536000) söylediğini, ancak tasarımcınızın hemen dağıtmanız gereken acil bir güncelleme yaptığını varsayalım. Tarayıcıları, dosyanın "güncel olmayan" önbelleğe alınmış kopyasını güncellemeleri için nasıl bilgilendirirsiniz? En azından kaynağın URL'sini değiştirmeden bunu yapamazsınız.

Tarayıcı yanıtı önbelleğe aldıktan sonra, önbelleğe alınan sürüm max-age veya expires tarafından belirlendiği şekilde artık güncel olmadığı veya başka bir nedenle önbellekten çıkarılana (ör. kullanıcının tarayıcı önbelleğini temizlemesi) kadar kullanılır. Sonuç olarak, sayfa oluşturulduğunda farklı kullanıcılar dosyanın farklı sürümlerini kullanabilir: Kaynağı yeni getirmiş olan kullanıcılar yeni sürümü kullanırken, daha önceki (ancak hâlâ geçerli) bir kopyayı önbelleğe alan kullanıcılar yanıtın eski bir sürümünü kullanır.

İki dünyanın da en iyi özelliklerinden (istemci tarafı önbelleğe alma ve hızlı güncellemeler) nasıl yararlanabilirsiniz? Kaynağın URL'sini değiştirir ve içeriği değiştiğinde kullanıcıyı yeni yanıtı indirmeye zorlarsınız. Bunu genellikle dosyanın parmak izini veya sürüm numarasını dosya adına ekleyerek yaparsınız (örneğin, style.x234dff.css).

"Parmak izi" veya sürüm bilgileri içeren ve içeriğinin hiçbir zaman değişmemesi amaçlanan URL'lerle ilgili isteklere yanıt verirken yanıtlarınıza Cache-Control: max-age=31536000 ekleyin.

Bu değerin ayarlanması, tarayıcıya önümüzdeki bir yıl içinde (31.536.000 saniye; desteklenen maksimum değer) herhangi bir zamanda aynı URL'yi yüklemesi gerektiğinde web sunucunuza ağ isteği göndermek zorunda kalmadan HTTP önbelleğindeki değeri hemen kullanabileceğini bildirir. Bu harika. Ağı kullanmamanın sağladığı güvenilirlik ve hızı hemen elde ettiniz.

Webpack gibi derleme araçları, öğe URL'lerinize karma parmak izi atama işlemini otomatikleştirebilir.

Sürümlenmemiş URL'ler için sunucu yeniden doğrulaması

Maalesef yüklediğiniz URL'lerin tümü sürümlü değildir. Web uygulamanızı dağıtmadan önce bir derleme adımı ekleyemiyor olabilirsiniz. Bu nedenle, öğe URL'lerinize karma oluşturma işlemleri ekleyemezsiniz. Ayrıca her web uygulamasının HTML dosyalarına ihtiyacı vardır. Bu dosyalar (neredeyse) hiçbir zaman sürüm bilgilerini içermez. Çünkü ziyaret edilecek URL'nin https://example.com/index.34def12.html olduğunu hatırlaması gereken hiç kimse web uygulamanızı kullanmaya zahmet etmez. Peki bu URL'ler için ne yapabilirsiniz?

Bu, yenilgiyi kabul etmeniz gereken bir senaryodur. HTTP önbelleğe alma işlemi tek başına ağı tamamen atlamak için yeterli değildir. (Endişelenmeyin, kısa süre içinde hizmet çalışanları hakkında bilgi edineceksiniz. Bu çalışanlar, mücadeleyi lehinize çevirmek için ihtiyaç duyduğumuz desteği sağlayacak.) Ancak ağ isteklerinin mümkün olduğunca hızlı ve verimli olmasını sağlamak için uygulayabileceğiniz birkaç adım vardır.

Aşağıdaki Cache-Control değerleri, sürümlenmemiş URL'lerin nerede ve nasıl önbelleğe alınacağı konusunda ince ayar yapmanıza yardımcı olabilir:

  • no-cache. Bu, tarayıcıya URL'nin önbelleğe alınmış sürümünü kullanmadan önce her seferinde sunucuyla yeniden doğrulama yapması gerektiğini bildirir.
  • no-store. Bu, tarayıcıya ve diğer ara önbelleklere (CDN'ler gibi) dosyanın hiçbir sürümünü saklamamalarını söyler.
  • private. Tarayıcılar dosyayı önbelleğe alabilir ancak ara önbellekler alamaz.
  • public. Yanıt herhangi bir önbellekte saklanabilir.

Hangi Cache-Control değerlerinin kullanılacağına karar verme sürecini görselleştirmek için Ek: Cache-Control akış şeması bölümüne bakın. Cache-Control, virgülle ayrılmış bir yönerge listesi de kabul edebilir. Ek: Cache-Control örnekleri bölümüne bakın.

ETag veya Last-Modified olarak ayarlamak da yardımcı olabilir. Yanıt üstbilgileri bölümünde belirtildiği gibi, ETag ve Last-Modified aynı amaca hizmet eder: Tarayıcının, süresi dolmuş bir önbelleğe alınmış dosyayı yeniden indirmesi gerekip gerekmediğini belirleme. Daha doğru olduğu için ETag kullanmanızı öneririz.

İlk getirme işleminden bu yana 120 saniye geçtiğini ve tarayıcının aynı kaynak için yeni bir istek başlattığını varsayalım. Tarayıcı önce HTTP önbelleğini kontrol eder ve önceki yanıtı bulur. Maalesef yanıtın süresi dolduğu için tarayıcı önceki yanıtı kullanamıyor. Bu noktada tarayıcı yeni bir istek gönderebilir ve yeni yanıtın tamamını alabilir. Ancak bu, kaynak değişmediği için zaten önbellekte bulunan bilgileri indirmenin bir anlamı olmadığından verimsizdir.

ETag başlığında belirtildiği gibi doğrulama jetonlarının çözmek için tasarlandığı sorun budur. Sunucu, genellikle dosyanın içeriğinin karması veya başka bir parmak izi olan rastgele bir jeton oluşturup döndürür. Tarayıcının, parmak izinin nasıl oluşturulduğunu bilmesi gerekmez. Yalnızca bir sonraki istekte sunucuya göndermesi gerekir. Parmak izi aynıysa kaynak değişmemiştir ve tarayıcı indirme işlemini atlayabilir.

ETag veya Last-Modified ayarını yapmak, İstek üstbilgileri bölümünde belirtilen If-Modified-Since veya If-None-Match istek üstbilgilerini tetiklemesine izin vererek yeniden doğrulama isteğini çok daha verimli hale getirir.

Düzgün yapılandırılmış bir web sunucusu, gelen istek üst bilgilerini gördüğünde, tarayıcının HTTP önbelleğindeki kaynağın sürümünün web sunucusu üzerindeki en son sürümle eşleşip eşleşmediğini onaylayabilir. Eşleşme varsa sunucu, "Hey, mevcut olanı kullanmaya devam et!" anlamına gelen bir 304 Not Modified HTTP yanıtıyla yanıt verebilir. Bu tür bir yanıt gönderilirken aktarılacak çok az veri olduğundan genellikle istenen gerçek kaynağın bir kopyasını geri göndermek zorunda kalmaktan çok daha hızlıdır.

Bir kaynak isteyen istemci ve 304 başlığıyla yanıt veren sunucunun görselleştirmesi.
Tarayıcı, sunucudan /file ister ve If-None-Match üst bilgisini ekleyerek sunucuya, dosyanın sunucudaki ETag değerinin tarayıcıdaki If-None-Match değeriyle eşleşmemesi durumunda yalnızca dosyanın tamamını döndürmesini talimatlandırır. Bu durumda 2 değer eşleştiğinden sunucu, dosyanın ne kadar daha uzun süre önbelleğe alınması gerektiğine dair talimatlar içeren bir 304 Not Modified yanıtı döndürür (Cache-Control: max-age=120).

Özet

HTTP önbelleği, gereksiz ağ isteklerini azalttığı için yükleme performansını iyileştirmenin etkili bir yoludur. Tüm tarayıcılarda desteklenir ve ayarlanması çok fazla zaman almaz.

Aşağıdaki Cache-Control yapılandırmaları iyi bir başlangıçtır:

  • Her kullanımdan önce sunucuyla yeniden doğrulanması gereken kaynaklar için Cache-Control: no-cache.
  • Cache-Control: no-store, hiçbir zaman önbelleğe alınmaması gereken kaynaklar içindir.
  • Cache-Control: max-age=31536000 sürümlü kaynaklar için.

ETag veya Last-Modified başlığı, süresi dolmuş önbelleğe alınmış kaynakları daha verimli bir şekilde yeniden doğrulamanıza yardımcı olabilir.

Daha fazla bilgi

Cache-Control başlığını kullanmayla ilgili temel bilgilerden daha fazlasını öğrenmek istiyorsanız Jake Archibald'ın Önbelleğe almayla ilgili en iyi uygulamalar ve maksimum yaşla ilgili dikkat edilmesi gereken noktalar başlıklı rehberine göz atın.

Önbelleğinizi geri gelen ziyaretçiler için nasıl optimize edeceğinizle ilgili yol gösterici bilgiler için Önbelleğinizi sevme başlıklı makaleyi inceleyin.

Ek: Daha fazla ipucu

Daha fazla zamanınız varsa HTTP önbelleğini kullanmanızı optimize etmenin diğer yollarını aşağıda bulabilirsiniz:

  • Tutarlı URL'ler kullanın. Aynı içeriği farklı URL'lerde yayınlarsanız bu içerik birden çok kez getirilip depolanır.
  • Uygulamayı kullanmayı bırakan kullanıcı sayısını en aza indirin. Bir kaynağın bir kısmı (ör. CSS dosyası) sık sık güncellenirken dosyanın geri kalanı (ör. kitaplık kodu) güncellenmiyorsa sık sık güncellenen kodu ayrı bir dosyaya ayırabilir ve sık sık güncellenen kod için kısa süreli bir önbelleğe alma stratejisi, sık sık değişmeyen kod için de uzun süreli bir önbelleğe alma stratejisi kullanabilirsiniz.
  • Cache-Control politikanızda belirli bir düzeyde güncel olmama kabul edilebilirse yeni stale-while-revalidate yönergesine göz atın.

Ek: Cache-Control akış şeması

Akış şeması
Cache-Control üst bilgilerinizi ayarlamayla ilgili karar verme süreci.

Ek: Cache-Control örnekleri

Cache-Control değer Açıklama
max-age=86400 Yanıt, tarayıcılar ve aracı önbellekler tarafından 1 güne (60 saniye x 60 dakika x 24 saat) kadar önbelleğe alınabilir.
private, max-age=600 Yanıt, tarayıcı tarafından 10 dakikaya (60 saniye x 10 dakika) kadar önbelleğe alınabilir (ara önbellekler tarafından değil).
public, max-age=31536000 Yanıt, herhangi bir önbellekte 1 yıl boyunca saklanabilir.
no-store Yanıtın önbelleğe alınmasına izin verilmez ve her istekte tam olarak getirilmelidir.