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

Ilya Grigorik
Cem Posnick
Jeff Posnick

Kaynakları ağ üzerinden getirmek hem yavaş hem de pahalı bir işlemdir:

  • Büyük yanıtlar, tarayıcı ile sunucu arasında çok sayıda gidiş-dönüş gerektirir.
  • Sayfanız tüm kritik kaynakları tamamen indirilene kadar yüklenmez.
  • Bir kullanıcı sitenize sınırlı bir mobil veri planıyla erişiyorsa tüm gereksiz ağ istekleri parayı boşa harcama anlamına gelir.

Gereksiz ağ isteklerinden nasıl kaçınabilirsiniz? Tarayıcının HTTP Önbelleği, ilk savunma hatınızdır. En güçlü veya esnek yaklaşımın olması gerekmez ve önbelleğe alınan yanıtların ömrü üzerinde sınırlı denetime sahip olursunuz. Ancak etkilidir, tüm tarayıcılarda desteklenir ve çok fazla çalışma gerektirmez.

Bu kılavuz, etkili bir HTTP önbelleğe alma uygulamasının temel özelliklerini gösterir.

Tarayıcı uyumluluğu

HTTP Önbelleği adında tek bir API yoktur. Web platformu API'leri koleksiyonunun genel adıdır. Bu API'ler tüm tarayıcılarda desteklenir:

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

Tarayıcının yaptığı 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 için öncelikle tarayıcı önbelleğine yönlendirilir. Eşleşme bulunursa yanıt önbellekten okunur. Böylece hem ağ gecikmesi hem de aktarım işleminin yol açtığı veri maliyetleri ortadan kalkar.

HTTP Önbelleğinin davranışı, istek başlıkları ve yanıt başlıklarının bir kombinasyonu ile kontrol edilir. İdeal bir senaryoda, hem web uygulamanızın kodu (istek başlıklarını belirler) hem de web sunucunuzun yapılandırmasını (yanıt başlıklarını belirler) kontrol edebilirsiniz.

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

İstek başlıkları: Varsayılanlara bağlı kalın (genellikle)

Web uygulamanızın giden isteklerine eklenmesi gereken birkaç önemli başlık olsa da tarayıcı, istekte bulunduğunda neredeyse her zaman bunları sizin adınıza ayarlar. If-None-Match ve If-Modified-Since gibi güncellik kontrolünü etkileyen istek üst bilgileri, tarayıcının HTTP Önbelleğindeki geçerli değerleri anlamasına göre gösterilir.

Bu iyi bir haberimiz var. Bu şekilde HTML'nize <img src="my-image.png"> gibi etiketler eklemeye devam edebilirsiniz. Tarayıcı, fazladan çaba sarf etmeden HTTP önbelleğe alma işlemini otomatik olarak halleder.

Yanıt üstbilgileri: Web sunucunuzu yapılandırın

HTTP önbelleğe alma kurulumunun en önemli bölümü, web sunucunuzun giden her yanıta eklediği üstbilgilerdir. Etkili önbelleğe alma davranışında aşağıdaki başlıkların tümü hesaba katılır:

  • Cache-Control. Sunucu, tarayıcının ve diğer ara önbelleklerin bağımsız yanıtı nasıl ve ne kadar süreyle önbelleğe alacağını belirtmek için 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 dosya içeriğinin karması) gönderebilir. Sunucu aynı jetonu döndürürse dosya aynı olur ve dosyanın yeniden indirilmesine gerek yoktur.
  • Last-Modified. Bu başlık, ETag ile aynı amaca hizmet eder ancak içeriğe dayalı ETag stratejisinin aksine bir kaynağın değişip değişmediğini belirlemek için zamana dayalı bir strateji kullanır.

Bazı web sunucularında bu üst bilgileri varsayılan olarak ayarlamak için yerleşik destek bulunurken bazıları, açık bir şekilde yapılandırmadığınız sürece başlıkları tamamen dışarıda bırakır. Üstbilgilerin nasıl yapılandırılacağına ilişkin belirli ayrıntılar, kullandığınız web sunucusuna bağlı olarak büyük ölçüde değişiklik gösterir. En doğru ayrıntıları almak için sunucunuzun dokümanlarına başvurmanız gerekir.

Daha az arama yapmak için popüler web sunucularının yapılandırılmasına ilişkin talimatları aşağıda bulabilirsiniz:

Cache-Control yanıt başlığının hariç tutulması HTTP önbelleğe alma özelliğini devre dışı bırakmaz. Bunun yerine tarayıcılar, belirli bir içerik türü için ne tür önbelleğe alma davranışının en mantıklı olacağını etkili bir şekilde tahmin eder. Muhtemelen bu tekliflerden daha fazla kontrole ihtiyacınız vardır. Bu nedenle, zaman ayırıp yanıt başlıklarınızı yapılandırın.

Hangi yanıt başlığı değerlerini kullanmalısınız?

Web sunucunuzun yanıt başlıklarını yapılandırırken ele almanız gereken iki önemli senaryo vardır.

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

Sürümlü URL'ler, önbelleğe alma stratejinize nasıl yardımcı olabilir?
Sürümlü URL'ler, önbelleğe alınan yanıtların geçersiz kılınmasını kolaylaştırdığından iyi bir uygulamadır.

Sunucunuzun tarayıcılara bir CSS dosyasını 1 yıl süreyle (Cache-Control: max-age=31536000) önbelleğe alma talimatı verdiğini, ancak tasarımcınızın kısa süre önce hemen kullanıma sunmanız gereken bir acil durum güncellemesi yaptığını varsayalım. Tarayıcılara dosyanın "eski" önbelleğe alınmış kopyasını güncellemeleri için nasıl bildirimde bulunursunuz? En azından kaynağın URL'sini değiştirmeden 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 şekliyle artık güncel olmayana ya da başka bir nedenle önbellekten çıkarılana kadar (örneğin, kullanıcının tarayıcı önbelleğini temizlemesi) kullanılır. Sonuç olarak, sayfa oluşturulduğunda farklı kullanıcılar dosyanın farklı sürümlerini kullanabilir: Kaynağı yeni getiren kullanıcılar yeni sürümü kullanırken daha eski (ama hâlâ geçerli) bir kopyayı önbelleğe alan kullanıcılar ise yanıtının daha eski bir sürümünü kullanır. İstemci taraflı önbelleğe alma ve hızlı güncellemeler özellikleri dahil olmak üzere her iki yöntemden de en iyi şekilde nasıl yararlanabilirsiniz? Kaynağın URL'sini değiştirir ve içeriği her değiştiğinde kullanıcıyı yeni yanıtı indirmeye zorlarsınız. Genellikle bunu, dosya adına dosyanın bir parmak izini veya sürüm numarasını (örneğin, style.x234dff.css) yerleştirerek yaparsınız.

"Parmak izi" veya sürüm oluşturma bilgileri içeren ve içeriği hiçbir zaman değişmeyecek olan URL isteklerine yanıt verirken yanıtlarınıza Cache-Control: max-age=31536000 ekleyin.

Bu değerin ayarlanması, tarayıcıya aynı URL'yi gelecek bir yıl boyunca herhangi bir zamanda (31.536.000 saniye; desteklenen maksimum değer) yüklemesi gerektiğinde, web sunucunuza hiçbir ağ isteği göndermek zorunda kalmadan HTTP Önbelleğindeki değeri hemen kullanabileceğini bildirir. Harika, ağdan kaçınarak elde edilen güvenilirlik ve hızı hemen kazandınız.

Web paketi gibi araçlar oluşturma, öğe URL'lerinize karma parmak izleri atama süreci otomatik hale getirebilir.

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

Maalesef yüklediğiniz URL'lerin hepsi sürüm oluşturulmuş değil. Belki de web uygulamanızı dağıtmadan önce bir derleme adımı ekleyemediğiniz için öğe URL'lerinize karma değerler ekleyemezsiniz. Ayrıca, her web uygulamasının HTML dosyalarına ihtiyacı vardır. Bu dosyalar (neredeyse) hiçbir zaman sürüm oluşturma bilgisi içermez. Çünkü ziyaret edilecek URL'nin https://example.com/index.34def12.html olduğunu hatırlamaları gerektiğinde web uygulamanızı kullanabilecek kimse olmaz. Bu URL'ler için ne yapabilirsiniz?

Bu, yenilgiyi kabul etmeniz gereken senaryolardan biridir. HTTP önbelleğine alma, ağdan tamamen kaçınmak için yeterince etkili değildir. (Endişelenmeyin, yakında savaşı sizin lehinize çevirmek için ihtiyacımız olan desteği sağlayacak hizmet çalışanları hakkında bilgi edineceksiniz.) Ancak ağ isteklerinin mümkün olduğunca hızlı ve verimli olmasını sağlamak için atabileceğiniz birkaç adım vardır.

Aşağıdaki Cache-Control değerleri, sürümü kaldırılmamış URL'lerin nerede ve nasıl önbelleğe alınacağını hassas bir şekilde ayarlamanıza yardımcı olabilir:

  • no-cache. Bu, tarayıcıya URL'nin önbelleğe alınmış bir sürümünü kullanmadan önce her seferinde sunucuyla yeniden doğrulama yapması gerektiğini bildirir.
  • no-store. Bu işlem, tarayıcıya ve diğer ara önbelleklere (CDN gibi) dosyanın hiçbir sürümünü hiçbir zaman depolamamalarını bildirir.
  • private. Tarayıcılar dosyayı önbelleğe alabilir, ancak ara önbellekler yapamaz.
  • 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ına göz atın. Cache-Control politikasının virgülle ayrılmış bir yönerge listesini kabul edebileceğini de unutmayın. Ek: Cache-Control örnek bölümüne bakın.

Bununla birlikte, iki ek yanıt başlığından birini ayarlamak da yardımcı olabilir: ETag veya Last-Modified. Yanıt başlıklarında 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 indirmesinin gerekip gerekmediğini belirlemek. ETag daha doğru olduğu için önerilen yaklaşımdır.

ETag örneği

İlk getirme işleminin üzerinden 120 saniye geçtiğini ve tarayıcının aynı kaynak için yeni bir istek başlattığını varsayalım. Tarayıcı, ilk olarak HTTP Önbelleğini kontrol eder ve önceki yanıtı bulur. Yanıtın süresi dolduğu için maalesef tarayıcı önceki yanıtı kullanamıyor. Bu noktada, tarayıcı yeni bir istek gönderip yeni tam yanıtı getirebilir. Ancak kaynak değişmediyse önbellekte bulunan bilgilerin aynısını indirmenize gerek olmadığı için bu verimsizdir. ETag başlığında belirtildiği gibi doğrulama jetonlarının çözmek için tasarlandığı sorundur. Sunucu, rastgele bir jeton oluşturur ve döndürür. Bu, genellikle dosya içeriklerinin karma değeri veya başka bir parmak izidir. Tarayıcının parmak izinin nasıl oluşturulduğunu bilmesine gerek yoktur, yalnızca bir sonraki istekte sunucuya göndermesi gerekir. Parmak izi hâlâ aynıysa kaynak değişmemiştir ve tarayıcı indirme işlemini atlayabilir.

ETag veya Last-Modified ayarlayarak yeniden doğrulama isteğini çok daha verimli hâle getirirsiniz. Bunlar, İstek başlıklarında bahsedilen If-Modified-Since veya If-None-Match istek başlıklarını tetikler.

Doğru şekilde yapılandırılmış bir web sunucusu gelen istek başlıklarını gördüğünde, tarayıcının HTTP Önbelleğinde zaten bulunan sürümünün, web sunucusundaki en son sürümle eşleşip eşleşmediğini onaylayabilir. Eşleşme varsa sunucu bir 304 Not Modified HTTP yanıtıyla yanıt verebilir. Bu, "Hey, zaten sahip olduğunuz şeyi kullanmaya devam edin!" ifadesine eşdeğerdir. Bu tür yanıtlar gönderilirken aktarılacak veri miktarı çok az olduğundan bu işlem, istenen kaynağın bir kopyasını gerçekten geri göndermek zorunda kalmadan genellikle çok daha hızlıdır.

Kaynak isteyen bir istemci ile 304 üstbilgisiyle yanıt veren sunucunun diyagramı.
Tarayıcı, sunucudan /file isteğinde bulunur ve If-None-Match üst bilgisini, sunucunun yalnızca sunucudaki dosyanın ETag değeri, tarayıcının If-None-Match değeriyle eşleşmediğinde tam dosyayı döndürmesi için döndürmesini ister. Bu durumda 2 değer eşleşmiştir. Böylece sunucu, dosyanın ne kadar süreyle önbelleğe alınması gerektiğine (Cache-Control: max-age=120) dair talimatları içeren bir 304 Not Modified yanıtı döndürür.

Özet

HTTP Önbelleği, gereksiz ağ isteklerini azalttığı için yük performansını iyileştirmenin etkili bir yoludur. Tüm tarayıcılarda desteklenir ve kurulumu ç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.
  • Hiçbir zaman önbelleğe alınmaması gereken kaynaklar için Cache-Control: no-store.
  • Sürümü tutulan kaynaklar için Cache-Control: max-age=31536000.

Ayrıca ETag veya Last-Modified üst bilgisi, süresi dolan önbellek kaynaklarını daha verimli bir şekilde yeniden doğrulamanıza yardımcı olabilir.

Daha fazla bilgi

Cache-Control üstbilgisinin kullanımıyla ilgili temel bilgilerin ötesine geçmek istiyorsanız Jake Archibald'ın Önbelleğe almayla ilgili en iyi uygulamalar ve maksimum yaş sınırı kılavuzuna göz atın.

Geri gelen ziyaretçiler için önbellek kullanımınızı nasıl optimize edeceğinizle ilgili yardım almak üzere Önbelleğinizi sevme bölümüne bakın.

Ek: Daha fazla ipucu

Daha fazla zamanınız varsa HTTP Önbelleği kullanımınızı optimize etmek için aşağıdaki diğer yöntemleri kullanabilirsiniz:

  • Tutarlı URL'ler kullanın. Aynı içeriği farklı URL'lerde sunuyorsanız bu içerik birden çok kez getirilir ve depolanır.
  • Uygulamayı kullanmayı bırakan kullanıcı sayısını en aza indirin. Bir kaynağın parçası (CSS dosyası gibi) sık sık güncelleniyorsa ancak dosyanın geri kalanı (kitaplık kodu gibi) sık sık güncelleniyorsa sık güncellenen kodu ayrı bir dosyaya bölmeyi ve sık güncellenen kod için kısa süreli bir önbelleğe alma stratejisi, sık değişmeyen kod için ise uzun bir önbelleğe alma süresi stratejisi kullanmayı düşünün.
  • Cache-Control politikanızda bir miktar eskiliği kabul edilebilir nitelikteyse yeni stale-while-revalidate yönergesini inceleyin.

Ek: Cache-Control akış şeması

Akış çizelgesi

Ek: Cache-Control örnek

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