Diyarbakır Yazılım LogoDİYARBAKIR
>Ana Sayfa>Projeler>Atölye>Yazılar
>Ana Sayfa>Projeler>Atölye>Yazılar
durum: inşa ediliyor
Tarayıcı İçi Caching Stratejileri ve Veri Tutarlılığı
  1. Anasayfa
  2. Yazılar
  3. Tarayıcı İçi Caching Stratejileri ve Veri Tutarlılığı

Tarayıcı İçi Caching Stratejileri ve Veri Tutarlılığı

Diyarbakır Yazılım
Diyarbakır Yazılım
16.08.2026
#Yazılım#Teknoloji#Topluluk

Bir web uygulamasını hızlandırmak için cache eklemek kolaydır, doğru veriyi doğru zamanda göstermek ise işin asıl zor kısmıdır. On yılı aşkın frontend geliştirme deneyimimde performans sorunlarının önemli bir bölümünün cache eksikliğinden, daha tehlikeli veri hatalarının ise yanlış cache politikasından kaynaklandığını gördüm. Tarayıcı İçi Caching Stratejileri ve Veri Tutarlılığı konusu bu nedenle yalnızca yanıtları birkaç dakika saklamak veya JavaScript dosyalarına uzun max-age vermek değildir. Tarayıcı cache stratejileri nasıl uygulanır, browser caching ile veri tutarlılığı nasıl sağlanır ve hangi veri ne kadar süre eski kalabilir gibi sorular uygulamanın iş modeline göre cevaplanmalıdır. Bu rehberde HTTP cache, Service Worker Cache Storage, IndexedDB, query cache, bfcache, cross-tab senkronizasyonu, invalidation, versioning, offline çalışma ve güvenlik konularını tek bir mimari içinde ele alacağız.

Tarayıcı İçi Caching Nedir?

Tarayıcı içi caching, daha önce elde edilmiş kaynakların veya verilerin sonraki kullanım için kullanıcı cihazında geçici ya da kalıcı biçimde tutulmasıdır. Amaç aynı veriyi her ihtiyaçta ağ üzerinden yeniden indirmek yerine uygun cache katmanından daha hızlı sunmaktır. Bu yaklaşım statik JavaScript dosyalarından API sonuçlarına, uygulama durumundan offline veri setlerine kadar farklı veri türlerini kapsayabilir. Her katmanın yaşam süresi, invalidation yöntemi ve güvenlik modeli farklıdır. Sağlıklı bir cache mimarisinde ilk soru “ne kadar uzun saklayabiliriz” değil, “bu veri ne kadar eski olduğunda kullanıcı veya işletme açısından sorun oluşturur” olmalıdır.

Client-Side Cache Nedir?

Client-side cache, sunucudan alınan veya uygulama tarafından üretilen verinin kullanıcı cihazındaki browser ortamında tekrar kullanılmak üzere saklanmasıdır. Bu saklama JavaScript memory, HTTP cache, Cache Storage, IndexedDB veya query library memory'si gibi farklı yapılarda gerçekleşebilir. Her mekanizmanın kullanım amacı aynı değildir ve bunları tek bir cache olarak düşünmek hatalıdır. Örneğin HTTP cache request ve response davranışına odaklanırken IndexedDB structured application data için programatik erişim sağlar. Mimari tasarımda hangi cache'in hangi verinin sahibi olduğu açık biçimde tanımlanmalıdır.

Cache Neden Kullanılır?

Cache kullanımının en görünür faydası kullanıcıya daha hızlı yanıt vermektir, ancak gerçek fayda bundan daha geniştir. Network request sayısı azalır, origin server üzerindeki trafik düşer ve mobil kullanıcıların veri tüketimi sınırlandırılır. Offline veya zayıf bağlantı koşullarında temel özellikler çalışmaya devam edebilir. Bunun karşılığında uygulama aynı verinin birden fazla kopyasını yönetmek zorunda kalabilir. Bu nedenle cache performans kazanımı ile veri güncelliği arasında kontrollü bir denge kurma işidir.

Latency Azaltma

Ağ üzerinden yapılan her request DNS, bağlantı, TLS, server processing ve response transferi gibi gecikme bileşenleri taşıyabilir. Veri memory cache veya local persistent storage içinde hazır olduğunda bu adımların önemli bölümü atlanır. Kullanıcı özellikle tekrar ziyaretlerde ve route geçişlerinde sonucu daha hızlı görür. Yine de cache hit hızlı olduğu için verinin doğru olduğu varsayılmamalıdır. Latency hedefi freshness politikasıyla birlikte tasarlanırsa hız kazanımı kullanıcıya eski bilgi gösterme pahasına elde edilmez.

Bandwidth Tasarrufu

Cache aynı kaynakların tekrar tekrar indirilmesini önleyerek veri transferini azaltır. Hash'lenmiş JavaScript, CSS, font ve görseller uzun süre browser cache içinde tutulduğunda tekrar ziyaretler belirgin biçimde hafifler. API tarafında ETag ve 304 yanıtları response body'nin yeniden gönderilmesini önleyebilir. Mobil bağlantılarda bu yaklaşım kullanıcı veri tüketimi açısından da değerlidir. Bandwidth tasarrufu hedeflenirken stale içerik riski ve conditional request maliyeti birlikte değerlendirilmelidir.

Backend Yükünü Azaltma

Browser veya CDN cache hit olduğunda bazı request'ler origin server'a hiç ulaşmaz. Query cache ise aynı sayfa içinde birden fazla component'in aynı veriyi tekrar istemesini önleyebilir. Bu durum backend işlem yükünü ve database query sayısını azaltabilir. Ancak cache TTL sonunda çok sayıda client aynı anda origin'e yönelirse ani yük artışı oluşabilir. Bu nedenle client cache politikası backend caching, request deduplication ve gerektiğinde TTL jitter gibi yaklaşımlarla birlikte düşünülmelidir.

Offline Kullanım

Service Worker ve IndexedDB çevrimdışı kullanılabilen web uygulamalarının temel yapı taşları arasındadır. App shell önceden cache edilebilir ve daha önce alınmış application data IndexedDB üzerinden gösterilebilir. Kullanıcının offline yaptığı değişiklikler mutation queue içinde saklanıp bağlantı geldiğinde server'a gönderilebilir. Bu model yalnızca dosya saklamak değil, conflict ve ordering problemlerini de yönetmek anlamına gelir. Offline desteği gerekiyorsa veri tutarlılığı tasarımı geliştirme sürecinin başında ele alınmalıdır.

Cache Kullanmanın Veri Tutarlılığı Maliyeti

Bir veriyi cache'e koyduğunuz anda server'daki gerçek durum ile client'taki kopya birbirinden ayrılabilir. Veri server'da değişirse browser bunu kendiliğinden her cache katmanında öğrenmez. TTL, revalidation, push event veya mutation invalidation gibi bir güncelleme mekanizması gerekir. Birden fazla tab, offline queue ve Service Worker eklendiğinde aynı kaynağın birkaç farklı kopyası oluşabilir. Cache tasarımının maliyeti tam olarak bu kopyaların hangi kuralla güncel tutulacağını belirlemektir.

Tarayıcıda Kaç Farklı Cache Katmanı Vardır?

Modern web uygulamalarında tek bir “browser cache” yoktur ve hata ayıklarken bu ayrım kritik öneme sahiptir. JavaScript memory cache, query cache, HTTP cache, Cache Storage, IndexedDB, Web Storage ve bfcache farklı yaşam döngülerine sahiptir. Bunlara CDN ve origin cache eklendiğinde bir resource kullanıcıya ulaşmadan önce birçok katmandan geçebilir. Aynı URL'nin bir katmanda güncel, diğerinde eski kopyası bulunabilir. Bu nedenle production sorunlarında hangi katmanın response verdiğini belirlemeden cache temizlemek veya TTL değiştirmek güvenilir çözüm değildir.

JavaScript Memory Cache

JavaScript memory cache uygulama çalışırken object, Map veya custom data structure içinde veri tutmayı ifade eder. Erişim son derece hızlıdır çünkü disk veya network işlemi gerekmez. Sayfa yenilendiğinde veya tab kapandığında bu veri genellikle kaybolur. Memory cache application lifecycle ile doğrudan bağlantılıdır. Büyük verilerin sınırsız tutulması memory leak ve garbage collection baskısı oluşturabileceği için entry sınırı ve cleanup stratejisi düşünülmelidir.

Query / Server-State Cache

Query cache server'dan alınan veriyi component lifecycle'dan bağımsız biçimde yönetmeye odaklanır. TanStack Query, SWR ve benzeri yapılar request deduplication, stale/fresh ayrımı, refetch ve mutation invalidation gibi özellikler sağlar. Bu katman application UI state ile aynı amaç için kullanılmamalıdır. Server state'in server'da başka aktörler tarafından değişebileceği kabul edilir. Bu nedenle query cache'in temel görevi yalnızca saklamak değil, verinin ne zaman yeniden doğrulanacağını yönetmektir.

Browser HTTP Cache

HTTP cache browser tarafından HTTP header kurallarına göre yönetilen response cache'idir. Cache-Control, ETag, Last-Modified ve Vary gibi header'lar bu davranışı belirler. Fresh response network'e gitmeden kullanılabilir, stale response ise validator varsa conditional request ile doğrulanabilir. Bu cache application JavaScript'inden bağımsız çalışabilir. DevTools üzerinde “memory cache”, “disk cache” ve 304 gibi işaretler davranışın farklı taraflarını gözlemlemeye yardımcı olur.

Service Worker Cache Storage

Cache Storage Service Worker veya window JavaScript tarafından programatik olarak yönetilebilen request-response deposudur. HTTP cache'ten farklı olarak hangi request'in hangi cache'e yazılacağı uygulama koduyla belirlenebilir. Cache-first, network-first ve stale-while-revalidate gibi stratejiler burada uygulanabilir. Entry'ler browser kendiliğinden HTTP freshness header'larına göre otomatik invalidation yapacak şekilde düşünülmemelidir. Uygulama cache version, expiration ve cleanup davranışının sorumluluğunu açık biçimde üstlenmelidir.

IndexedDB

IndexedDB browser içinde structured ve büyük veri setlerini saklamak için tasarlanmış asynchronous bir database API'sidir. Object store, key, index ve transaction modelleri sağlar. API response'larının normalize edilmiş kopyaları, offline kayıtlar veya büyük local dataset için kullanılabilir. Schema versioning gerektiği için basit key-value storage'dan daha fazla bakım ister. IndexedDB'nin cache mi yoksa offline-first uygulamada geçici source of truth mu olduğu mimari düzeyde belirlenmelidir.

localStorage / sessionStorage

Web Storage basit string tabanlı key-value veriler için uygundur. localStorage browser oturumları arasında kalabilirken sessionStorage tab session sınırında yaşar. API'lerin synchronous olması büyük payload ve sık erişimde main thread'i bloklayabilir. Bu nedenle büyük API response'larını veya binlerce kaydı saklamak doğru kullanım değildir. Tema, dil veya küçük kullanıcı tercihi gibi sınırlı veriler daha uygun örneklerdir.

Back/Forward Cache

bfcache klasik resource cache değildir ve sayfanın tüm çalışma durumunu memory içinde dondurarak geri veya ileri navigasyonda geri yükleyebilir. Kullanıcı geri düğmesine bastığında sayfa JavaScript state dahil önceki haliyle çok hızlı açılabilir. Bu hız aynı zamanda eski UI bilgisinin tekrar görünmesi riskini getirir. pageshow ve event.persisted kullanılarak restore tespit edilebilir. Kritik server state geri dönüş sırasında hedefli biçimde yeniden doğrulanmalıdır.

CDN Cache

CDN browser dışında, kullanıcı ile origin arasında çalışan shared cache katmanıdır. Public asset ve uygun response'ları edge noktalarda saklayarak origin'e gitmeden sunabilir. s-maxage gibi direktifler shared cache freshness politikasını browser politikasından ayırmayı sağlar. Personalized response yanlışlıkla shared cache'e girerse ciddi veri sızıntısı oluşabilir. CDN cache key ve Vary davranışı bu nedenle güvenlik tasarımının da parçasıdır.

Origin Server

Origin server çoğu sistemde en güncel doğrulanmış verinin üretildiği veya backend cache üzerinden sunulduğu katmandır. Browser cache miss veya revalidation request sonunda origin'e kadar ulaşabilir. Origin tarafında Redis benzeri cache, application memory veya database query cache bulunabilir. Client ekibi bu katmanların varlığını bilmiyorsa stale response'un kaynağını yanlış teşhis edebilir. Uçtan uca cache mimarisi bütün katmanların freshness ve invalidation kurallarını birlikte belgelemelidir.

Browser Memory Cache Nedir?

Browser memory cache terimi ile application JavaScript memory cache'i birbirine karıştırmamak gerekir. Browser kendi network ve resource yükleme kararları kapsamında RAM üzerinde bazı kaynakları tutabilir. Bu davranış browser implementation'ına bağlıdır ve application'ın Map nesnesi gibi doğrudan yönetilemez. DevTools bazen resource'un memory cache üzerinden geldiğini gösterir. Refresh veya tab lifecycle sırasında davranışın browser kararlarına göre değişebileceği unutulmamalıdır.

RAM Üzerinde Cache

Memory cache disk erişimine gerek kalmadan RAM üzerinden hızlı resource tekrar kullanımı sağlayabilir. Bu özellik özellikle aynı document yaşamı içinde tekrar kullanılan asset'lerde düşük latency sunar. Browser hangi entry'yi ne kadar tutacağını kendi memory baskısına göre değiştirebilir. Developer bu cache'i kalıcı storage gibi düşünmemelidir. Doğru HTTP header'ları yine temel kontrol mekanizmasıdır.

Tab Yaşam Döngüsü

Tab açık olduğu sürece browser bazı resource ve application state'leri memory içinde tutabilir. Tab discard edildiğinde veya browser memory baskısı yaşadığında bu kaynaklar kaybolabilir. Background tab freeze gibi lifecycle davranışları JavaScript execution'ı da etkileyebilir. Bu nedenle memory'deki cache entry'nin her zaman mevcut olacağı varsayımı yapılmamalıdır. Kalıcı offline gereksinimi varsa IndexedDB veya Cache Storage gibi uygun storage mekanizması kullanılmalıdır.

Refresh Sonrası Davranış

Normal refresh browser'ın HTTP cache'i tamamen yok saydığı anlamına gelmez. Browser validator ve cache directive'lerine göre conditional request veya yeniden kullanım davranışı gösterebilir. Force reload ise daha agresif biçimde cached response'u bypass etmeyi hedefler. DevTools açıkken Disable Cache seçeneği test davranışını ayrıca değiştirebilir. Cache bug'ı araştırırken hangi reload türünün kullanıldığı not edilmelidir.

Browser Tarafından Yönetilen Memory Cache

Browser network stack kendi memory cache davranışını implementation seviyesinde yönetir. Uygulama geliştiricisinin entry listesi veya eviction sırası üzerinde doğrudan kontrolü yoktur. HTTP semantics doğru tanımlandığında browser uygun reuse kararını verir. Bu nedenle “browser memory cache'i temizleyen JavaScript yazalım” yaklaşımı doğru değildir. Uygulamanın kontrol edebildiği taraf URL versioning, cache header ve gerektiğinde programmatic storage katmanlarıdır.

Uygulama Memory Cache'inden Farkı

Application memory cache doğrudan kendi JavaScript kodunuz veya kullandığınız query library tarafından yönetilir. Entry key, TTL, invalidation ve cleanup davranışını siz belirlersiniz. Browser memory cache ise network resource yönetiminin iç parçasıdır. Aynı API response hem HTTP cache'te hem query cache'te bulunabilir ve iki katmanın freshness tanımı farklı olabilir. Double-cache durumlarında hangi katmanın güncelliği kontrol ettiği açıkça belirlenmelidir.

Application State ile Server State Arasındaki Fark

Frontend uygulamalarda veri yönetiminin en temel ayrımlarından biri application state ile server state arasındadır. Modal'ın açık olup olmadığı veya seçili tab gibi bilgiler uygulamanın kendisine aittir. Ürün, kullanıcı profili veya sipariş bilgisi ise server'dan türetilir ve başka aktörler tarafından değiştirilebilir. Server state'in local kopyası gerçekte bir cache'dir. Bu ayrım yapılmadığında global state store zaman içinde manual refetch ve invalidation kodlarıyla dolabilir.

UI State

UI state kullanıcı arayüzünün geçici davranışını tanımlar. Modal görünürlüğü, seçili accordion, sidebar durumu veya aktif filtre paneli buna örnektir. Bu verinin server ile freshness problemi yoktur. Component state veya uygun client store içinde yönetilebilir. Server query cache'e UI state koymak iki farklı problemi gereksiz yere birbirine bağlar.

Form State

Form state kullanıcının henüz server'a göndermediği input değerlerini ve validation durumunu içerir. Bu veri server state'in geçici taslağı olabilir ancak mutation tamamlanana kadar server source of truth değildir. Draft persistence gerekiyorsa ayrı storage stratejisi kullanılabilir. Submit başarılı olduğunda query cache server response ile uzlaştırılmalıdır. Optimistic update uygulanıyorsa form state ile cached entity arasındaki sınır açık tutulmalıdır.

Server-Derived State

Server-derived state API veya server rendering sonucu elde edilen ve asıl kaynağı backend olan veridir. Kullanıcı aynı veriyi başka cihazdan veya başka tab'dan değiştirebilir. Bu nedenle local kopyanın güncel olup olmadığını belirleyen freshness mekanizması gerekir. Query library'lerin sağladığı stale, invalidation ve refetch kavramları bu ihtiyaca yöneliktir. Server state'i normal application state gibi sonsuza kadar saklamak eski veri riskini artırır.

Server State'in Cache Olması

Frontend'in server state kopyası her zaman belirli bir anda çekilmiş snapshot'tır. Server'daki gerçek kayıt bundan sonra değişebilir. Bu nedenle query result “state” olsa bile mimari açıdan cache olarak ele alınmalıdır. Cache key, dataUpdatedAt veya validator gibi metadata güncellik kararına yardımcı olur. Uygulama bu kopyanın ne zaman geçersiz sayılacağını açık biçimde tanımlamalıdır.

Redux/Zustand ile TanStack Query/SWR Farkı

Redux ve Zustand genel application state yönetimi için kullanılabilirken TanStack Query ve SWR server-derived data'nın cache ve refetch yaşam döngüsüne odaklanır. Elbette teknik olarak API data global store içinde tutulabilir, ancak invalidation ve request deduplication işini kendiniz tasarlamanız gerekir. Query library server state'in stale olabileceğini modelin merkezine yerleştirir. Application store ise genellikle verinin local olarak doğrudan sahiplenildiği durumlarda daha doğaldır. Büyük projelerde iki yaklaşım rakip değil, farklı veri sınıfları için tamamlayıcı araçlar olarak kullanılabilir.

Browser HTTP Cache Nasıl Çalışır?

Browser HTTP cache request URL'si, ilgili request header'ları ve response cache metadata'sını kullanarak daha önce alınmış yanıtın tekrar kullanılıp kullanılamayacağını değerlendirir. Response fresh ise network'e gitmeden doğrudan cache'ten sunulabilir. Response stale ise validator bulunuyorsa conditional request yapılabilir. Server resource değişmediyse 304 yanıtı body tekrar indirilmeden cached response'un kullanılmasını sağlar. Bu mekanizma doğru header'larla yapılandırıldığında uygulama koduna ek cache logic yazmadan ciddi performans kazanımı sağlar.

HTTP Response'un Cache'e Yazılması

Bir response'un HTTP cache'e girip girmeyeceği status, method, cache header ve browser kurallarına bağlıdır. Server caching beklentisini açık Cache-Control politikalarıyla belirtmelidir. Header bırakılmadığında bazı response'lar heuristic caching davranışına girebilir. Bu nedenle “cache istemiyoruz, header koymayalım” güvenilir strateji değildir. Her önemli endpoint için saklama ve reuse politikası açıkça tanımlanmalıdır.

Fresh Response

Fresh response tanımlanan freshness lifetime henüz dolmamış cached response'dur. Browser çoğu durumda origin'e gitmeden bu response'u kullanabilir. max-age en yaygın freshness mekanizmalarından biridir. Freshness süresi resource'un gerçek değişim sıklığıyla uyumlu olmalıdır. Fiyat veya permission gibi hızlı değişen data için uzun freshness kullanıcıya yanlış bilgi gösterebilir.

Stale Response

Freshness lifetime dolduğunda response stale kabul edilir. Stale olması response'un mutlaka yanlış olduğu anlamına gelmez, yalnızca yeniden kullanılmadan önce belirli kurallara ihtiyaç duyulduğunu gösterir. Validator varsa origin veya uygun cache katmanıyla revalidation yapılabilir. stale-while-revalidate gibi direktifler belirli süre boyunca stale response'un kullanılmasına izin verebilir. Bu karar verinin business toleransına göre verilmelidir.

Cache Hit

Cache hit istenen response'un uygun cache katmanında bulunup network veya origin maliyeti azaltılarak sunulmasıdır. Hit rate yüksek olması her zaman iyi sonuç anlamına gelmez. Yanlış cache key ile kullanıcıya başka kullanıcının response'u verilmesi de teknik olarak hit olabilir. Bu nedenle cache hit metriği freshness ve correctness metrikleriyle birlikte izlenmelidir. Performans ile veri doğruluğu birbirinden ayrı kalite eksenleridir.

Revalidation

Revalidation cached response'un hâlâ güncel olup olmadığını server'a sormaktır. ETag kullanılıyorsa client If-None-Match, Last-Modified kullanılıyorsa If-Modified-Since gönderebilir. Resource değişmediyse 304 response body taşımadan cached copy'nin geçerli olduğunu doğrular. Bu yaklaşım güncellik gerektiren içerikte tam response indirmeye göre bandwidth tasarrufu sağlar. Revalidation network round trip'i tamamen ortadan kaldırmaz.

Origin Request

Cache miss veya validator sonucunda resource'un değiştiğinin anlaşılması origin request gerektirebilir. Request CDN gibi shared cache katmanlarından geçiyorsa origin'e ulaşmadan da cevaplanabilir. Origin response yeni validator ve freshness metadata ile cache'leri günceller. Bu aşamadaki server latency kullanıcıya doğrudan yansıyabilir. Cache stratejisi origin capacity ve response time hedefleriyle birlikte tasarlanmalıdır.

Cache-Control Nedir?

Cache-Control browser ve shared cache'lere bir response'un nasıl saklanıp tekrar kullanılabileceğini anlatan HTTP header'ıdır. Tek bir directive yerine çoğu zaman birkaç directive birlikte kullanılır. max-age, private, no-cache, no-store ve stale-while-revalidate farklı problemleri çözer. Cache-Control ETag Last-Modified ve stale-while-revalidate karşılaştırması yapılırken freshness ile validation kavramlarını birbirinden ayırmak önemlidir. Doğru politika resource'un değişim sıklığı, gizlilik seviyesi ve offline toleransına göre seçilmelidir.

max-age

max-age response'un kaç saniye fresh kabul edilebileceğini belirtir. Bu süre boyunca uygun cache response'u revalidation yapmadan kullanabilir. Hash'lenmiş immutable asset'lerde bir yıl gibi uzun değerler sık kullanılır. Dynamic API data için süre çok daha kısa olabilir. TTL belirlemek için yalnızca teknik performans değil verinin yanlış kalma maliyeti de hesaplanmalıdır.

s-maxage

s-maxage shared cache'ler için freshness süresi belirler ve browser private cache davranışından ayrışabilir. CDN'de response'u uzun süre tutarken browser'a daha kısa max-age vermek bazı mimarilerde yararlı olabilir. Personalized response için shared caching güvenli değilse bu directive dikkatle kullanılmalıdır. CDN implementation ayrıntıları ayrıca kontrol edilmelidir. Cache policy deployment ve invalidation kapasitesiyle birlikte tasarlanmalıdır.

public

public response'un shared cache tarafından saklanabileceğini açıkça ifade eder. Authorization içeren veya kullanıcıya özel response'larda yanlış kullanımı güvenlik riski oluşturur. Static asset ve herkes için aynı public içerik daha uygun adaydır. Public kullanmak tek başına freshness süresi belirlemez. max-age veya s-maxage gibi directive'lerle birlikte anlamlı politika oluşturulur.

private

private response'un shared cache tarafından saklanmaması, ancak private browser cache tarafından uygun kurallarla tutulabilmesi anlamına gelir. Kullanıcıya özel ama hassas olmayan bazı HTML veya API response'larda kullanılabilir. Bunun yine de doğru authentication ve authorization tasarımının yerini tutmadığı unutulmamalıdır. Logout sırasında application cache cleanup ayrıca yapılmalıdır. Çok hassas veri için no-store daha doğru olabilir.

no-cache

no-cache ismine rağmen response'un saklanmasını yasaklamaz. Asıl anlamı response yeniden kullanılmadan önce revalidation yapılması gerektiğidir. ETag veya Last-Modified ile birlikte kullanıldığında güncel içerik kontrolü yapılıp 304 alınabilir. HTML gibi URL'si kolay versionlanamayan ana resource'larda güçlü bir yaklaşımdır. no-cache ile no-store arasındaki bu ayrım production caching sorunlarında en sık karıştırılan noktalardan biridir.

no-store

no-store cache'in request veya response'u saklamamasını istemek için kullanılır. Finansal detay veya hassas kullanıcı bilgisi gibi cache'te bulunması istenmeyen response'larda değerlendirilebilir. Bu directive performans maliyetini artırabilir çünkü reuse yapılmaz. Her dynamic endpoint'e refleks olarak no-store vermek gereksiz network ve server yükü oluşturabilir. Güvenlik gereksinimi ile freshness gereksinimi birbirinden ayrılmalıdır.

must-revalidate

must-revalidate response stale olduktan sonra origin doğrulaması yapılmadan reuse edilmemesi gerektiğini belirtir. Network erişilemediğinde cache'in eski response'u keyfi biçimde kullanmasını sınırlamayı amaçlar. Kesin güncellik gerektiren bazı veriler için yararlı olabilir. Offline-first içerikte ise bu davranış kullanıcı deneyimiyle çelişebilir. Directive seçimi failure durumunda nasıl davranmak istediğinizle birlikte yapılmalıdır.

immutable

immutable freshness süresi boyunca resource'un değişmeyeceğini belirtir. Content hash içeren JavaScript ve CSS asset'leri buna doğal örnektir. İçerik değişirse URL de değiştiği için eski URL'nin response'u gerçekten sabit kalabilir. Bu yaklaşım gereksiz revalidation request'lerini azaltır. Hash içermeyen ve aynı URL altında değişen resource'a immutable vermek deployment sonrası stale asset problemine yol açabilir.

stale-while-revalidate

stale-while-revalidate response freshness süresi dolduktan sonra belirli bir ek süre cached stale response'un hızlı biçimde kullanılmasına izin verirken arka planda güncelleme yapılmasını sağlar. Kullanıcı düşük latency alır ve cache sonraki request için yenilenir. Ancak ilk kullanıcı kısa süreli eski içerik görebilir. Blog, katalog veya avatar gibi toleranslı veriler için uygun olabilir. Fiyat, permission veya finansal işlem durumu gibi verilerde business riski dikkatle değerlendirilmelidir.

stale-if-error

stale-if-error origin veya upstream hata verdiğinde belirli süre eski cached response'un kullanılmasına izin verebilir. Bu yaklaşım availability gereksinimi yüksek sistemlerde kullanıcıya tamamen hata göstermek yerine son bilinen içeriği sunabilir. Stale response'un ne kadar eski olduğu UI'da belirtilmesi gereken durumlar olabilir. Kritik finansal veya güvenlik verisinde kullanımı doğru olmayabilir. Hata anındaki fallback politikası veri sınıfına göre önceden tanımlanmalıdır.

no-cache ile no-store Arasındaki Fark

no-cache ile no-store isimleri nedeniyle sık karıştırılır, ancak semantik olarak farklıdır. no-cache response'un saklanmasına izin verip kullanmadan önce doğrulama ister. no-store ise response'un cache'te tutulmamasını amaçlar. Bir HTML belgesinin her ziyaret sırasında güncelliğini kontrol etmek istiyorsanız no-cache uygun olabilir. Hassas verinin tarayıcı storage katmanlarında bulunmasını istemiyorsanız no-store daha güçlü seçimdir.

no-cache Veriyi Saklayabilir

no-cache response body'nin browser cache'e yazılmasını engellemez. Cached kopya daha sonra ETag veya başka validator kullanılarak doğrulanabilir. İçerik değişmediyse 304 yanıtıyla aynı body tekrar kullanılabilir. Bu mekanizma freshness ile bandwidth tasarrufunu birlikte sağlar. İsme bakarak “cache kapalı” varsayımı yapmak yanlış debug sonucuna yol açabilir.

Kullanımdan Önce Revalidation

No-cache politikasında amaç cached response'u doğrudan sunmadan önce güncelliğini kontrol etmektir. Validator mevcutsa conditional request küçük response ile sonuçlanabilir. Bu yaklaşım HTML, manifest veya sık değişen public API gibi kaynaklarda yararlıdır. Network round trip hâlâ gerektiği için tamamen offline çalışmaz. Gecikme ile freshness gereksinimi birlikte değerlendirilmelidir.

no-store Veriyi Saklamaz

No-store response'un storage cache'lerinde saklanmamasını istemek için kullanılır. Browser request'i network üzerinden alır ve normal HTTP cache reuse davranışını uygulamaz. Çok hassas veriler için güvenlik açısından daha uygun olabilir. Bunun her tür private data için otomatik zorunluluk olmadığı unutulmamalıdır. Gereksiz kullanım tekrar navigation ve server cost üzerinde performans kaybı yaratır.

Hassas Veriler İçin Kullanım

Hesap bakiyesi, tek kullanımlık güvenlik bilgisi veya hassas kişisel veri gibi response'ların cihaz üzerinde cache'te kalması istenmeyebilir. Bu durumlarda no-store değerlendirilebilir. Uygulama query cache, IndexedDB ve Service Worker gibi diğer katmanların da aynı veriyi saklamadığından emin olmalıdır. Sadece HTTP header eklemek client application cache'i temizlemez. Logout ve account switch akışları uçtan uca veri temizliği testleri içermelidir.

Sık Yapılan Yanlışlar

En yaygın hata bütün dynamic API'lere no-store vererek caching'i tamamen kapatmaktır. Bir diğer hata no-cache'in hiç saklama yapılmadığı anlamına geldiğini düşünmektir. Personalized response'a public directive eklemek çok daha ciddi güvenlik sorunu yaratabilir. Browser tarafındaki query cache HTTP header'ından bağımsız kaldığı için yalnızca server header değiştirmek de yeterli olmayabilir. Cache bug'larında bütün katmanların ayrı ayrı incelenmesi gerekir.

Public ve Private Cache Arasındaki Fark

HTTP caching'de private cache genellikle tek kullanıcıya ait browser cache'i, shared cache ise CDN veya proxy gibi birden fazla kullanıcıya response sunabilen katmanı ifade eder. Bu ayrım veri güvenliği açısından son derece önemlidir. Aynı URL kullanıcıya göre farklı içerik üretiyorsa shared cache key'in doğru context'i içermesi veya response'un shared caching dışında tutulması gerekir. Authenticated API response'larının tamamını public cache'e koymak performans uğruna güvenliği riske atar. Cache mimarisi authorization tasarımıyla birlikte incelenmelidir.

Browser Private Cache

Browser private cache belirli kullanıcı cihazındaki browsing context'e aittir. Shared CDN gibi farklı kullanıcılara aynı entry'yi sunmaz. Yine de cihaz ortak kullanılıyorsa hassas verilerin kalıcı cache'te tutulması risk oluşturabilir. Private directive yalnızca shared cache'i sınırlar ve uygulama storage katmanlarını otomatik temizlemez. Hassasiyet seviyesine göre no-store ve logout cleanup gerekebilir.

CDN/Proxy Shared Cache

Shared cache aynı response'u çok sayıda kullanıcıya sunarak büyük performans ve origin maliyeti avantajı sağlar. Bunun güvenli olması için response gerçekten kullanıcıdan bağımsız olmalıdır. Language veya encoding gibi varyasyonlar cache key'e doğru yansıtılmalıdır. Cookie veya Authorization context yanlış dışarıda bırakılırsa bir kullanıcının verisi başka kullanıcıya ulaşabilir. Shared cache configuration güvenlik review sürecine dahil edilmelidir.

Kullanıcıya Özel Response

Kullanıcı adı, sipariş geçmişi veya hesap bilgisi içeren response personalized kabul edilir. Bu tür verinin shared cache'e girmesi çoğu senaryoda istenmez. Browser private cache kullanılacaksa freshness ve logout davranışı açıkça tanımlanmalıdır. User-specific query key içinde user veya tenant context'i bulunmalıdır. Account switch sırasında eski kullanıcının cached state'inin yeni kullanıcıya görünmemesi test edilmelidir.

Authenticated API

Authorization gerektiren endpoint cache edilemez diye genel bir kural yoktur, ancak policy son derece dikkatli tasarlanmalıdır. User-specific response private cache içinde kısa süre tutulabilir veya tamamen no-store seçilebilir. Shared caching gerekiyorsa cache key ve authorization semantics güçlü biçimde doğrulanmalıdır. UI authorization cached permission'a güvenerek gerçek güvenlik sağlamaz. Server her kritik request'te authorization kontrolünü yapmaya devam etmelidir.

Yanlış Public Cache'in Veri Sızıntısı Riski

Personalized response'un public shared cache'e yazılması ciddi veri sızıntısına yol açabilir. Bir kullanıcının response'u aynı cache key'e sahip sonraki kullanıcıya verilebilir. Bu tür hata yalnızca frontend bug değil security incident olarak değerlendirilmelidir. Cache key, Vary, cookie ve authorization context penetration test kapsamına alınmalıdır. Güvenlik belirsiz olduğunda performans kazancı yerine cache'i sınırlamak daha doğru tercihtir.

ETag Nedir?

ETag belirli bir resource representation sürümünü tanımlayan HTTP response header'ıdır. Client cached response stale olduğunda ETag değerini If-None-Match request header'ında server'a gönderebilir. Server mevcut sürüm aynıysa body göndermek yerine 304 Not Modified döndürür. ETag yalnızca bandwidth azaltmak için değil optimistic concurrency control amacıyla da kullanılabilir. Doğru version metadata cache ve mutation tutarlılığını aynı model üzerinde güçlendirebilir.

Resource Version Identifier

ETag resource'un belirli temsil sürümünü tanımlar. Server bunu content hash, version number veya başka deterministic yöntemle oluşturabilir. Resource değiştiğinde ilgili ETag değerinin de değişmesi gerekir. Client bu identifier sayesinde elindeki copy ile server copy'nin aynı olup olmadığını sorabilir. Version semantics backend implementation içinde tutarlı biçimde tanımlanmalıdır.

If-None-Match

If-None-Match client'ın sahip olduğu ETag değerini conditional GET veya HEAD request içinde server'a iletir. Server mevcut representation aynıysa full body göndermeden 304 döndürebilir. Farklıysa yeni response 200 ile gelir ve yeni ETag cache'e yazılır. Bu davranış revalidation'ın temel mekanizmalarından biridir. CDN ve browser katmanlarının validator'ı doğru ilettiği production ortamında doğrulanmalıdır.

Conditional Request

Conditional request response'un belirli şart sağlandığında gönderilmesini sağlayan HTTP mekanizmasıdır. ETag ile If-None-Match veya Last-Modified ile If-Modified-Since sık kullanılan örneklerdir. Cache revalidation bu yöntemle full transferi azaltır. Concurrency kontrolünde If-Match farklı amaçla kullanılabilir. Conditional request tasarımı resource version modeline bağlandığında hem performans hem veri doğruluğu iyileşir.

304 Not Modified

304 Not Modified server'ın client'taki cached representation'ın hâlâ geçerli olduğunu bildirdiği body içermeyen response'dur. Client daha önce sakladığı body'yi kullanmaya devam eder. Network round trip gerçekleştiği için latency sıfır değildir, ancak büyük response tekrar indirilmez. 304 oranı revalidation stratejisinin ne kadar sık cached copy'yi doğruladığını gösterebilir. Çok yüksek 304 oranı bazı resource'larda freshness süresinin gereğinden kısa olduğunu düşündürebilir.

Bandwidth Tasarrufu

ETag büyük API response veya HTML body değişmediğinde tekrar transferi önler. Özellikle mobil network ve sık tekrar navigation durumunda belirgin kazanç sağlar. Yine de request ve response header trafiği devam eder. Çok sık değişmeyen content için uygun max-age ile revalidation sayısı daha da azaltılabilir. Validator ve freshness birlikte kullanıldığında en dengeli HTTP caching modeli oluşur.

Freshness Garantisi

ETag tek başına response'un otomatik olarak her request'te doğrulanacağı anlamına gelmez. Cache-Control fresh kabul edilen süre boyunca browser cached response'u revalidation yapmadan kullanabilir. Kesin revalidation isteniyorsa no-cache gibi policy gerekir. Dolayısıyla ETag version identifier, Cache-Control ise kullanım zamanlamasının önemli parçasıdır. Freshness garantisi iki mekanizmanın birlikte doğru yapılandırılmasına bağlıdır.

Last-Modified ile ETag Arasındaki Fark

Last-Modified resource'un server tarafından bilinen son değişiklik zamanını belirtirken ETag representation sürümünü identifier ile tanımlar. Last-Modified timestamp tabanlı olduğu için bazı hızlı değişim veya distributed deployment senaryolarında daha az hassas olabilir. ETag içerik veya version modeli üzerinden daha net equality kontrolü sağlayabilir. HTTP ekosisteminde ikisini birlikte göndermek de mümkündür. Cache stratejisinde validator seçimi server altyapısı ve resource değişim modeline göre yapılmalıdır.

Last-Modified

Last-Modified response header'ı resource'un server'a göre son değiştirilme tarihini bildirir. Browser stale response'u doğrularken bu bilgiyi kullanabilir. Timestamp kolay üretildiği için static file server'larda yaygındır. İçeriğin gerçekten değişip değişmediğini byte veya semantic version seviyesinde tanımlamaz. Çok hızlı art arda güncellenen resource'larda ETag daha hassas yaklaşım sunabilir.

If-Modified-Since

Client daha önce aldığı Last-Modified değerini If-Modified-Since request header'ında gönderebilir. Server resource daha yeni değilse 304 döndürebilir. Resource değişmişse yeni body ve yeni metadata 200 response ile gelir. Bu yöntem ETag bulunmayan sistemlerde faydalıdır. ETag ve Last-Modified birlikte bulunuyorsa If-None-Match validator'ı daha güçlü tercih olabilir.

Timestamp Hassasiyeti

Timestamp-based validator zaman çözünürlüğü ve clock davranışından etkilenebilir. Aynı saniye içinde birden fazla değişiklik yapılması bazı sistemlerde fark edilmeyebilir. File metadata deploy pipeline tarafından beklenmedik biçimde yeniden yazılabilir. Bu nedenle yüksek doğruluk gereken resource versioning için ETag daha güvenilir olabilir. Last-Modified yine de crawl, display ve fallback validation açısından değerlidir.

Distributed Server Problemleri

Birden fazla origin server aynı resource için farklı timestamp veya ETag üretiyorsa client gereksiz revalidation ve full response alabilir. Validator generation deterministic olmalıdır. Content hash veya ortak version metadata bu sorunu azaltabilir. Load balancer arkasındaki node'lar aynı deployment sürümünü tutarlı biçimde tanımlamalıdır. Cache observation sisteminde node-specific validator farklılıkları izlenebilir.

ETag Kullanmanın Avantajları

ETag resource version'ını timestamp'ten bağımsız biçimde temsil edebilir. Content hash ile oluşturulduğunda gerçek representation değişimiyle doğrudan ilişkilendirilebilir. If-Match ile mutation conflict detection için de kullanılabilir. Bu sayede aynı version modeli hem read caching hem lost update prevention amacıyla kullanılabilir. ETag üretim maliyeti ve distributed consistency backend mimarisine göre değerlendirilmelidir.

Vary Header Nedir?

Vary aynı URL için response'un hangi request header değerlerine göre farklılaşabileceğini cache'lere bildirir. Language, content encoding veya başka negotiation bilgisi response seçimini etkiliyorsa URL tek başına doğru cache key olmayabilir. Vary yanlış eksik olduğunda farklı kullanıcı koşullarına ait response'lar karışabilir. Çok geniş Vary kullanımı ise cache hit oranını düşürebilir. Cache correctness ve cardinality arasında dengeli seçim yapılmalıdır.

URL Tek Başına Cache Key İçin Yeterli mi?

Birçok static resource için URL güçlü cache key temelidir, ancak her response için yeterli değildir. Aynı URL Accept-Language değerine göre farklı içerik döndürebilir. Encoding veya device negotiation da response'u değiştirebilir. Bu durumda cache kullanılan request header'ı bilmiyorsa yanlış variant sunabilir. Vary bu ilişkiyi explicit hale getirir.

Vary: Accept-Language

Server aynı URL altında dil header'ına göre farklı response üretiyorsa Vary: Accept-Language kullanabilir. Cache English ve Turkish response'ları ayrı variant olarak tutar. Çok fazla olası language header kombinasyonu cache cardinality'yi yükseltebilir. URL tabanlı language routing bazı sistemlerde daha öngörülebilir cache key sağlar. Mimari SEO ve cache davranışını birlikte düşünmelidir.

Encoding

Content encoding response representation'ını değiştirdiği için cache bu varyasyonu doğru ayırmalıdır. Modern server ve CDN'ler Accept-Encoding davranışını çoğu zaman otomatik yönetir. Brotli ve gzip variant'larının karışmaması gerekir. Cache debug sırasında response header ve content encoding kontrol edilmelidir. CDN configuration default varsayım yerine gerçek response üzerinden doğrulanmalıdır.

Personalized Responses

Vary personalized response güvenliği için tek başına yeterli çözüm değildir. Cookie veya authorization header'ını Vary içine eklemek cache key cardinality'sini aşırı büyütebilir. Kullanıcıya özel response çoğu durumda private veya no-store policy ile daha güvenli yönetilir. Shared caching gerçekten gerekiyorsa explicit tenant veya audience key tasarlanmalıdır. Güvenlik review cache strategy'nin zorunlu parçası olmalıdır.

Yüksek Cardinality Vary Riskleri

Vary içine user agent veya yüksek çeşitlilik gösteren header koymak çok sayıda cache variant oluşturabilir. Hit rate düşer ve cache storage gereksiz büyür. CDN edge'lerinde eviction daha sık yaşanabilir. Gerçekten response'u değiştirmeyen header cache key'e dahil edilmemelidir. Cardinality dashboard ve cache hit metric ile izlenebilir.

Cache Key Nasıl Tasarlanır?

Cache key belirli request'in hangi cached entry ile eşleşeceğini tanımlar ve veri tutarlılığının en kritik bileşenlerinden biridir. URL, query parameter, language, request header ve tenant bilgisi response'u etkiliyorsa key tasarımında dikkate alınmalıdır. Eksik context yanlış veri, fazla context ise düşük hit rate üretir. User-specific response için yanlış key doğrudan veri sızıntısı oluşturabilir. Cache key specification API contract kadar açık belgelenmelidir.

URL

URL çoğu HTTP cache'in temel eşleştirme bilgisidir. Static asset versioning için content hash URL içinde taşındığında doğal invalidation elde edilir. Aynı URL altında farklı semantic resource sunmak cache sorunlarını artırır. Stable API endpoint'lerde query veya header context ayrıca düşünülmelidir. URL design caching stratejisinin bir parçası olarak ele alınmalıdır.

Query Parameters

Filtre, pagination veya locale query parametresi response içeriğini değiştiriyorsa cache key'in doğal parçasıdır. Tracking parametreleri response'u değiştirmediği halde cache key fragmentation oluşturabilir. CDN bu parametreleri normalize edecek şekilde yapılandırılabilir. Query order deterministic hale getirilebilir. API query cache key'inde de aynı semantic parametreler tutarlı sırayla kullanılmalıdır.

Request Headers

Bazı request header'ları response representation'ını etkiler. Accept-Language ve Accept-Encoding yaygın örneklerdir. Vary server'ın hangi header'ların cache matching için önemli olduğunu bildirir. Her header'ın key'e eklenmesi doğru değildir. Response gerçekten değişmiyorsa gereksiz cardinality yaratır.

Language

Language response içeriğini belirliyorsa key modelinin açık parçası olmalıdır. URL prefix, domain veya Vary header farklı çözüm seçenekleridir. SEO ve CDN cache davranışı bu seçimden etkilenir. Client query cache key içinde locale bulunmazsa kullanıcı dil değiştirdiğinde eski dilde data görebilir. Language switch mutation gibi invalidation gerektiren context değişimi olarak ele alınabilir.

User/Tenant Context

Multi-tenant uygulamada aynı resource ID farklı tenant'larda farklı data temsil edebilir. Query key yalnızca resource ID kullanırsa tenant değişiminde eski cache görüntülenebilir. Tenant identifier veya account context key'in parçası olmalıdır. Shared CDN cache kullanılıyorsa güvenli partition daha da kritiktir. Account switch bütün user-specific cache katmanlarını invalidation veya cleanup ile yönetmelidir.

Yanlış Cache Key'in Veri Sızıntısı Riski

Cache key'in kullanıcı veya tenant ayrımını içermemesi bir response'un yanlış kullanıcıya sunulmasına neden olabilir. Bu hata UI seviyesinde karışıklık değil ciddi security incident oluşturur. Test suite aynı URL'ye farklı authorization context ile request göndererek leakage kontrolü yapmalıdır. CDN, Service Worker ve query cache ayrı ayrı incelenmelidir. Cache key değişiklikleri güvenlik etkisi taşıyan code olarak review edilmelidir.

Statik Asset'ler Nasıl Cache Edilmelidir?

JavaScript, CSS, font ve image gibi build çıktıları içerik hash'i taşıyorsa uzun süre cache için en güvenli kaynaklardır. İçerik değiştiğinde filename değişir ve yeni deployment yeni URL üretir. Eski URL hiçbir zaman yeni content göstermediği için uzun max-age ve immutable kullanılabilir. HTML ise yeni asset URL'lerini taşıdığı için daha kısa revalidation modeline ihtiyaç duyar. Bu ayrım deployment cache sorunlarını büyük ölçüde azaltır.

JavaScript

Production JavaScript bundle dosyaları content hash içeren filename ile yayınlanmalıdır. Hash aynı dosyanın farklı sürümlerini ayırır. Browser eski bundle'ı uzun süre saklayabilir çünkü yeni deployment farklı URL kullanır. Source map ve chunk manifest deployment retention politikasıyla uyumlu tutulmalıdır. Eski HTML kısa süreliğine eski chunk URL'sini isteyebileceği için asset'ler hemen CDN'den silinmemelidir.

CSS

CSS bundle'ları JavaScript gibi content hash ile versionlanabilir. Uzun cache lifecycle revalidation sayısını azaltır. Dynamic theme asset'i aynı URL altında değişiyorsa immutable modeli uygun olmayabilir. CSS ve JS deployment aynı manifest üzerinden eşleşmelidir. Eski HTML yeni CSS ile uyumsuz hale gelmeyecek biçimde asset retention yapılmalıdır.

Fonts

Font dosyaları genellikle nadiren değişir ve content hash ile uzun cache için uygundur. Cross-origin sunuluyorsa CORS header ve CDN policy doğru yapılandırılmalıdır. Font version değiştiğinde yeni URL kullanmak kullanıcıların eski dosyayı güvenle cache'te tutmasını sağlar. Subset veya unicode-range yapısı farklı asset key'leri oluşturabilir. Font preload yalnızca kritik kullanılan variant'lara uygulanmalıdır.

Images

Build-time image asset'leri hash ile versionlanabilir. CMS görselleri ise aynı URL altında değiştiriliyorsa farklı strategy gerekebilir. Image transformation CDN query parametreleri cache key'e dahil edilir. User avatar gibi güncellenen kaynaklarda version query veya yeni path kullanılabilir. Görsel freshness gereksinimi content tipine göre belirlenmelidir.

Content Hash

Content hash dosya içeriği değiştiğinde URL'nin de değişmesini sağlar. Bu özellik cache invalidation problemini URL seviyesinde çözer. Aynı content aynı hash kullanıyorsa browser gereksiz yeni download yapmaz. Build determinism hash churn'ünü azaltır. Deployment manifest hangi HTML sürümünün hangi hashed asset'leri kullandığını açık biçimde taşır.

Long max-age

Hashed asset URL'si immutable olduğu için bir yıl gibi uzun max-age değeri kullanılabilir. Kullanıcı tekrar ziyarette network request yapmadan cached dosyayı kullanır. Bu policy HTML veya aynı URL altında değişen API response'a uygulanmamalıdır. Cache süresi uzadıkça URL versioning doğruluğu daha kritik hale gelir. Asset rollback için eski dosyaların CDN'de belirli süre korunması gerekir.

immutable

Immutable browser'a freshness dönemi içinde resource'un değişmeyeceğini açıkça söyler. Hash'lenmiş static asset bu garantiye uygundur. Reload sırasında gereksiz validator request'lerini azaltabilir. Aynı URL altında hotfix yapma alışkanlığı varsa immutable kullanılmamalıdır. Deployment pipeline URL değişimini zorunlu kılacak şekilde tasarlanmalıdır.

Cache Busting Nedir?

Cache busting resource değiştiğinde client'ın eski cached URL yerine yeni resource URL'sini istemesini sağlayan versioning yaklaşımıdır. En güvenilir yöntem içerik hash'ini filename veya URL içine yerleştirmektir. Böylece cache entry manual olarak silinmek zorunda kalmaz. HTML yeni URL'yi referans eder ve browser doğal cache miss ile yeni asset'i indirir. Web uygulamalarında cache invalidation versioning ve güncel veri yönetimi için static asset tarafında content hash güçlü temel oluşturur.

Filename Hashing

Filename hashing build sırasında content digest'in dosya adına eklenmesidir. app.a81f21.js gibi filename her content değişiminde farklılaşır. Browser eski ve yeni dosyayı ayrı cache entry olarak görür. CDN purge gereksinimi büyük ölçüde azalır. Build manifest HTML üretiminde doğru hashed filename'i kullanmalıdır.

app.a81f21.js

app.a81f21.js content-addressed asset naming yaklaşımının basit örneğidir. İçerik değişirse a81f21 hash bölümü de değişir. Eski kullanıcı cached dosyayı tutabilir, yeni HTML yeni URL'yi ister. Bu model rollback sırasında eski asset'i tekrar kullanmayı da kolaylaştırabilir. Asset retention politikası eski client'ların halen erişebileceği chunk'ları dikkate almalıdır.

URL Versioning

Version bilgisi path veya filename içinde taşınabilir. /v42/app.js gibi yapı deployment sürümünü görünür hale getirir. Content hash kadar granular olmayabilir çünkü değişmeyen dosyalar da yeni version URL'si alabilir. Bunun sonucunda gereksiz cache miss oluşabilir. Yine de bazı platformlarda operasyon açısından daha basit uygulanabilir.

Query String Versioning

app.js?v=42 query string üzerinden cache busting yapılabilir. Modern cache katmanları query parametrelerini uygun biçimde key'e dahil edebilir. CDN configuration query normalization yapıyorsa version parametresinin atılmadığından emin olunmalıdır. Content hash filename daha açık ve yaygın deployment modeli sunar. Legacy platformlarda query versioning pratik çözüm olarak kalabilir.

Content-Hash Yaklaşımının Avantajları

Content hash yalnızca gerçekten değişen asset'in URL'sini değiştirir. Kullanıcı değişmeyen vendor chunk'ı tekrar indirmez. CDN ve browser uzun cache süresinden maksimum fayda sağlar. Deployment sırasında manual purge ihtiyacı azalır. Hash'in güvenilir olması için build output'unun deterministik olması tercih edilir.

HTML ile Hashed Asset'lerin Cache Politikası Neden Farklı Olmalıdır?

HTML application'ın hangi JavaScript ve CSS sürümünü yükleyeceğini belirleyen giriş belgesidir. HTML uzun süre immutable cache'te kalırsa yeni deployment yapılsa bile kullanıcı eski hashed asset URL'lerini görmeye devam eder. Bu nedenle HTML çoğu durumda revalidation odaklı daha kısa policy kullanır. Hashed asset'ler ise URL değiştiği için uzun süre cache edilebilir. İki katmanın farklı policy kullanması cache-friendly deployment'ın temel prensiplerinden biridir.

HTML'in Yeni Asset URL'lerini Taşıması

Build sonucu oluşturulan HTML veya server-rendered document yeni chunk manifest'ini içerir. Kullanıcı yeni HTML aldığında otomatik olarak yeni hashed asset URL'lerini öğrenir. HTML stale kalırsa uygulama yeni deployment'tan haberdar olmaz. Bu nedenle entry document freshness kritik rol oynar. Dynamic HTML personalized ise private caching policy ayrıca değerlendirilmelidir.

HTML İçin Revalidation

HTML için Cache-Control: no-cache ve validator kombinasyonu sık kullanılan güvenli modeldir. Browser cached HTML'i tutabilir ancak tekrar kullanmadan güncelliğini kontrol eder. Değişmemişse 304 alınarak bandwidth korunur. Değişmişse yeni asset manifest içeren HTML indirilir. Çok yüksek traffic uygulamalarda CDN revalidation ve edge cache ayrıca optimize edilebilir.

JS/CSS İçin Uzun Cache

Hash'lenmiş JS ve CSS content değişmeden URL değiştirmediği için uzun max-age kullanabilir. Browser tekrar ziyaretlerde network'e gitmez. Immutable directive reload sırasında da gereksiz validation'ı azaltabilir. Deploy sonrasında eski asset dosyaları hemen kaldırılmamalıdır. Eski HTML kullanan aktif tab'lar daha sonra lazy chunk isteyebilir.

Eski HTML + Yeni Bundle Problemi

Eski HTML genellikle eski bundle URL'sini istediği için yeni bundle ile doğrudan karışmaz. Sorun eski bundle deployment sırasında server veya CDN'den silinirse ortaya çıkar. Kullanıcı açık tab'da daha sonra lazy route'a geçtiğinde eski chunk URL'si 404 verebilir. Asset retention veya service worker update strategy bu riski azaltır. Client chunk load error durumunda kontrollü reload fallback'i uygulanabilir.

Yeni HTML + Eski Bundle Problemi

Hashed asset doğru kullanılıyorsa yeni HTML yeni bundle URL'sini istediği için browser eski URL'yi yanlışlıkla eşleştirmez. Hash kullanılmayan aynı filename deployment'ında ise browser stale JS sunabilir. HTML yeni API contract beklerken eski bundle farklı behavior gösterebilir. Content hash bu version skew problemini önemli ölçüde azaltır. Cache header ile filename versioning birlikte tasarlanmalıdır.

Fetch API Cache Modları

Fetch API cache seçeneği request'in browser HTTP cache ile nasıl etkileşeceğini kontrol eder. Bu seçenek server'ın response Cache-Control header'ıyla aynı şey değildir. default, no-store, reload, no-cache, force-cache ve only-if-cached farklı request davranışları tanımlar. Yanlış kullanıldığında server policy'yi beklenmedik biçimde bypass edebilir. Uygulama genel caching stratejisini Fetch cache modlarıyla sürekli zorlamak yerine doğru HTTP semantics kurmayı önceliklendirmelidir.

default

default browser'ın normal HTTP cache kurallarını uygulamasını sağlar. Fresh matching response varsa cache'ten kullanılabilir. Stale response validator ile revalidate edilebilir. Match yoksa network request yapılır ve response policy'ye göre cache'e yazılır. Çoğu normal request için başlangıç tercihi budur.

no-store

Fetch cache: "no-store" request sırasında HTTP cache'te match aramadan network'e gitmeyi ve alınan response'u HTTP cache'e eklememeyi ister. Server response no-store header'ıyla aynı katmanda benzer sonuç hedeflese de biri request seçeneğidir. Debug veya kesin network fetch gereken özel akışlarda kullanılabilir. Her request'te kullanılması HTTP caching avantajlarını ortadan kaldırır. Query cache gibi application katmanları bundan bağımsız olabilir.

reload

reload browser cache'teki response'u kullanmadan network'ten yeni response getirir, ancak alınan response HTTP cache'i güncelleyebilir. Force reload benzeri davranış için kullanılabilir. Normal freshness kontrolü için no-cache daha uygun olabilir. Kullanıcıya “veriyi yenile” butonu uygularken application query invalidation çoğu zaman daha doğru abstraction sunar. Fetch cache mode düşük seviyeli network davranışı olarak görülmelidir.

no-cache

Fetch no-cache matching response fresh olsa bile conditional validation yapılmasını sağlar. Validator varsa full body gereksiz yere indirilmeden güncellik doğrulanabilir. Server doğru ETag veya Last-Modified sağlamıyorsa avantaj azalır. Bu seçenek cached response'un saklanmasını yasaklamaz. İsim benzerliği HTTP Cache-Control no-cache ile aynı freshness fikrine yakın olsa da kullanıldığı yer request ayarıdır.

force-cache

force-cache fresh veya stale matching cached response varsa onu kullanmayı tercih eder. Match yoksa network'e gider. Güncellik kritik olmayan ve bandwidth tasarrufu öncelikli resource'larda kullanılabilir. Stale API data için bilinçsiz kullanım kullanıcıya uzun süre eski bilgi gösterebilir. Resource versioning veya iş kuralı bu tercihi desteklemelidir.

only-if-cached

only-if-cached matching response'u HTTP cache'te arar ve bulunamazsa network'e gitmez. Bu mod aynı-origin request mode şartıyla kullanılabilir. Cache-only benzeri özel offline veya debug akışında yararlı olabilir. Normal application data fetch için oldukça sınırlı kullanım alanına sahiptir. Cache miss durumunun 504 veya implementation behavior ile doğru yönetilmesi gerekir.

HTTP Cache-Control ile Fetch cache Arasındaki Fark

HTTP Cache-Control response'un cache'ler tarafından nasıl saklanıp tekrar kullanılabileceğine dair server policy'sidir. Fetch cache ise belirli client request'in browser HTTP cache ile nasıl davranacağını belirleyen request-level seçenektir. İkisini birbirine alternatif görmek doğru değildir. Server genel resource policy'yi tanımlamalı, client yalnızca özel ihtiyaçlarda request davranışını değiştirmelidir. Debugging sırasında iki katmanın birlikte etkisi incelenmelidir.

Service Worker Nedir?

Service Worker web uygulaması ile network arasında çalışan event-driven worker katmanıdır. Request'leri intercept ederek network'e gönderebilir, Cache Storage'dan cevaplayabilir veya özel fallback üretebilir. App shell precache, offline kullanım ve runtime caching için güçlü kontrol sunar. Bu güç aynı zamanda stale content ve deployment version problemlerinin sorumluluğunu uygulamaya taşır. Service Worker eklemek yalnızca performans özelliği değil ayrı lifecycle ve cache governance kararıdır.

Browser ile Network Arasında Proxy

Service Worker controlled page'in fetch request'lerini dinleyerek programatik proxy gibi davranabilir. Request doğrudan network'e geçebilir veya respondWith üzerinden custom response döndürülebilir. Bu mekanizma offline fallback ve cache strategy uygulamayı mümkün kılar. HTTPS secure context gereksinimi güvenlik modelinin parçasıdır. Yanlış route matching kritik API request'lerinin beklenmedik cache'ten gelmesine neden olabilir.

Fetch Event

Service Worker fetch event'i controlled page tarafından yapılan uygun network request'lerini gözlemleyebilir. Handler request URL, method ve destination bilgisine göre strateji seçebilir. GET static asset cache-first kullanırken API network-first kullanılabilir. Mutation request'lerini cache'lemek veya replay etmek ayrı güvenlik ve idempotency tasarımı gerektirir. Fetch handler mümkün olduğunca açık route kurallarıyla yönetilmelidir.

Offline Support

Service Worker offline durumda app shell ve cached content sunabilir. Kullanıcı daha önce ziyaret etmediği route için offline fallback sayfası gösterilebilir. API data IndexedDB veya Cache Storage'dan okunabilir. Offline write varsa mutation queue ve sync süreci gerekir. Offline özelliği test edilirken yalnızca airplane mode değil bağlantı kopma ve yeniden bağlanma geçişleri de denenmelidir.

Programmatic Caching

Cache Storage API application'a cache name oluşturma, request-response entry ekleme ve silme kontrolü verir. HTTP cache header'larının otomatik freshness modeli burada birebir uygulanmaz. Entry expiration ve versioning uygulama logic'i veya Workbox plugin'leriyle yönetilebilir. Programmatic control farklı resource türlerine özel strategy sağlar. Buna karşılık cache cleanup unutulursa storage yıllar içinde gereksiz büyüyebilir.

Background Processing

Service Worker page açık değilken bazı platform event'leri üzerinden background iş yapabilir. Push ve background sync use case'leri buna örnektir. Browser resource ve power policy bu execution'ı sınırlandırabilir. Kritik işlemin kesin zamanda çalışacağı varsayılmamalıdır. Offline mutation queue server idempotency ve retry davranışıyla birlikte güvenli tasarlanmalıdır.

Service Worker Cache Storage ile HTTP Cache Arasındaki Fark

HTTP cache browser tarafından HTTP semantics üzerinden yönetilirken Cache Storage application tarafından programatik olarak yönetilir. Aynı network request Service Worker fetch handler içinden network'e gönderildiğinde HTTP cache katmanıyla da etkileşebilir. Böylece aynı resource iki farklı cache mekanizmasında bulunabilir. Bu durum doğru tasarlanmazsa stale response'un hangi katmandan geldiğini anlamak zorlaşır. Service Worker kullanıldığında HTTP cache policy'nin ortadan kalkmadığı özellikle hatırlanmalıdır.

Browser-Managed HTTP Cache

HTTP cache freshness, validator ve request matching davranışını browser uygular. Application normal fetch yaptığında doğru server header'ları yeterli olabilir. Manual entry cleanup çoğu durumda gerekmez. Browser kendi eviction davranışını yönetir. Static asset caching için Service Worker zorunlu değildir.

Application-Managed Cache Storage

Cache Storage'a hangi response'un yazılacağı ve ne zaman silineceği application logic tarafından belirlenir. Cache name versioning veya Workbox expiration policy kullanılabilir. HTTP response Cache-Control header'ı Cache Storage entry'sini kendi başına otomatik olarak TTL sonunda silmez. Bu nedenle runtime cache policy ayrı düşünülmelidir. Debugging Application panel üzerinden yapılabilir.

Ayrı Cache Katmanları

HTTP cache ve Cache Storage aynı veriyi farklı mekanizmalarla saklayabilir. Birini temizlemek diğerini otomatik temizlemez. DevTools Disable Cache seçeneği Service Worker Cache Storage için farklı davranabilir. Production bug'ında her katman ayrı bypass edilmelidir. Mimari gereksiz double caching'i azaltacak kadar basit tutulmalıdır.

Aynı Request'in İki Cache'den Geçebilmesi

Service Worker cache miss olduğunda fetch(request) çağrısı yapabilir. Bu fetch browser HTTP cache policy'sine göre cached response döndürebilir. Developer network'e gittiğini düşünürken aslında HTTP cache hit alabilir. Kesin network revalidation gerekiyorsa request cache mode veya server header davranışı anlaşılmalıdır. Bu ayrım stale bug analizinde önemlidir.

Double-Caching Problemi

Double caching aynı response'un query cache, Service Worker Cache Storage ve HTTP cache gibi birkaç katmanda bulunmasıdır. Her katman farklı TTL kullanıyorsa üst katman alt katmanın güncel response'unu hiç görmeyebilir. Örneğin query refetch yapar ancak Service Worker eski cached response döndürür. Tek freshness owner belirlemek bu problemi azaltır. Her cache katmanının neden var olduğu mimari dokümana yazılmalıdır.

Service Worker Cache-First Stratejisi

Cache-first stratejisinde Service Worker önce Cache Storage içinde matching response arar. Entry bulunduğunda hızlı biçimde onu döndürür ve normalde network'e gitmez. Cache miss olduğunda network request yapılır ve uygun response cache'e eklenebilir. Hash'lenmiş static asset ve offline app shell için bu model güçlüdür. Dynamic business data için expiration veya versioning olmadan kullanılması eski veri riskini büyütür.

Önce Cache

Request geldiğinde ilk lookup Cache Storage üzerinde yapılır. Hit durumunda response disk veya memory storage'dan hızla dönebilir. Network latency tamamen atlanır. Bunun bedeli freshness kontrolünün request sırasında yapılmamasıdır. Resource URL versioned değilse stale copy uzun süre kalabilir.

Miss Durumunda Network

Cache entry bulunmazsa Service Worker origin veya network chain üzerinden resource'u ister. Başarılı response cache'e yazılıp client'a döndürülebilir. İlk request network latency taşır, sonraki request hızlı olur. Failure durumunda offline fallback stratejisi eklenebilir. Error response'ların yanlışlıkla cache'e yazılmaması gerekir.

Static Assets

Hashed JavaScript, CSS, font ve image cache-first için doğal adaydır. URL content ile versionlandığı için stale content riski düşüktür. Cache name deployment version ile değişebilir veya revision manifest kullanılabilir. Asset sayısı ve storage size expiration policy ile yönetilmelidir. HTTP immutable caching zaten yeterliyse Service Worker layer'ın ek faydası ayrıca değerlendirilmelidir.

Offline App Shell

Offline-first PWA temel HTML shell, CSS, icon ve critical JavaScript'i install sırasında precache edebilir. Network olmadığında kullanıcı uygulamanın temel arayüzüne ulaşır. Dynamic data local storage'dan ayrıca yüklenebilir. Shell ile API schema version uyumluluğu korunmalıdır. Yeni deployment sırasında eski tab'ların çalışmaya devam etmesi test edilmelidir.

Stale Content Riski

Cache-first response bulunduğu anda network'e gitmediği için aynı URL altındaki değişiklik kendiliğinden öğrenilmeyebilir. ExpirationPlugin, versioned URL veya manual invalidation gerekir. Kullanıcıya özel API data için yanlış cache-first kullanımı ciddi tutarlılık problemi yaratabilir. “Offline çalışıyor” başarısı data correctness testinin yerini tutmaz. Resource classification strateji seçiminden önce yapılmalıdır.

Network-First Stratejisi

Network-first stratejisinde uygulama öncelikle server'dan güncel response almaya çalışır. Başarılı network response client'a sunulur ve gerektiğinde Cache Storage güncellenir. Network başarısız olduğunda son cached copy fallback olarak kullanılabilir. Dynamic içerikte freshness ile offline dayanıklılığı arasında dengeli yaklaşım sunar. Network çok yavaş olduğunda kullanıcı uzun süre bekleyebileceği için timeout davranışı ayrıca tasarlanmalıdır.

Önce Network

Her request normal koşulda server'a gider. Bu nedenle güncel content alma olasılığı cache-first'e göre daha yüksektir. CDN ve HTTP cache yine network fetch zincirinde rol oynayabilir. User-facing latency bağlantı kalitesinden etkilenir. Gereksiz yüksek frekanslı endpoint için query staleTime ile request sayısı ayrıca azaltılabilir.

Network Failure'da Cache

Connection hatası veya timeout oluştuğunda daha önce saklanmış response kullanılabilir. Kullanıcı tamamen hata görmek yerine son bilinen veriyi görür. UI bu verinin offline veya eski olduğunu gösterebilir. Çok hassas data için stale fallback sunmamak daha doğru olabilir. Failure policy resource sınıfına göre belirlenmelidir.

Dynamic API Data

Haber, feed veya profil gibi server'da değişebilen data network-first için uygun olabilir. Uygulama her navigation'da fresh response denediği için server yükü artabilir. Query cache ve staleTime aynı request'i tekrar tekrar göndermeyi sınırlayabilir. Service Worker ile query cache birlikte kullanıldığında double freshness policy açıkça belirlenmelidir. API data JSON olarak Cache Storage yerine IndexedDB'de tutulacaksa farklı architecture düşünülebilir.

Offline Fallback

Network unavailable olduğunda cached response veya özel offline JSON döndürülebilir. Kullanıcıya hangi verinin son güncelleme zamanı gösterilebilir. Mutation yapılmasına izin veriliyorsa offline queue ayrıca gerekir. Read-only stale fallback ile offline write aynı problem değildir. Product gereksinimi iki davranışı ayrı tanımlamalıdır.

Slow Network Problemi

Network tamamen kapalı değil ancak çok yavaş olduğunda network-first uzun bekleme yaratabilir. Workbox NetworkFirst strategy belirli timeout seçenekleriyle cache fallback'i erkene çekebilir. Timeout çok kısa tutulursa sağlıklı ama biraz yavaş network'te gereksiz stale data gösterilebilir. RUM network latency dağılımı uygun threshold seçmeye yardımcı olur. Kullanıcıya loading state ve retry kontrolü verilmelidir.

Stale-While-Revalidate Stratejisi

Stale-while-revalidate hız ile güncellik arasında pratik denge sağlayan popüler caching modelidir. Cached response varsa kullanıcıya hemen sunulur ve aynı zamanda arka planda network request başlatılır. Yeni response başarılı olduğunda cache güncellenir. Mevcut kullanıcı ilk anda eski veriyi görebilir, sonraki kullanım güncel hale gelir. Bu nedenle eventual consistency kabul edilebilen verilerde güçlüdür, kritik transactional data için dikkatli kullanılmalıdır.

Cache'i Hemen Gösterme

Hit durumunda kullanıcı network round trip beklemeden content'i görür. Repeat navigation son derece hızlı hissedilir. Eski content riski UI ve business requirement ile değerlendirilmelidir. “Son güncelleme” göstergesi bazı ürünlerde güveni artırabilir. Cache entry bulunmazsa ilk request yine network bekler.

Background Fetch

Cached response sunulurken network üzerinden güncel version istenir. Kullanıcı bu request'i beklemek zorunda değildir. Network response error verirse mevcut cache kullanılmaya devam edebilir. Background request sayısı yüksek traffic'te backend yükü oluşturabilir. HTTP cache veya CDN bu maliyeti azaltabilir.

Cache Güncelleme

Background fetch başarılı olduğunda yeni response Cache Storage'a yazılır. Sonraki request yeni version'ı alır. Mevcut UI'ın da aynı session içinde güncellenmesi isteniyorsa Broadcast Update veya application event kullanılabilir. Aksi halde kullanıcı refresh veya sonraki navigation'a kadar eski content'i görür. UI reconciliation product ihtiyacına göre tasarlanmalıdır.

Eventual Consistency

Bu model bütün client'ların aynı anda en güncel veriyi görmesini garanti etmez. Cache update belirli süre içinde yayılır. Blog, avatar veya public katalog gibi verilerde bu kabul edilebilir olabilir. Inventory veya permission gibi alanlarda birkaç saniyelik fark bile kritik olabilir. Freshness sınıfları business domain uzmanlarıyla birlikte belirlenmelidir.

Hangi Veriler İçin Uygun?

Sık okunan ama değişiklikleri anında görülmek zorunda olmayan content iyi adaydır. Blog listesi, yardım dokümanı, public profil resmi veya düşük riskli referans data örnek olabilir. Güncellik gereksinimi dakika seviyesindeyse SWR güçlü kullanıcı deneyimi sağlar. Cache entry'ye updatedAt metadata eklemek gözlemlenebilirliği artırır. Product owner stale data toleransını açık biçimde tanımlamalıdır.

Stale-While-Revalidate Hangi Veriler İçin Kullanılmamalıdır?

Stale-while-revalidate her response için güvenli varsayılan değildir. Kullanıcının kararını doğrudan etkileyen fiyat, stok, permission veya finansal durum gibi bilgiler eski gösterildiğinde gerçek zarar oluşabilir. Bu verilerde network-first, kısa staleTime, push invalidation veya işlem anında server-side revalidation gerekir. UI hızlı görünmesi uğruna yanlış bilgi sunmak performans başarısı değildir. Freshness policy iş riskine göre sınıflandırılmalıdır.

Fiyat

Ürün fiyatı kampanya veya dinamik pricing nedeniyle hızlı değişebilir. Kullanıcının katalogda eski fiyat görmesi güven kaybı ve yasal sorun oluşturabilir. Liste ekranında kısa stale tolerance kabul edilse bile checkout sırasında server fiyatı mutlaka doğrulanmalıdır. Price mutation event query cache'i invalidate edebilir. CDN ve browser cache policy de fiyat freshness hedefiyle uyumlu olmalıdır.

Envanter/Stok

Stok bilgisi yüksek trafik ürünlerde saniyeler içinde değişebilir. Eski cache “stokta var” gösterirken checkout işlemi başarısız olabilir. Kısa polling, push invalidation veya kısa staleTime kullanılabilir. Reservation veya satın alma anında server source of truth olmalıdır. UI cache yalnızca kullanıcıya yaklaşık availability göstergesi olarak ele alınmalıdır.

Yetkilendirme

Permission değişikliği güvenlik açısından eski kalmamalıdır. Cached permission UI elementini göstermek için kullanılabilir ancak server authorization kararının yerini tutamaz. Kullanıcının rolü kaldırıldığında active session query cache invalidate edilmelidir. Cross-tab logout ve permission update mesajları uygulanabilir. Kritik endpoint her request'te server-side authorization yapmalıdır.

Finansal İşlemler

Hesap bakiyesi veya işlem durumu yanlış gösterildiğinde kullanıcı gerçek para hareketini yanlış yorumlayabilir. Finansal endpoint'lerde stale fallback son derece kontrollü kullanılmalıdır. Response'un “as of” timestamp'i UI'da gösterilebilir. İşlem onayı server tarafından authoritative biçimde verilmelidir. Hassas response storage için no-store gereksinimi güvenlik ekibiyle değerlendirilmelidir.

Kritik Durum Bilgisi

Sistem alarmı, güvenlik bildirimi veya operasyonel kritik status eski kaldığında yanlış karar alınabilir. Bu veriler push veya sık revalidation ile güncel tutulmalıdır. Offline durumda “son bilinen durum” açık biçimde etiketlenmelidir. Kullanıcı stale bilgiyi fresh sanmamalıdır. Fail-closed veya fail-open davranışı domain gereksinimine göre belirlenmelidir.

Kullanıcıya Özel Hassas Veriler

Hassas kullanıcı verisini Service Worker runtime cache'e koymak çoğu durumda gereksiz risk oluşturur. Logout sonrası entry temizlenmezse başka session'da görüntülenebilir. Shared cihazlarda local storage persistence ayrıca risk taşır. Gerekliyse private short-lived cache ve güçlü cleanup uygulanmalıdır. Çok hassas response için hiç cache etmemek daha güvenli olabilir.

Cache-Then-Network Pattern

Cache-then-network yaklaşımında cached data hızlı ilk render için kullanılırken network request de güncel veri almak amacıyla başlatılır. Stale-while-revalidate'e benzer görünse de application state seviyesinde cache ve network sonucunun UI'a ayrı ayrı uygulanması sık görülür. Kullanıcı önce eski data, birkaç an sonra yeni data görebilir. Bu durum flicker, list reorder ve layout shift oluşturabilir. Reconciliation tasarımı performans kadar görsel istikrar açısından da önemlidir.

Cache ve Network'ü Paralel Başlatma

Local cache read ve network request aynı anda başlatılabilir. Cache genellikle daha hızlı tamamlanır ve UI ilk data'yı gösterir. Network sonucu geldiğinde freshness karşılaştırması yapılır. Aynı version ise gereksiz render önlenebilir. Request deduplication aynı kaynak için birden fazla network call oluşmasını engeller.

Hızlı İlk Render

Kullanıcı daha önce gördüğü content'i anında görebilir. Cold-start algısı belirgin biçimde iyileşir. Cache çok eskiyse UI'ın stale olduğunu belirtmek gerekebilir. Critical action cached data doğrulanmadan aktif edilmemelidir. Hızlı render ile doğru action state birbirinden ayrılabilir.

Fresh Data Geldiğinde UI Güncelleme

Network response eski cached version'dan farklıysa state güncellenir. Structural sharing gereksiz component render'larını azaltabilir. Kullanıcının scroll position veya form edit'i yeni data ile bozulmamalıdır. Server response ile local unsaved state ayrı tutulmalıdır. Reconciliation domain modeline göre belirlenir.

UI Flicker / Layout Shift

Cache ve network data farklı layout boyutu üretiyorsa content aniden değişebilir. Skeleton veya stable container boyutları bu etkiyi azaltır. Liste sırası değiştiğinde kullanıcı odaklandığı item'ı kaybedebilir. Fresh update animation veya “yeni içerik var” kontrolü daha iyi deneyim sağlayabilir. Her background refresh'in UI'ı hemen yeniden çizmesi gerekmez.

Reconciliation

Reconciliation cached snapshot ile server'ın yeni state'ini nasıl birleştireceğinizi belirler. Basit read-only data'da server response doğrudan replace edilebilir. Local optimistic mutation varsa pending değişiklik korunmalıdır. Version veya updatedAt karşılaştırması stale response'un daha yeni local data'yı ezmesini önleyebilir. Offline-first sistemlerde bu katman domain-specific conflict resolution gerektirir.

Cache-Only ve Network-Only Ne Zaman Kullanılır?

Cache-only ve network-only uç stratejilerdir ve belirli kaynak sınıflarında anlamlıdır. Cache-only precache edilmiş ve network'ten asla alınmaması gereken resource'larda kullanılabilir. Network-only ise her seferinde server doğrulaması gereken request'lerde daha güvenlidir. İki stratejinin de offline ve latency trade-off'u açıktır. Genel varsayılan olarak değil, bilinçli resource classification sonucunda seçilmelidir.

Precached Assets

Install sırasında kesin olarak Cache Storage'a eklenen app shell asset'leri cache-only kullanılabilir. Network'e gitmeden hızlı ve deterministic response elde edilir. Cache manifest version doğru tutulmalıdır. Entry eksikse kullanıcı için güvenli fallback gerekir. Critical asset precache başarısızsa Service Worker install başarısız bırakılabilir.

Offline-Only Resources

Bazı eğitim, demo veya kullanıcı tarafından indirilen offline paketler yalnızca local storage üzerinden kullanılabilir. Network endpoint hiç olmayabilir. Cache-only bu resource lifecycle'ını netleştirir. Storage eviction riski kullanıcıya gösterilmelidir. Offline-critical data için persistent storage talebi değerlendirilebilir.

Payment Endpoint

Payment authorization ve transaction request'leri cache üzerinden cevaplanmamalıdır. Network-only veya doğrudan güvenli server request gerekir. Mutation retry idempotency key ile kontrol edilmelidir. Service Worker yanlış fetch route ile payment POST request'i intercept edip cache logic'e sokmamalıdır. Financial correctness performans optimizasyonundan önce gelir.

Analytics

Analytics event genellikle network'e gönderilir ve cached response'a ihtiyaç duymaz. Offline event queue gerekiyorsa bu response caching değil ayrı background sync problemidir. Request batching network maliyetini azaltabilir. Beacon veya queue storage privacy gereksinimleriyle tasarlanmalıdır. Analytics failure ana kullanıcı akışını engellememelidir.

Real-Time Data

Gerçek zamanlı trading, operasyon dashboard veya canlı status data için stale cached response yanıltıcı olabilir. WebSocket, SSE veya sık server fetch source of truth olarak kullanılabilir. Offline olduğunda son bilinen data ancak açık stale etiketiyle gösterilmelidir. Real-time stream reconnect sırasında snapshot reconciliation gerekir. Cache daha çok başlangıç snapshot'ı hızlandırmak için kullanılabilir.

Precache ile Runtime Cache Arasındaki Fark

Precache Service Worker install sırasında build tarafından bilinen kaynakların önceden cache'e alınmasıdır. Runtime cache ise kullanıcı uygulamayı kullanırken oluşan request'lerin belirli stratejilerle sonradan saklanmasıdır. App shell için precache, user-generated image veya API response için runtime cache daha doğal olabilir. İki cache'in version ve expiration politikaları farklıdır. Workbox revision manifest bu ayrımı yönetmeyi kolaylaştırır.

Install Sırasında Precache

Service Worker install event'inde critical asset listesi Cache Storage'a eklenebilir. Gerekli dosyalardan biri alınamazsa install'ın başarısız bırakılması eski çalışan worker'ı koruyabilir. Asset listesi build output ile otomatik üretilmelidir. Çok fazla precache first install bandwidth'ini artırır. Yalnızca offline başlangıç için gerçekten gerekli resource'lar seçilmelidir.

App Shell

App shell navigation, temel CSS ve runtime gibi uygulamanın çalışması için gereken minimum iskeleti ifade eder. Offline-first PWA bunu precache edebilir. Dynamic page data shell'den ayrı tutulur. Shell version API contract ile uyumlu olmalıdır. Yeni worker activate olurken eski tab'ların eski shell ile çalışmaya devam edebileceği hesaba katılmalıdır.

Runtime Request'ler

Kullanıcı belirli ürün görseli veya içerik route'una eriştiğinde oluşan request runtime cache'e eklenebilir. Bütün olası resource'ları install sırasında indirmek gerekmez. Cache size zaman içinde büyüyebileceği için expiration gerekir. Resource türüne göre CacheFirst veya StaleWhileRevalidate seçilebilir. User-specific response için security policy ayrıca kontrol edilmelidir.

Dinamik İçerik

Dinamik content build sırasında bilinmediği için runtime caching daha uygundur. API veya CMS image request'leri route matcher ile seçilebilir. Dynamic olması her response'un cache edilmesi gerektiği anlamına gelmez. Freshness ve personalization seviyesi strategy'yi belirler. Error response ve opaque cross-origin response caching dikkatle yönetilmelidir.

Workbox Precache Manifest

Workbox build araçları resource listesi ve revision metadata içeren precache manifest oluşturabilir. Content revision değiştiğinde yeni worker install sırasında yalnızca değişen asset'leri getirir. Activate aşamasında artık manifestte bulunmayan entry'ler temizlenebilir. Bu otomasyon manual cache name versiyonlamadaki hataları azaltır. Build pipeline ile Service Worker deployment aynı release içinde tutulmalıdır.

Service Worker Lifecycle Cache Tutarlılığını Nasıl Etkiler?

Service Worker yeni dosya yayınlanınca hemen bütün açık tab'ları otomatik olarak kontrol etmeyebilir. Yeni worker install olur, çoğu durumda waiting state'e geçer ve eski worker'ın kontrol ettiği client'lar kapanana kadar bekler. Bu davranış kullanıcıyı yarım deployment durumundan korumaya yardımcı olur. skipWaiting ve clients.claim gibi yöntemler lifecycle'ı hızlandırabilir ancak version mismatch riski yaratır. Cache tutarlılığı lifecycle ile deployment stratejisini birlikte ele almalıdır.

Install

Yeni Service Worker script bulunduğunda install event çalışır. Precache asset'leri bu aşamada alınabilir. Kritik install görevi başarısız olursa worker active olmamalıdır. Böylece çalışan eski version korunur. Install sırasında database migration gibi user data'yı bozabilecek ağır işlemlerden kaçınılmalıdır.

Waiting

Yeni worker başarıyla install olduktan sonra mevcut active worker varsa waiting state'te kalabilir. Açık eski tab'lar eski worker tarafından kontrol edilmeye devam eder. Bu durum version isolation sağlar. Kullanıcıya “yeni sürüm hazır” bildirimi verilip kontrollü reload istenebilir. Force activation kullanıcı form state'ini kaybetmemelidir.

Activate

Activate event yeni worker'ın control almaya hazırlandığı aşamadır. Eski cache name'leri burada temizlenebilir. Cleanup yalnızca yeni worker tarafından kullanılmayan cache'leri hedeflemelidir. Aynı origin üzerinde başka application cache'lerini yanlışlıkla silmemek gerekir. Cache prefix ve ownership convention kullanılmalıdır.

Eski Service Worker

Eski worker açık client'ları kontrol ederken kendi cache version'ını kullanmaya devam edebilir. Deployment server eski asset'leri hemen kaldırırsa runtime request'ler bozulabilir. Bu nedenle backward-compatible API ve asset retention önemlidir. Eski worker'ın ne kadar süre yaşayabileceği kesin kabul edilmemelidir. Telemetry client app version dağılımını izleyebilir.

Yeni Service Worker

Yeni worker yeni cache schema ve app shell ile gelir. Activate olduktan sonra yeni navigation'ları kontrol eder. Eski IndexedDB schema veya query persisted data ile uyum problemi yaşayabilir. Client app version cache metadata'ya eklenebilir. Migration ve cache buster deployment planının parçası olmalıdır.

Aynı Anda Açık Eski Tab'lar

Kullanıcı bir tab'ı günlerce açık tutabilir ve başka tab'da yeni deployment yükleyebilir. İki client farklı application version kullanabilir. IndexedDB upgrade veya BroadcastChannel message formatı bu version farkından etkilenebilir. Event payload backward-compatible tasarlanmalıdır. Gerekirse eski client kullanıcıyı kontrollü refresh'e yönlendirmelidir.

Service Worker Cache Versioning

Service Worker Cache Storage entry'lerinin uygulama deployment'ıyla uyumlu tutulması için versioning gerekir. Cache name içine sürüm eklemek basit bir yöntemdir. Yeni worker yeni cache'i doldurur ve activate sırasında eski version'ları temizleyebilir. Ancak açık eski tab hâlâ eski cache'e ihtiyaç duyuyorsa agresif cleanup onu bozabilir. Versioning planı client lifecycle ve asset backward compatibility ile birlikte tasarlanmalıdır.

Cache Name Version

app-shell-v12 gibi cache name kullanımı version ayrımını açık hale getirir. Yeni release yeni cache oluşturabilir. Eski cache'ler belirli policy ile silinir. Her deployment bütün runtime image cache'ini sıfırlamak gerekmeyebilir. Cache türüne göre bağımsız version prefix kullanılabilir.

Yeni Deployment

Deployment yeni Service Worker script ve asset manifest yayınlar. Browser update check sonucunda yeni worker install edilir. Asset URL hash'leri değiştiyse yeni dosyalar indirilir. API contract değişikliği varsa eski client compatibility korunmalıdır. Release rollback aynı cache version scheme içinde güvenli çalışmalıdır.

Old Cache Cleanup

Eski cache entry'lerinin sınırsız kalması storage tüketimini artırır. Activate event kullanılmayan cache name'lerini temizlemek için uygundur. Ancak origin üzerindeki bütün Cache Storage entry'lerini körlemesine silmek başka feature'ları etkileyebilir. Allowlist veya prefix-based cleanup yapılmalıdır. Cleanup metric ve error logları production'da izlenebilir.

Activate Event

Activate yeni worker'ın eski version cleanup işlemleri için doğal lifecycle noktasıdır. event.waitUntil cleanup promise tamamlanana kadar activation sürecini ilişkilendirebilir. Migration uzun sürüyorsa kullanıcı navigation'ı gecikebilir. Cache cleanup idempotent olmalıdır. Hata durumunda application'ın kullanılabilir kalması önceliklidir.

Kullanıcının Eski Tab'ını Bozmamak

Eski tab lazy chunk veya cached data için önceki release kaynaklarına ihtiyaç duyabilir. Yeni deployment bu kaynakları anında silerse açık session hata verebilir. Static hashed asset'leri CDN'de bir süre korumak en basit çözümlerden biridir. Service Worker cleanup version-aware yapılabilir. Kullanıcı kritik form dolduruyorsa automatic forced reload uygulanmamalıdır.

Workbox Nedir?

Workbox Service Worker caching ve offline davranışlarını daha düzenli kurmak için kullanılan modüler araç setidir. Routing, cache strategy, expiration ve precaching için hazır implementation sunar. Custom Service Worker yazma ihtiyacını tamamen ortadan kaldırmaz, ancak yaygın pattern'lerde hata riskini azaltır. Workbox kullanmak doğru freshness classification ihtiyacını değiştirmez. Hangi route'a CacheFirst veya NetworkFirst uygulanacağını yine uygulamanın business gereksinimi belirler.

Routing

Workbox routing request URL veya request destination gibi kriterlerle farklı strategy handler'ları eşleştirmeyi sağlar. Route sırası önemlidir çünkü ilk matching rule response'u kontrol edebilir. GET request'ler ve API path'leri açık biçimde ayrılmalıdır. Broad regex kritik endpoint'i yanlış cache strategy'ye sokabilir. Route listesi code review ve test kapsamına alınmalıdır.

CacheFirst

Workbox CacheFirst önce matching cached response'u kullanır ve miss durumunda network'e gider. Static asset ve uzun ömürlü image için uygundur. ExpirationPlugin entry sayısı ve yaşını sınırlayabilir. Versioned olmayan dynamic content'te stale risk taşır. Network request yalnızca miss olduğunda yapıldığı için freshness update mekanizması ayrıca gerekir.

NetworkFirst

NetworkFirst önce network response almaya çalışır. Başarı durumunda cache güncellenir, failure durumunda cached response kullanılabilir. Frequently updated data için güçlü offline fallback sunar. Network timeout ayarı yavaş bağlantıda kullanıcı bekleme süresini sınırlayabilir. Timeout değerinin gerçek mobile latency'ye göre belirlenmesi gerekir.

StaleWhileRevalidate

Workbox StaleWhileRevalidate cached response varsa hemen döndürürken network update request'i başlatır. Workbox implementation uygun request'lerde background revalidation yapar. Content freshness kritik değilse hızlı repeat experience sağlar. Runtime cache entry expiration plugin ile sınırlandırılabilir. User-specific data için security ve account cleanup ayrıca tasarlanmalıdır.

ExpirationPlugin

ExpirationPlugin Workbox runtime cache içinde maximum entry count ve maximum age gibi sınırlar uygulamayı kolaylaştırır. Image cache'in sonsuza kadar büyümesi böylece önlenebilir. Expiration check belirli request lifecycle anlarında çalışır. Storage quota yine browser kontrolündedir ve entry'ler daha erken evict edilebilir. Plugin cache correctness değil storage lifecycle problemine çözüm sunar.

Precache

Workbox precaching build manifest üzerinden revisioned asset'leri install sırasında cache'e alabilir. Yeni release'te değişen resource'lar güncellenir. Artık manifestte olmayan precache entry'leri activate sürecinde temizlenebilir. Global CSS, application shell ve kritik runtime uygun adaylardır. Çok büyük veya nadiren kullanılan asset'leri precache etmek ilk yükleme maliyetini artırabilir.

Browser Query Cache Nedir?

Query cache server-derived data'yı JavaScript application katmanında saklayan ve freshness davranışını yöneten yapıdır. HTTP cache request-response seviyesinde çalışırken query cache semantic resource key'leri üzerinden hareket eder. Aynı user query farklı component'lerde kullanıldığında request deduplication sağlayabilir. Mutation sonrası targeted invalidation yapılabilir. Bu katman frontend'de veri tutarlılığının en aktif yönetildiği yerlerden biridir.

TanStack Query

TanStack Query server state caching, request lifecycle, invalidation ve mutation yönetimi için kapsamlı API sunar. Query'ler default olarak stale kabul edilir ve belirli trigger'larda background refetch yapılabilir. staleTime freshness süresini, gcTime inactive entry'nin memory'de ne kadar tutulacağını kontrol eder. Query key design targeted invalidation için önemlidir. Persisted cache kullanılacaksa client app version ve max age ayrıca yönetilmelidir.

SWR

SWR stale-while-revalidate fikrini application query cache seviyesinde uygular. Cached data hızlı gösterilir ve gerektiğinde background revalidation yapılır. Key resource identity'yi belirler. Mutation sonrası cache update veya revalidation tetiklenebilir. HTTP SWR directive ile application SWR library aynı kavramı farklı katmanlarda uyguladığı için ikisinin davranışı ayrı anlaşılmalıdır.

Apollo Client

Apollo Client GraphQL response'larını normalized cache modeliyle yönetebilir. Entity identity ve field merge policy cache consistency açısından önemlidir. Mutation response cache'i otomatik veya explicit update edebilir. Pagination merge yanlış yapılandırılırsa duplicate veya stale entity görülebilir. GraphQL schema ve client cache policy birlikte tasarlanmalıdır.

Server State Cache

Server state cache local copy'nin server'da değişebileceğini kabul eder. Freshness, invalidation ve refetch temel operasyonlardır. Component unmount olması data'nın hemen silinmesini zorunlu kılmaz. Aynı resource tekrar açıldığında hızlı cached response gösterilebilir. Bunun güvenli olması staleTime ve business data sınıfına bağlıdır.

Request Deduplication

Birden fazla component aynı query key'i aynı anda isterse query library tek in-flight request paylaşabilir. Bu davranış network ve backend yükünü azaltır. Component sayısı request sayısıyla birebir artmaz. Key yanlış farklılaştırılırsa deduplication kaybolur. Tenant veya filter gibi gerçek response farklılığı ise key'den çıkarılmamalıdır.

TanStack Query staleTime Nedir?

staleTime query data'nın ne kadar süre fresh kabul edileceğini belirler. Fresh query normal stale-trigger refetch davranışlarını çalıştırmaz. Süre dolduğunda data cache'ten anında gösterilmeye devam edebilir, ancak belirli koşullarda background refetch yapılabilir. Default davranışta query data hızla stale kabul edilir. En doğru staleTime bütün API'ye tek değer vermek yerine veri türünün değişim sıklığına göre seçilmelidir.

Fresh Data

Query staleTime süresi içindeyse fresh kabul edilir. Component yeniden mount olduğunda yalnızca freshness nedeniyle hemen refetch yapılmaz. Bu davranış gereksiz request'leri azaltır. Fresh olmak server'da hiçbir değişiklik olmadığına dair mutlak garanti değildir. Push event veya mutation query'yi daha erken invalidate edebilir.

Stale Data

Stale query cache'te kullanılmaya devam edebilir. Stale olmak entry'nin silindiği anlamına gelmez. Mount, focus veya reconnect gibi trigger'larda background refetch gerçekleşebilir. Kullanıcı cached data'yı hemen görürken yeni data alınabilir. Bu behavior stale-while-revalidate deneyimine benzer bir kullanıcı hissi oluşturur.

Fresh Olduğu Süre

staleTime örneğin iki dakika ayarlanırsa data fetch anından itibaren iki dakika fresh kabul edilir. Bu süre business freshness SLA olarak düşünülmemelidir çünkü external invalidation daha erken gerekebilir. User profile için dakika, reference table için saatler uygun olabilir. Inventory için çok kısa süre gerekebilir. RUM request count ve stale incident verisi threshold'u optimize etmeye yardımcı olur.

Gereksiz Refetch'i Azaltma

Default stale davranış yeni developer'a çok fazla request atılıyor hissi verebilir. Gerçekte background refetch güncelliği korumaya çalışır. Veri sık değişmiyorsa staleTime artırmak network request sayısını azaltır. Refetch trigger'larını tamamen kapatmak yerine uygun freshness window seçmek daha sağlıklı olabilir. Request deduplication aynı anda başlayan duplicate fetch'leri ayrıca sınırlar.

Veri Türüne Göre staleTime

Permission, profile, feed ve country list aynı staleTime kullanmamalıdır. Reference data saatlerce fresh kalabilir. Feed birkaç saniye veya dakika sonra stale olabilir. Permission değişikliği push event ile invalidate ediliyorsa daha uzun cache kullanılabilir ancak server authorization devam etmelidir. Freshness matrix uygulamanın data contract dokümanına eklenmelidir.

gcTime Nedir?

gcTime TanStack Query'de inactive query cache entry'sinin memory'den ne zaman garbage collection ile çıkarılacağını belirler. Bu değer freshness anlamına gelmez. Bir query stale olduğu halde active veya cache'te bulunabilir. Güncel default dokümantasyonda inactive query'ler varsayılan olarak beş dakika sonra temizlenir. staleTime ve gcTime birbirinden bağımsız iki farklı yaşam döngüsü kararını temsil eder.

Freshness ile İlgili Olmaması

gcTime data'nın server'a göre ne kadar güncel olduğunu söylemez. Yalnızca inactive cache entry'nin memory retention süresini kontrol eder. staleTime sıfır olsa bile query gcTime boyunca cache'te tutulabilir. Kullanıcı route'a geri döndüğünde cached data hemen gösterilip background refetch yapılabilir. Bu ayrım doğru anlaşılmadığında gereksiz düşük gcTime ayarları kullanıcı deneyimini kötüleştirebilir.

Inactive Query

Hiçbir active observer veya mounted component query'yi kullanmıyorsa query inactive duruma geçebilir. Data hemen silinmez. Kullanıcı kısa süre sonra route'a dönerse cached result reuse edilebilir. Bu behavior navigation performansını iyileştirir. Büyük dataset'lerde memory budget nedeniyle daha kısa gcTime değerlendirilebilir.

Cache Entry'nin Memory'den Temizlenmesi

gcTime dolduğunda inactive entry memory cache'ten çıkarılabilir. Sonraki kullanım cold fetch gerektirir. Persisted query cache plugin'i kullanılıyorsa disk storage lifecycle ayrı olabilir. Çok uzun gcTime büyük application session'ında memory tüketimini artırabilir. Memory profiling bu karar için veri sağlar.

staleTime ile gcTime Farkı

staleTime “bu data yeniden doğrulanmadan ne kadar süre fresh kabul edilir” sorusuna cevap verir. gcTime ise “kimse kullanmadığında bu entry memory'de ne kadar tutulur” sorusunu cevaplar. Fresh data inactive olabilir veya stale data active olabilir. İki değer aynı olmak zorunda değildir. İdeal ayarlar veri değişim hızı, navigation davranışı ve memory budget'a göre belirlenir.

Query Key Nasıl Tasarlanmalıdır?

Query key cache'teki server resource'un identity'sidir. İyi query key aynı semantic request'lerin aynı cache entry'yi paylaşmasını, farklı request'lerin ise birbirine karışmamasını sağlar. Resource type, ID, filter, pagination ve tenant context gerektiğinde key içinde bulunmalıdır. Deterministic yapı targeted invalidation'ı kolaylaştırır. Query key design doğrudan veri tutarlılığı ve request deduplication kalitesini etkiler.

Resource

Key'in ilk bölümü genellikle resource türünü tanımlar. ["products"] ve ["users"] gibi namespace yapısı invalidation için kullanışlıdır. Mutation sonrası bütün product listeleri gerektiğinde prefix ile invalidate edilebilir. Çok genel namespace gereksiz geniş refetch oluşturabilir. Resource taxonomy backend domain model ile uyumlu tutulabilir.

Resource ID

Detail query belirli resource ID'sini key içine eklemelidir. ["product", 42] ile başka ürünlerin cache'i ayrılır. ID type consistency önemlidir ve string ile number karışımı duplicate cache oluşturabilir. Composite key gereken domain'lerde bütün identity parçaları eklenmelidir. ID user input ise normalization yapılabilir.

Filters

Category, sort veya search filter response'u değiştiriyorsa query key içinde yer almalıdır. Filter object deterministic serialize edilmelidir. Default value'lar normalize edilmezse aynı request farklı key oluşturabilir. Mutation sonrası yalnızca etkilenen filter result'lar invalidate edilebilir. Çok karmaşık filter key'leri cardinality açısından izlenmelidir.

Pagination

Page number, cursor veya page size response set'ini değiştirir. Bu bilgiler query key'in parçasıdır. Infinite query kendi page param yönetimine sahip olabilir. Mutation bir item'ı etkilediğinde hangi page cache'lerinin update edileceği belirlenmelidir. Global invalidation kolay ama gereksiz network maliyetlidir.

Tenant

Tenant değiştiğinde aynı resource ID farklı content temsil edebilir. Tenant context key'e eklenmezse veri sızıntısı riski oluşur. Account switch query client tamamen resetlenebilir. Multi-tenant SaaS'ta cache namespace tenant ID ile ayrılabilir. Authorization yine server tarafından uygulanmalıdır.

Deterministic Keys

Aynı semantic request her zaman aynı query key üretmelidir. Object property order veya optional field default'ları normalize edilmelidir. Key helper function merkezi kullanılırsa consistency artar. Ad hoc array oluşturmak büyük projede invalidation bug'larına yol açabilir. TypeScript key factory pattern compile-time güvenliği güçlendirebilir.

Targeted Invalidation

İyi key hierarchy mutation sonrasında yalnızca ilgili query'leri stale işaretlemeyi sağlar. Product 42 güncellendiğinde bütün application query cache'ini temizlemek gerekmez. Detail ve bu ürünü içeren ilgili listeler hedeflenebilir. Backend domain event affected resource key bilgisi taşıyabilir. Targeted invalidation network ve UI churn'ünü azaltır.

Mutation Sonrası Cache Nasıl Güncellenmelidir?

Mutation server state'i değiştirdiği için client cache'in eski hale gelme ihtimali doğar. Mutation başarılı olduğunda ilgili query invalidate edilebilir, server response doğrudan cache'e yazılabilir veya optimistic update reconcile edilebilir. Tek bir yöntem bütün use case'lere uygun değildir. Server hesaplanan alanlar döndürüyorsa response ile cache update değerli olabilir. Büyük dependency graph'ta targeted invalidation daha güvenli ve basit çözüm olabilir.

Query Invalidation

Mutation sonrası ilgili query key'ler stale işaretlenebilir. Active query'ler background refetch yaparak server'ın authoritative state'ini alır. Bu yöntem cache update logic'i yazmayı azaltır. Network request maliyeti vardır. Mutation response zaten güncel entity'yi içeriyorsa direct update ile birlikte kullanılabilir.

Refetch

Refetch server'dan yeni data isteyerek cache'i authoritative response ile günceller. Doğruluk açısından basittir. Çok geniş refetch listesi gereksiz request yaratır. Mutation etkilediği resource graph biliniyorsa targeted yapılmalıdır. Critical transactional data için refetch sonrası UI confirmation güvenilir yaklaşım olabilir.

Cache Update

Server mutation response tam güncel entity döndürüyorsa query cache doğrudan bu data ile update edilebilir. Ek round trip gerekmez. Ancak list, aggregate veya related query'ler de etkilenmiş olabilir. Bunlar ayrıca invalidate edilmelidir. Cache update logic backend response contract değişikliklerine duyarlı olabilir.

Optimistic Update

Optimistic update server cevabı gelmeden UI ve cache'i beklenen sonuçla günceller. Kullanıcı daha hızlı feedback alır. Mutation başarısız olursa previous snapshot geri yüklenmelidir. Concurrent mutation ve conflict durumları dikkatle ele alınmalıdır. Yüksek hata oranlı veya kritik finansal işlemde optimistic yaklaşım uygun olmayabilir.

Hybrid Yaklaşım

Pratik uygulamalarda optimistic update, server response reconciliation ve invalidation birlikte kullanılabilir. UI anında optimistic değişir. Server başarılı response döndürdüğünde gerçek entity cache'e yazılır. Ardından aggregate list veya related query'ler background refetch edilir. Bu model hızlı deneyim ile server doğruluğunu birlikte sağlar.

Query Invalidation Nedir?

Query invalidation cached data'nın artık güvenilir biçimde fresh kabul edilemeyeceğini işaretleme işlemidir. Entry'yi doğrudan silmek zorunda değildir. Active query gerekli koşullarda refetch yapabilir. Prefix-based invalidation resource ailesini, exact invalidation tek query'yi hedefleyebilir. İyi key hierarchy gereksiz global invalidation ihtiyacını azaltır.

Cached Query'yi Stale İşaretlemek

Invalidation query'nin mevcut staleTime'ını override ederek stale kabul edilmesini sağlayabilir. Cached data hemen yok olmayabilir. Kullanıcı data görmeye devam ederken background refetch yapılabilir. Bu özellik mutation sonrası UI blank state oluşmasını önler. Critical data için refetch completion ayrıca beklenebilir.

Active Query'yi Refetch Etmek

Invalidated query ekranda active ise library background refetch başlatabilir. Kullanıcı cached snapshot görmeye devam eder. New response geldiğinde component yeniden render olur. Error durumunda old data policy application'a göre korunabilir. Loading ve fetching state'leri UI'da farklı anlamlarda kullanılmalıdır.

Prefix-Based Invalidation

["products"] prefix'i bütün product related query'leri hedeflemek için kullanılabilir. Kullanımı basittir ancak büyük app'te fazla request oluşturabilir. Mutation etki alanı genişse uygundur. Daha dar query filters performansı iyileştirebilir. Invalidation count observability metric olarak izlenebilir.

Exact Invalidation

Tek resource query kesin olarak biliniyorsa exact key invalidate edilebilir. Network maliyeti daha düşüktür. Ancak ilgili list cache'i stale kalabilir. Domain relationship map hangi query'lerin etkilenebileceğini tanımlayabilir. Over-optimization correctness bug'ı oluşturmamalıdır.

Gereksiz Global Invalidation'dan Kaçınmak

Her mutation sonrası bütün query cache'i invalidate etmek kolay başlangıç çözümüdür. Büyük application'da yüzlerce refetch ve UI churn yaratabilir. Query key hierarchy olgunlaştıkça invalidation daha hedefli hale getirilmelidir. Mutation event affected resource tiplerini taşıyabilir. Network request count ve mutation-to-fresh-UI latency doğru granularity'yi değerlendirmeye yardımcı olur.

Optimistic Update Nedir?

Optimistic update kullanıcının yaptığı değişikliğin server tarafından başarılı olacağını varsayarak UI'ı önceden günceller. Like, todo toggle veya düşük riskli preference işlemlerinde deneyimi hızlandırabilir. Uygulama mutation öncesi cache snapshot'ını saklar. Server failure veya conflict döndürürse rollback yapılır. Bu teknik hızlı hissettirir, ancak veri modelinde conflict olasılığı yüksekse daha dikkatli uygulanmalıdır.

Server Response Beklemeden UI Güncellemek

Kullanıcı action sonrasında sonucu birkaç yüz milisaniye beklemeden görür. Perceived latency azalır. Local cache beklenen yeni değerle güncellenir. Mutation request arka planda server'a gider. UI pending state göstergesi gerçek confirmation henüz gelmediğini belirtebilir.

Previous Cache Snapshot

Mutation başlamadan önce ilgili cache data'nın snapshot'ı alınır. Hata durumunda bu data rollback için kullanılır. Concurrent mutation varsa tek snapshot yeterli olmayabilir. Version veya operation log daha güvenli model gerekebilir. Large cache clone memory maliyeti oluşturabileceği için yalnızca gerekli data saklanmalıdır.

Mutation

Optimistic UI update sonrasında gerçek mutation server'a gönderilir. Request idempotency ve retry behavior önemlidir. Server validation optimistic varsayımı reddedebilir. Client pending operation ID ile response'u doğru local değişiklikle eşleştirmelidir. Network offline olursa queue veya rollback product kararına göre uygulanır.

Success Reconciliation

Server success response local optimistic state ile birebir aynı olmayabilir. Server timestamp, ID veya calculated field ekleyebilir. Cache gerçek server entity ile reconcile edilmelidir. Related aggregate query'ler invalidate edilebilir. Pending flag success sonrasında kaldırılır.

Failure Rollback

Server request başarısız olduğunda optimistic değişiklik geri alınabilir. Kullanıcıya hata ve tekrar deneme seçeneği gösterilir. Bu sırada başka mutation aynı data'yı değiştirmişse eski snapshot'a körlemesine rollback yapmak yeni değişikliği silebilir. Operation-based rollback daha güvenli olabilir. Conflict senaryoları automated test içinde yer almalıdır.

Optimistic Update Veri Tutarlılığını Nasıl Bozabilir?

Optimistic update local UI'ı server response öncesinde değiştirdiği için client ile source of truth arasında geçici fark oluşturur. Normal başarı akışında bu fark kısa sürer. Validation failure, concurrent edit veya out-of-order response olduğunda fark kalıcı bug'a dönüşebilir. Version metadata ve rollback modelinin doğru tasarlanması gerekir. Kritik domain'lerde pessimistic confirmation daha güvenli olabilir.

Server Validation Failure

Client bir değerin geçerli olduğunu varsayabilir ancak server business rule nedeniyle mutation'ı reddedebilir. Optimistic UI bu sırada yanlış sonuç göstermiş olur. Failure response geldiğinde rollback ve açıklayıcı hata gerekir. Client validation yalnızca erken feedback sağlar ve server validation'ın yerini tutmaz. Repeated failure oranı optimistic yaklaşımın uygunluğunu sorgulatabilir.

Concurrent Mutation

Kullanıcı aynı entity üzerinde hızlı biçimde birden fazla mutation başlatabilir. Response'lar request sırasından farklı dönebilir. İlk response ikinci optimistic state'i yanlışlıkla ezebilir. Mutation ID veya latest-version kontrolü gerekir. Query cancellation ve serialized mutation bazı domain'lerde çözümü basitleştirir.

Başka Kullanıcının Güncellemesi

Collaborative sistemde entity başka kullanıcı tarafından aynı anda değiştirilebilir. Client eski version üzerinden optimistic update yaparsa server conflict tespit etmelidir. Last write wins bazı data için kabul edilebilir, bazı data için kayıp oluşturur. ETag veya version field optimistic concurrency sağlar. Conflict UI kullanıcıya merge seçeneği sunabilir.

Version Conflict

Client mutation yaptığı version server current version'dan eskiyse conflict vardır. If-Match header ve ETag bunun HTTP seviyesinde tespit edilmesini sağlar. Server 412 gibi conflict response döndürebilir. Client latest data'yı çekip kullanıcı değişikliğini yeniden uygulayabilir. Domain-specific merge gerektiğinde otomatik overwrite yapılmamalıdır.

Rollback Problemleri

Rollback için eski snapshot kullanmak concurrent state değişikliklerini silebilir. Bir mutation başarısız olurken başka mutation başarılı olmuş olabilir. Operation patch tersine çevirme veya version-aware rollback daha güvenlidir. UI state ve server cache ayrı tutulmalıdır. Failure testleri yalnızca tek request değil race condition senaryolarını içermelidir.

Optimistic Concurrency Control

Optimistic concurrency control aynı veriyi birden fazla actor güncellerken lost update problemini kilit kullanmadan tespit etmeyi amaçlar. Client okuduğu version bilgisini mutation sırasında server'a geri gönderir. Server current version ile karşılaştırır. Eşleşmiyorsa mutation conflict olarak reddedilir. Bu model cache ve mutation tutarlılığında version metadata'nın değerini artırır.

Version Field

Entity içinde integer version field her update'te artırılabilir. Client mutation request'te okuduğu version'ı gönderir. Server aynı değilse conflict döndürür. Bu yaklaşım database row-level optimistic locking ile kolay uygulanabilir. API response version field'ı query cache metadata olarak saklanabilir.

UpdatedAt

UpdatedAt timestamp basit conflict sinyali olarak kullanılabilir. Client son gördüğü timestamp'i mutation request'te gönderir. Precision ve clock handling doğru değilse aynı anda yapılan değişiklikler kaçabilir. Server-generated monotonic version daha güçlü olabilir. UpdatedAt yine UI freshness göstergesi için faydalıdır.

ETag

ETag entity representation version'ını HTTP header seviyesinde taşır. GET response ETag verir ve client mutation sırasında bunu kullanabilir. Content değiştiğinde yeni ETag üretilir. Cache validation ile concurrency control aynı version identifier'dan yararlanabilir. Weak ETag semantics mutation conflict için dikkatle değerlendirilmelidir.

If-Match

If-Match mutation'ın yalnızca server resource ETag'i client'ın bildiği version ile eşleşiyorsa uygulanmasını sağlar. Eşleşme yoksa server precondition failure döndürebilir. Böylece başka kullanıcının güncellemesi sessizce ezilmez. Client conflict UI veya refetch akışı başlatır. REST API'lerde güçlü optimistic concurrency pattern'idir.

Conflict Response

Conflict response yalnızca generic hata mesajı olmamalıdır. Client'ın latest entity'yi çekip kullanıcıya ne değiştiğini gösterebilmesi gerekir. 409 veya 412 gibi status domain design'a göre kullanılabilir. Retry otomatik yapılacaksa kullanıcının niyetini yanlışlıkla ezmemelidir. Conflict telemetry domain'de concurrent edit sıklığını gösterir.

Lost Update'ı Önlemek

Lost update iki actor aynı eski version'ı okuyup sırayla yazdığında ilk değişikliğin görünmeden kaybolmasıdır. Version check ikinci write'ı conflict olarak durdurur. Client merge veya tekrar edit akışı sunar. Finansal, inventory veya collaborative data için bu kontrol önemlidir. Cache freshness tek başına lost update problemini çözmez.

IndexedDB Nedir?

IndexedDB browser içinde kalıcı structured data saklamak için kullanılan asynchronous transactional database API'sidir. Büyük veri setleri, index'li sorgular ve offline-first senaryolar için Web Storage'dan daha uygundur. Object store ve transaction modeli relational database ile birebir aynı değildir. Schema değişiklikleri database version artırılarak upgradeneeded sürecinde yapılır. Browser storage eviction ihtimali nedeniyle kritik verinin tek kopyası olarak kullanılması ancak açık offline architecture ile anlamlıdır.

Persistent Structured Storage

IndexedDB object ve structured clone uyumlu verileri browser restart sonrasında da saklayabilir. Storage best-effort veya persistent policy'ye tabi olabilir. Büyük API dataset'leri cold start hızlandırmak için kullanılabilir. Data source of truth değilse server version metadata ile birlikte tutulmalıdır. Logout sırasında user-specific object store entry'leri temizlenmelidir.

Object Stores

Object store belirli entity türlerinin kayıtlarını tutan temel IndexedDB yapısıdır. Key path veya auto increment key kullanılabilir. Schema normalization ihtiyaçlarına göre product, mutationQueue veya metadata gibi ayrı store'lar oluşturulabilir. Transaction birden fazla store'u birlikte kapsayabilir. Store sayısı business domain ve query pattern'e göre belirlenmelidir.

Keys

IndexedDB key kayıt identity'sini belirler. String, number ve belirli structured key türleri kullanılabilir. Server resource ID doğal key olabilir. Multi-tenant data için composite key tenant context'i içermelidir. Key design migration ve query performansını etkiler.

Indexes

Index object store içindeki kayıtları farklı property üzerinden hızlı sorgulamaya yardımcı olur. Category, updatedAt veya status gibi alanlar index olabilir. Gereksiz çok index write maliyeti ve storage kullanımını artırır. Query pattern ölçülerek eklenmelidir. Schema upgrade sırasında index create veya delete işlemi yapılabilir.

Transactions

IndexedDB transaction belirli operation grubunun tutarlı biçimde uygulanmasını sağlar. Readwrite transaction sırasında ilgili object store'lar üzerinde değişiklik yapılabilir. Async flow transaction lifecycle'a uygun yönetilmelidir. Uzun network request transaction içinde bekletilmemelidir. Offline queue update gibi multi-step local değişiklik transaction ile korunabilir.

Asynchronous API

IndexedDB operation'ları asynchronous çalışır ve main thread'i localStorage kadar doğrudan bloklamaz. Native API event ve request modeline sahiptir. Promise wrapper library'leri kullanım ergonomisini artırabilir. Büyük data serialization yine CPU maliyeti oluşturabilir. Performance profile cold read ve write latency'yi gerçek cihazda ölçmelidir.

IndexedDB Ne Zaman Cache Olarak Kullanılmalıdır?

IndexedDB yalnızca cache response saklamak için değil büyük structured local state gerektiren uygulamalarda değerlidir. Offline-first uygulamalar, binlerce kayıttan oluşan dataset veya browser restart sonrasında tekrar kullanılmak istenen data iyi adaydır. Küçük ve kolay yeniden alınabilir birkaç API response için query memory cache daha basit olabilir. Persistent layer eklemek schema migration ve cleanup sorumluluğu getirir. Karar performance kazancı ile maintenance maliyeti birlikte değerlendirilerek verilmelidir.

Offline-First Uygulamalar

Offline-first app kullanıcı açtığında network olmasa bile local data ile çalışmalıdır. IndexedDB structured entity ve pending mutation queue için uygundur. Server reconnect olduğunda sync engine değişiklikleri uzlaştırır. Conflict resolution domain modelinin parçasıdır. Offline state'in kullanıcıya görünür olması güveni artırır.

Büyük API Dataset'leri

On binlerce kayıt her application açılışında network üzerinden alınmak zorunda olmayabilir. IndexedDB last snapshot'ı saklayabilir. Server delta sync veya version endpoint değişen kayıtları getirir. Full dataset replacement yerine incremental update bandwidth azaltır. Schema ve data version ayrı metadata olarak tutulmalıdır.

Cold-Start Performance

Application ilk açılışta cached local dataset'i okuyarak UI'ı hızla gösterebilir. Network güncellemesi background çalışır. IndexedDB read'in kendisi de disk ve serialization maliyeti taşıdığı için ölçülmelidir. Çok büyük object tek record olarak saklanmamalıdır. Progressive query gerekli viewport data'yı önce sunabilir.

Complex Local Query

IndexedDB index'ler offline durumda filtreleme ve lookup yapmaya yardımcı olur. Büyük dataset'i memory'ye tamamen yükleyip JavaScript filter çalıştırmak gerekmeyebilir. Query capability relational SQL kadar zengin değildir. Domain query'leri index yapısına uygun tasarlanmalıdır. Karmaşık analytics için WebAssembly veya local processing ayrı değerlendirilebilir.

Browser Restart Sonrası Veri

Memory cache browser kapanınca kaybolur. IndexedDB uygun storage koşullarında sonraki session'da data'yı korur. Kullanıcı repeat visit'te hızlı başlangıç alabilir. Browser storage pressure altında best-effort data evict edilebilir. Bu nedenle server'dan yeniden oluşturulabilen cache entry'ler kaybolmaya dayanıklı tasarlanmalıdır.

IndexedDB Source of Truth Olmalı mı?

IndexedDB'nin source of truth olup olmayacağı uygulamanın offline modeline bağlıdır. Normal online-first web uygulamasında server authoritative source olarak kalır ve IndexedDB yalnızca cache görevi görür. Gerçek offline-first uygulamada kullanıcı local data üzerinde uzun süre çalışabilir ve local database geçici authoritative state haline gelebilir. Sonradan server synchronization conflict çözümü gerektirir. Bu karar kod seviyesinde değil product ve domain seviyesinde verilmelidir.

Cache Olarak IndexedDB

Server authoritative ise IndexedDB kayıtları yeniden oluşturulabilir cache olarak kabul edilir. Her record server version veya updatedAt metadata taşıyabilir. Stale entry background refresh ile güncellenir. Storage eviction data loss değil performans kaybı oluşturmalıdır. User-specific cache logout sırasında silinmelidir.

Offline-First Local Source of Truth

Offline-first application kullanıcı mutation'larını network olmadan local database'e yazar. UI local state'i authoritative kabul eder. Server bağlantısı geldiğinde pending operations sync edilir. Bu sırada başka actor değişiklikleri conflict oluşturabilir. Operation log veya CRDT gibi ileri modeller domain ihtiyacına göre değerlendirilebilir.

Server Synchronization

Sync engine local ve server version'ları karşılaştırır. New server changes indirilebilir ve pending local mutations upload edilir. Ordering ve idempotency kritik hale gelir. Partial failure sonrası retry hangi operation'ın uygulandığını bilmeli­dir. Sync checkpoint metadata duplicate processing'i azaltır.

Conflict Resolution

Local ve remote aynı entity'yi değiştirdiğinde resolution policy gerekir. Last write wins basit ama veri kaybı oluşturabilir. Version-based conflict kullanıcıya manual merge sunabilir. Bazı field'lar otomatik merge edilebilir. Domain-specific rule generic cache library'nin tek başına çözebileceği bir konu değildir.

Uygulama Modeline Göre Karar

Read-heavy content app ile field worker offline application aynı persistence modelini kullanmamalıdır. İlkinde IndexedDB optional cache olabilir. İkincisinde local database kritik iş verisi taşıyabilir. Backup, export ve recovery requirement buna göre değişir. Architecture decision record bu farkı açık biçimde belgelemelidir.

IndexedDB Schema Versioning

IndexedDB schema object store ve index değişikliklerini database version üzerinden yönetir. Daha yüksek version ile database açıldığında upgradeneeded event tetiklenir. Migration sırasında eski kayıtlar yeni formatla uyumlu hale getirilebilir. Başka tab eski database connection'ı açık tutuyorsa upgrade blocked olabilir. Production migration planı çoklu tab ve rollback senaryolarını içermelidir.

Database Version

indexedDB.open çağrısındaki integer version schema sürümünü belirler. Version artırıldığında upgrade transaction başlar. Sürüm geriye düşürülemez gibi düşünülmeli ve rollback strategy buna göre tasarlanmalıdır. Application version ile database version aynı olmak zorunda değildir. Migration sequence source control içinde tutulmalıdır.

upgradeneeded

upgradeneeded database yeni oluşturulduğunda veya daha yüksek version açıldığında çalışır. Object store ve index schema değişiklikleri bu transaction içinde yapılır. Migration başarısız olursa transaction rollback olabilir. Ağ request'i gibi dış bağımlılıklar bu aşamaya konulmamalıdır. Migration deterministic ve local data üzerinden çalışmalıdır.

Object Store Migration

Yeni entity type için store eklenebilir veya mevcut yapı yeniden tasarlanabilir. Store rename doğrudan desteklenmeyen durumda copy strategy gerekebilir. Büyük dataset migration startup süresini uzatabilir. Lazy migration bazı use case'lerde daha iyi olabilir. User data kaybı yaşanmaması için test fixture'ları eski production schema'ları içermelidir.

Index Migration

Query pattern değiştiğinde yeni index eklenebilir veya eskisi kaldırılabilir. Index creation büyük dataset üzerinde maliyetli olabilir. Migration sırasında browser thread ve disk kullanımı ölçülmelidir. Index uniqueness constraint mevcut data ile conflict yaratabilir. Deployment öncesi representative database snapshot üzerinde test yapılmalıdır.

Eski Verilerin Dönüştürülmesi

Field rename veya data format değişikliği eski record'ların transform edilmesini gerektirebilir. Migration idempotent olmalı ve beklenmeyen data'yı güvenli biçimde ele almalıdır. Çok büyük dataset tek transaction içinde uzun sürebilir. Alternatif olarak schema version metadata ile read-time dönüşüm uygulanabilir. Data loss riskinde backup veya yeniden server fetch seçeneği değerlendirilmelidir.

IndexedDB Upgrade Başka Tab Tarafından Neden Bloklanabilir?

IndexedDB schema upgrade tüm açık connection'ların yeni version change'e izin vermesini gerektirir. Kullanıcının eski application version'ı başka tab'da database'i açık tutuyorsa upgrade blocked event oluşabilir. Bu durum gerçek production ortamında sık gözden kaçar. Eski tab versionchange event aldığında connection'ı kapatabilir ve kullanıcıya refresh mesajı gösterebilir. Cross-tab communication migration UX'ini daha güvenli hale getirir.

Eski Tab'da Açık Database Connection

Tab A eski schema ile IDBDatabase connection'ı açık tutabilir. Tab B yeni deployment'la daha yüksek version açmaya çalışır. Browser mevcut connection kapanmadan upgrade transaction başlatamaz. Bu nedenle application connection lifecycle'ını yönetmelidir. Uzun yaşayan hidden tab'lar migration'ı bekletebilir.

Version Change

Yeni tab yüksek version istediğinde eski connection'a versionchange event gönderilebilir. Eski client event'i dinleyip database connection'ını kapatmalıdır. Ardından UI kullanıcıya sayfanın güncellenmesi gerektiğini söyleyebilir. Eski code yeni schema ile çalışmaya devam etmemelidir. Event handling deployment standardının parçası olmalıdır.

blocked Event

Upgrade request başka connection nedeniyle ilerleyemiyorsa blocked event oluşur. Yeni tab sonsuz loading göstermek yerine kullanıcıya açıklayıcı mesaj vermelidir. Telemetry blocked duration ve browser session bilgisini toplayabilir. BroadcastChannel ile diğer tab'a refresh isteği gönderilebilir. Force data delete çözüm olarak kullanılmamalıdır.

Diğer Tab'lara Update Mesajı

BroadcastChannel aynı origin tab'larına application update veya database migration mesajı gönderebilir. Eski tab form state içeriyorsa kullanıcıya önce kaydetme fırsatı verilmelidir. Otomatik reload data loss yaratmamalıdır. Channel message versioned payload kullanmalıdır. Farklı application version'ları message formatını anlayabilmelidir.

Safe Migration UX

Kullanıcı yeni tab açtığında “uygulamanın yeni sürümü hazır, diğer sekmeleri yenileyin” mesajı gösterilebilir. Eski tab connection'ı kapatınca migration devam eder. Kritik offline mutation queue migration öncesi korunmalıdır. Hata durumunda recovery path bulunmalıdır. Production migration yalnızca happy path ile test edilmemelidir.

localStorage ile IndexedDB Arasındaki Fark

localStorage küçük string key-value veriler için synchronous API sunarken IndexedDB asynchronous structured database yaklaşımı sağlar. Büyük payload localStorage'a yazıldığında main thread bloklanabilir. IndexedDB object store, index ve transaction özellikleriyle daha büyük data için uygundur. localStorage basit preference gibi veri için daha düşük geliştirme maliyetine sahiptir. Veri boyutu ve query ihtiyacı storage seçiminde belirleyici olmalıdır.

Synchronous vs Asynchronous

localStorage getter ve setter çağrıları synchronous çalışır. Büyük serialization veya storage erişimi kullanıcı interaction sırasında main thread'i bloklayabilir. IndexedDB operation'ları asynchronous request modeline sahiptir. Bu nedenle büyük veri için daha uygun performans profili sunar. Küçük birkaç preference için localStorage maliyeti genellikle kabul edilebilir düzeydedir.

String-Only vs Structured Data

localStorage yalnızca string value saklar. Object saklamak için JSON serialize ve parse gerekir. IndexedDB structured clone uyumlu object'leri daha doğal saklayabilir. Blob ve daha zengin data tipleri de desteklenebilir. Schema ve query ihtiyacı büyüdükçe IndexedDB daha uygun hale gelir.

Veri Boyutu

Web Storage quota browser'a göre sınırlıdır ve büyük dataset için tasarlanmamıştır. IndexedDB origin storage quota içinde daha büyük veri tutabilir. Kesin quota değerine güvenmek doğru değildir. navigator.storage.estimate() yaklaşık usage ve quota bilgisi sağlayabilir. Cache eviction ve cleanup strategy yine gereklidir.

Main-Thread Blocking

localStorage synchronous olduğu için sık veya büyük erişim interaction responsiveness'i etkileyebilir. JSON.parse büyük payload üzerinde ayrıca CPU maliyeti yaratır. IndexedDB asynchronous olsa da büyük serialization tamamen bedava değildir. Critical rendering sırasında storage read sayısı sınırlandırılmalıdır. Performance trace gerçek maliyeti göstermelidir.

Query/Index

localStorage key üzerinden basit lookup sunar ve secondary index kavramı yoktur. Büyük JSON array içinden filter yapmak için bütün payload parse edilmelidir. IndexedDB index belirli property üzerinde daha verimli lookup sağlar. Offline search veya status filtering için bu önemli farktır. Query pattern schema design sırasında düşünülmelidir.

Hangi Veri Nerede Tutulmalı?

Tema, dil ve küçük preference localStorage için uygundur. Büyük structured API cache, offline entity ve mutation queue IndexedDB için daha iyi adaydır. Hassas auth token storage güvenlik modeline göre ayrıca değerlendirilmelidir. Server state yalnızca storage kolay olduğu için kalıcı hale getirilmemelidir. Her veri için persistence ihtiyacı ayrı sorulmalıdır.

localStorage Cache İçin Kullanılmalı mı?

localStorage teknik olarak cache verisi saklayabilir, ancak büyük server response cache'i için güçlü varsayılan değildir. Synchronous API ve string serialization büyük payload'larda performans maliyeti oluşturur. Küçük preference veya düşük hacimli metadata için gayet pratiktir. Hassas kullanıcı verisinin uzun süre localStorage içinde tutulması güvenlik riskini artırabilir. Cache persistence gerekiyorsa veri boyutu ve erişim pattern'ine göre IndexedDB tercih edilebilir.

Küçük User Preference

Kullanıcının table density, sidebar state veya dismissed notice gibi küçük preference'ları localStorage'da tutulabilir. Bu data server sync gerektirmeyebilir. Key'e application namespace eklemek collision riskini azaltır. Schema formatı değişirse version prefix kullanılabilir. Kullanıcı storage'ı temizlediğinde uygulama güvenli default'a dönebilmelidir.

Theme

Light veya dark theme tercihi localStorage için yaygın örnektir. İlk paint öncesi theme okunarak flash azaltılabilir. Read küçük tutulduğu için synchronous maliyet düşüktür. System preference fallback olarak kullanılabilir. Account-level theme server'da tutuluyorsa local ve remote preference reconciliation tanımlanmalıdır.

Language

Language preference küçük string value olduğu için localStorage'da tutulabilir. URL locale routing kullanılıyorsa source of truth URL olabilir. Login user profile'dan language geliyorsa local preference ile server value arasında öncelik kuralı gerekir. Cache key language context'ini doğru içermelidir. Dil değişiminde query cache'in locale-dependent data'sı invalidate edilmelidir.

Büyük API Payload'larından Kaçınmak

Megabyte seviyesinde JSON localStorage'a yazmak serialize ve storage I/O sırasında main thread'i bloklayabilir. Her read JSON.parse maliyeti taşır. Büyük data için IndexedDB veya normal query cache daha uygun olabilir. Payload server'dan kolay yeniden alınabiliyorsa persistence gereksiz olabilir. Performance optimization storage katmanı eklemekle değil toplam lifecycle maliyetini azaltmakla ilgilidir.

Hassas Verilerden Kaçınmak

localStorage JavaScript erişimine açık olduğu için XSS durumunda data okunabilir. Long-lived access token storage security riski taşır. Hassas kişisel data da gereksiz kalıcı tutulmamalıdır. HttpOnly secure cookie gibi authentication yöntemleri architecture gereksinimine göre değerlendirilebilir. Cache performansı güvenlik sınırlarını zayıflatmamalıdır.

Browser Storage Kalıcı mıdır?

Browser storage kullanmak verinin sonsuza kadar cihazda kalacağını garanti etmez. Origin storage çoğu durumda best-effort olarak yönetilir ve storage pressure altında browser entry'leri silebilir. Kullanıcı site verilerini manuel olarak temizleyebilir. Persistent storage izni bazı origin'lerde eviction riskini azaltabilir. Cache edilebilir veriler kaybolduğunda uygulama server'dan yeniden oluşturabilmelidir.

Best-Effort Storage

Default storage çoğu browser'da best-effort davranışa tabidir. User agent disk baskısında origin data'yı evict edebilir. Hangi origin'in ne zaman silineceği browser policy'sine bağlıdır. Cache data kaybı application crash yaratmamalıdır. Offline-critical user work için daha güçlü persistence yaklaşımı gerekebilir.

Persistent Storage

navigator.storage.persist() browser'dan origin storage'ını persistent olarak değerlendirmesini isteyebilir. Browser isteği kendi kurallarına göre kabul veya reddedebilir. Bu izin cache edilmiş yeniden üretilebilir image'lar için gereksiz olabilir. Offline user-created data daha iyi adaydır. Kullanıcı cihaz depolamasına saygı gösterilmelidir.

Storage Pressure

Cihaz disk alanı azaldığında browser cache ve origin storage üzerinde eviction uygulayabilir. Büyük image cache veya unused IndexedDB snapshot bu baskıyı artırır. Application kendi max storage policy'sini belirlemelidir. navigator.storage.estimate() yaklaşık kullanım izleme sağlar. Threshold yaklaşımında eski entry'ler proaktif temizlenebilir.

Browser Eviction

Browser best-effort storage'ı application'a sormadan silebilir. Bu nedenle cache miss normal durum olarak işlenmelidir. IndexedDB bulunamadığında schema yeniden kurulabilir. Offline mutation queue gibi kritik data için persistence ve recovery daha güçlü tasarlanmalıdır. Telemetry unexpected local data loss oranını izleyebilir.

Kullanıcının Veriyi Temizlemesi

Kullanıcı browser settings üzerinden site data'yı her zaman silebilir. Application bunu hata olarak değil fresh install benzeri durum olarak ele almalıdır. Auth cookie silindiyse cached user-specific data da güvenli biçimde kullanılmamalıdır. Local draft kaybı product UX açısından açıklanabilir. Export veya server sync kritik user content'i korumaya yardımcı olur.

Storage Quota Nasıl Yönetilir?

IndexedDB ve Cache API aynı origin storage bütçesinin önemli bölümünü kullanabilir. Kesin quota browser, cihaz ve kullanıcı etkileşimine göre değişebildiği için sabit rakama güvenilmemelidir. Usage estimate, entry count ve expiration birlikte izlenmelidir. QuotaExceededError uygulamayı kullanılamaz hale getirmemelidir. Eski cache entry'leri LRU veya TTL politikasıyla temizlenebilir.

IndexedDB

IndexedDB büyük structured data tutabildiği için storage budget'ın önemli bölümünü tüketebilir. Snapshot version sayısı sınırlanmalıdır. Eski offline cache dataset'leri migration sonrası temizlenebilir. User-created unsynced data cache'ten farklı priority ile korunmalıdır. Storage monitor data class bazlı kullanım gösterebilir.

Cache API

Image ve runtime response cache'i hızlı büyüyebilir. Workbox ExpirationPlugin maxEntries ve maxAge sınırı sağlayabilir. Large video veya opaque response entry'leri özellikle dikkat ister. Cache name bazlı storage kullanımını browser API tam ayrıntıyla her zaman sunmayabilir. Application kendi metadata index'ini tutabilir.

Web Storage

localStorage quota daha sınırlıdır ve synchronous write failure oluşturabilir. Büyük data write sırasında exception handle edilmelidir. Küçük preference dışında storage kullanımını düşük tutmak en iyi yaklaşımdır. JSON cache entry expire metadata ile silinebilir. Web Storage'ı genel database gibi büyütmekten kaçınılmalıdır.

navigator.storage.estimate()

navigator.storage.estimate() origin'in yaklaşık usage ve quota değerlerini asynchronous olarak sağlar. Değerler güvenlik ve implementation nedenleriyle kesin olmayabilir. Dashboard veya debug telemetry storage pressure trend'ini takip edebilir. Her request'te çağırmak gerekli değildir. Büyük download öncesi yaklaşık capacity kontrolü yapılabilir.

QuotaExceededError

Storage write quota sınırına ulaştığında hata oluşabilir. Application önce düşük priority cache entry'lerini temizleyip tekrar deneyebilir. Kullanıcının unsynced çalışmasını sessizce silmek doğru değildir. Error telemetry hangi storage operation'ın başarısız olduğunu göstermelidir. Offline-critical feature quota failure UX'ini açık biçimde tasarlamalıdır.

Eski Cache Entry'lerini Temizlemek

TTL süresi geçmiş veya uzun zamandır kullanılmayan entry'ler cleanup edilebilir. LRU metadata son erişim zamanını tutabilir. Max storage threshold aşıldığında düşük değerli asset'ler önce silinir. Hashed asset browser HTTP cache tarafından zaten yönetiliyorsa duplicate Cache Storage entry'leri azaltılabilir. Cleanup periyodik veya write-before policy ile uygulanabilir.

Persistent Storage Ne Zaman İstenmelidir?

Persistent storage talebi kullanıcı cihazında cache edilebilir her veriyi korumak için kullanılmamalıdır. Asıl değer offline durumda üretilmiş ve server'a henüz sync edilmemiş önemli verilerde ortaya çıkar. Browser isteği kabul etmek zorunda değildir. Application persist reddedildiğinde de güvenli çalışmalıdır. Storage davranışı kullanıcıya saygılı ve ölçülü olmalıdır.

Offline-Critical Data

Field worker'ın saatlerce offline oluşturduğu kayıtlar eviction ile kaybolmamalıdır. Bu tip data persistent storage için güçlü adaydır. Sync başarıyla tamamlandıktan sonra local retention policy değişebilir. Unsynced record sayısı kullanıcıya gösterilebilir. Backup ve retry logic storage persistence kadar önemlidir.

navigator.storage.persist()

API origin için persistent storage izni talep eder. Promise sonucu true veya false olabilir. Browser user engagement gibi kendi kriterlerini kullanabilir. İzin reddedildiğinde tekrar tekrar kullanıcıyı rahatsız eden akış yapılmamalıdır. Persistence state telemetry offline feature reliability'sini değerlendirebilir.

Cache Edilebilir Veriler İçin Gereksiz Persistence

CDN'den tekrar indirilebilen image cache veya public article snapshot persistent olmak zorunda değildir. Evict edilmesi yalnızca sonraki load'u biraz yavaşlatır. User device storage'ını bu data için korumak gereksiz olabilir. Cache budget düşük priority veriyi doğal olarak silinebilir kabul etmelidir. Persistence değerli user data için saklanmalıdır.

Kullanıcı Cihaz Depolamasına Saygı

Offline feature yüzlerce megabyte data indirecekse kullanıcıya açık bilgi verilmelidir. Wi-Fi veya Save-Data preference dikkate alınabilir. Download package kullanıcı tarafından silinebilir olmalıdır. Storage usage settings sayfasında gösterilebilir. Performans optimizasyonu cihaz kaynağını sınırsız kullanma izni değildir.

Cache Eviction Stratejileri

Cache entry'lerinin ne zaman silineceği performans ile storage maliyeti arasındaki dengeyi belirler. TTL yaşa, LRU son kullanım zamanına, max entry count toplam kayıt sayısına göre karar verir. Birkaç strategy birlikte kullanılabilir. Browser-controlled eviction application policy'den bağımsız olarak daha erken gerçekleşebilir. Cache miss recovery her durumda sağlam olmalıdır.

TTL

Time-to-live entry'nin belirli süre sonunda geçersiz veya temizlenebilir kabul edilmesini sağlar. Basit ve anlaşılırdır. Resource kullanım sıklığını dikkate almaz. Çok değerli ama nadir kullanılan data süresi dolunca silinebilir. Freshness TTL ile storage eviction TTL birbirinden farklı kavramlar olarak tutulabilir.

LRU

Least Recently Used en uzun süredir kullanılmayan entry'leri önce siler. Runtime image cache gibi sınırlı storage senaryosunda etkilidir. Son erişim metadata write maliyeti vardır. Çok sık erişilen stale data'yı sonsuza kadar tutmamak için max age ile birlikte kullanılabilir. LRU correctness değil storage optimization sağlar.

Max Entry Count

Cache içinde en fazla belirli sayıda entry tutulabilir. Yeni entry eklendiğinde limit aşılırsa eski entry silinir. Boyutları çok farklı resource'larda count tek başına storage kullanımını doğru yansıtmayabilir. Image cache'te başlangıç için kullanışlıdır. Max storage size ile birlikte daha dengeli olabilir.

Max Storage Size

Toplam byte budget tanımlamak cihaz kaynağı kullanımını daha doğrudan kontrol eder. Cache API tek entry size bilgisini kolay sunmadığında custom metadata gerekebilir. Büyük video birden fazla küçük image kadar yer kaplamaz. Priority sınıfları budget allocation yapabilir. Storage estimate global origin kullanımını gözlemlemek için kullanılabilir.

Browser-Controlled Eviction

Application kendi entry'sini saklamak istese bile browser storage pressure altında best-effort data'yı silebilir. Bu behavior kesin süre garantisi vermez. Cache lookup her zaman miss dönebilir diye tasarlanmalıdır. Persistent storage risk azaltabilir ancak sınırsız storage sağlamaz. Offline user-generated data server sync ile mümkün olduğunca korunmalıdır.

Back/Forward Cache (bfcache) Nedir?

bfcache browser'ın kullanıcı başka sayfaya gittiğinde mevcut page'i tüm state'iyle dondurup geri veya ileri navigasyonda hızlı biçimde restore etmesidir. HTTP cache'ten farklı olarak yalnızca resource body değil document ve JavaScript state de geri gelir. Bu nedenle navigation neredeyse anlık olabilir. Aynı özellik eski server state'in tekrar görünmesine neden olabilir. Restore sonrası kritik data hedefli revalidation ile güncellenmelidir.

Sayfanın Tam State ile Dondurulması

bfcache page'in DOM, JavaScript heap ve scroll position gibi durumunu koruyabilir. User geri geldiğinde application yeniden boot olmak zorunda kalmaz. Timer ve connection lifecycle browser tarafından freeze veya restore edilebilir. Application normal load event'inin tekrar çalışacağını varsaymamalıdır. pageshow restore detection için önemlidir.

Geri/İleri Navigasyon

Kullanıcı browser history üzerinden geri veya ileri hareket ettiğinde bfcache hit varsa page hızlı açılır. Bu kullanıcı deneyimi özellikle commerce category-product navigation'da değerlidir. Analytics pageview ölçümü restore durumunu doğru ayırmalıdır. Server data bu sırada değişmiş olabilir. Critical query'ler background refresh ile güncellenebilir.

Normal HTTP Cache'den Farkı

HTTP cache network response resource'larını saklar. bfcache çalışan page state'ini memory snapshot olarak korur. HTTP no-cache directive bfcache restore öncesi otomatik revalidation anlamına gelmez. Bu yüzden page eski UI ile anında geri gelebilir. pageshow event business freshness için ekstra kontrol noktasıdır.

Hızlı Navigation

bfcache restore HTML parse, JS execution ve data fetch işlemlerinin önemli bölümünü atlayabilir. Kullanıcı history navigation'da çok hızlı response alır. Bu avantajı gereksiz unload handler ile kaybetmemek gerekir. DevTools eligibility ve not restored reason bilgisi sağlayabilir. bfcache hit rate production performance metric olarak izlenebilir.

Stale UI Riski

Kullanıcı product page'de stok değiştirip category page'e geri döndüğünde eski snapshot görebilir. Logout başka tab'da gerçekleşmişken geri navigation hassas account page'i restore edebilir. Bu nedenle pageshow persisted durumunda auth ve kritik data yeniden kontrol edilmelidir. Tam reload her zaman gerekli değildir. Targeted query invalidation daha hızlı ve stabil deneyim sağlar.

bfcache'den Dönen Sayfada Veriler Nasıl Fresh Tutulur?

bfcache restore hızlı olduğu için ilk frame eski state'i gösterebilir. Uygulama pageshow event'inde event.persisted değerini kontrol ederek restore durumunu algılayabilir. Kritik query'ler invalidate veya refetch edilebilir. Authentication state değişmişse page kontrollü biçimde yeniden yönlendirilebilir. Her restore'da full reload yapmak bfcache performans avantajını gereksiz yere yok eder.

pageshow

pageshow normal load sonrasında ve bfcache restore durumunda çalışabilir. Event üzerindeki persisted flag iki durumu ayırır. Application global lifecycle handler burada freshness check yapabilir. Handler ağır synchronous iş yapmamalıdır. Route criticality'ye göre farklı revalidation kuralları uygulanabilir.

Persisted Page Detection

event.persisted === true page'in bfcache'den restore edildiğini gösterir. Bu sinyal analytics ve cache refresh davranışı için kullanılabilir. Restore duration normal navigation'dan ayrı ölçülmelidir. Hassas session state yeniden doğrulanabilir. Browser support ve lifecycle farkları test edilmelidir.

Critical Data Revalidation

Cart total, inventory veya permission gibi data restore sonrasında refetch edilebilir. Public static content için buna gerek olmayabilir. Revalidation background yapılırken UI son known data'yı gösterebilir. İşlem butonu server confirmation gerektiriyorsa stale state üzerinden kritik action yapılmamalıdır. Data classification revalidation set'ini belirler.

Query Cache Refresh

TanStack Query gibi library kullanılan app'te bfcache restore event query invalidation tetikleyebilir. Her query'yi global refetch etmek yerine route dependency'leri hedeflenebilir. Existing staleTime davranışıyla uyumlu policy seçilmelidir. Network reconnect ve window focus trigger'larıyla duplicate refetch oluşmaması kontrol edilmelidir. Request deduplication bu riski azaltabilir.

Gereksiz Full Reload'dan Kaçınmak

Full reload bfcache'in sağladığı anlık navigation avantajını ortadan kaldırır. Yalnızca session security veya incompatible application version gibi güçlü gerekçe varsa kullanılmalıdır. Çoğu data update background query refetch ile yapılabilir. UI old state ile new state arasında stabil geçiş yapmalıdır. Logout gibi kritik event cross-tab broadcast ile daha restore öncesinde de ele alınabilir.

Çoklu Tab'larda Veri Tutarlılığı

Aynı application'ın iki tab'da açık olması client cache tutarlılığını daha zor hale getirir. Tab A mutation yaptığında Tab B kendi query cache'inde eski data tutabilir. Logout bir tab'da gerçekleşirken diğer tab authenticated görünmeye devam edebilir. Browser storage ortak olsa bile memory cache tab bazında ayrıdır. BroadcastChannel veya storage event gibi mekanizmalar cross-tab invalidation için kullanılabilir.

Tab A Mutation

Kullanıcı Tab A'da profile veya resource günceller. A kendi query cache'ini server response ile günceller. Tab B bu mutation'dan otomatik haberdar olmayabilir. Shared server state artık iki UI'da farklı görünür. Mutation success event diğer tab'lara broadcast edilebilir.

Tab B Eski Cache

Tab B staleTime uzun olduğu için saatlerce refetch yapmayabilir. Kullanıcı burada eski data üzerinden yeni action başlatabilir. Cross-tab invalidation query'yi stale işaretleyip refetch tetikleyebilir. Her mutation full cache dump göndermek gerekmez. Resource key ve version metadata yeterli olabilir.

Logout'ın Diğer Tab'da Görülmemesi

Tab A logout olduğunda server cookie veya token temizlenebilir. Tab B memory içinde user profile ve permission cache'i tutmaya devam edebilir. Sonraki API request 401 verene kadar UI authenticated görünebilir. Logout event BroadcastChannel ile bütün tab'lara iletilmelidir. Her tab query cache ve user-specific local storage temizliği yapmalıdır.

Cross-Tab Invalidation İhtiyacı

Bütün application'lar gerçek zamanlı cross-tab sync gerektirmez. Data nadiren değişiyor ve window focus refetch yeterliyse ekstra channel gereksiz olabilir. Collaboration veya auth gibi kritik alanlarda gecikme kabul edilmeyebilir. Resource freshness SLA bu kararı belirler. Cross-tab event sistemi versioned ve idempotent tasarlanmalıdır.

BroadcastChannel ile Cross-Tab Cache Senkronizasyonu

BroadcastChannel aynı origin storage partition içinde farklı tab ve window context'lerinin named channel üzerinden mesajlaşmasını sağlar. Mutation, logout veya cache invalidate event'leri bu kanaldan iletilebilir. Mesajı gönderen channel instance kendi mesajını event olarak almaz. Payload küçük ve semantic tutulmalıdır. Cross-tab messaging server authorization veya persistence mekanizmasının yerini tutmaz.

Named Channel

new BroadcastChannel("app-cache") gibi channel adı bütün ilgili browsing context'lerde aynı olmalıdır. Farklı application bölümleri ayrı channel kullanabilir. Channel lifecycle component yerine application root seviyesinde yönetilebilir. Tab kapanırken connection close edilebilir. Message version field backward compatibility sağlar.

Mutation Event

Mutation success sonrasında {type:"resource-updated", key:[...]} benzeri event gönderilebilir. Diğer tab actual payload yerine query invalidate yapabilir. Bu yaklaşım büyük veya hassas data'yı channel üzerinden taşımayı azaltır. Server response version event'e eklenebilir. Duplicate event idempotent biçimde işlenmelidir.

Cache Invalidate Mesajı

Invalidate message belirli query namespace veya entity ID içerebilir. Receiver local query client üzerinde targeted invalidation yapar. Active query refetch olabilir. Offline receiver event'i kaçırabilir ve daha sonra focus revalidation gerekir. Cross-tab sync tek freshness mekanizması olmamalıdır.

Logout Mesajı

Logout event bütün tab'lara güvenlik açısından hızlı yayılmalıdır. Receiver memory state, query cache ve user-specific IndexedDB data'yı temizler. Auth cookie zaten server veya browser seviyesinde kaldırılmış olmalıdır. Tab protected content gösteriyorsa login route'una geçebilir. Draft gibi kullanıcıya ait unsaved data policy ayrıca tanımlanmalıdır.

Query Refetch

Broadcast message sonrası her durumda full reload yerine query refetch yapılabilir. Kullanıcı açık form içindeyse data değişikliği notification olarak gösterilebilir. Background refetch new version'ı cache'e alır. Conflict ihtimali olan edit ekranında sessiz replace yapılmamalıdır. Version comparison kullanıcıya “başka yerde güncellendi” mesajı verebilir.

Same-Origin Sınırı

BroadcastChannel aynı origin ve storage partition sınırları içinde çalışır. Farklı subdomain veya origin'ler doğrudan aynı channel'ı paylaşmaz. Cross-origin product area için server push veya başka communication modeli gerekir. Security açısından bu sınır önemlidir. Architecture origin topology'yi cross-tab planına dahil etmelidir.

Server-Push Cache Invalidation

Polling yerine server resource değiştiğinde client'a event göndermek stale window'u azaltabilir. WebSocket veya Server-Sent Events üzerinden resource updated mesajı taşınabilir. Client event alınca ilgili query'yi invalidate veya refetch eder. Push channel kaybolabileceği için reconnect ve periodic validation fallback gerekir. Event delivery tek başına source of truth değildir, gerçek data yine normal API üzerinden alınabilir.

WebSocket

WebSocket bidirectional persistent connection sağlar. Collaborative editing veya yüksek frekanslı update için uygundur. Cache invalidation event küçük payload olarak gönderilebilir. Connection lifecycle, auth refresh ve reconnect backoff tasarlanmalıdır. Mobil battery ve server connection capacity maliyeti göz önünde bulundurulmalıdır.

Server-Sent Events

SSE server'dan client'a tek yönlü event stream sunar. Resource update notification için WebSocket'ten daha basit olabilir. Browser reconnect davranışı protokol tarafından desteklenir. Client mutation normal HTTP üzerinden devam edebilir. Proxy ve infrastructure timeout ayarları production ortamında test edilmelidir.

Resource Updated Event

Server domain mutation sonrasında affected resource key içeren event yayınlayabilir. Client full entity almak yerine invalidate sinyali kullanabilir. Event version veya updatedAt taşırsa duplicate ve out-of-order mesajlar filtrelenebilir. Tenant authorization stream seviyesinde uygulanmalıdır. Hassas data event payload içinde gereksiz taşınmamalıdır.

Query Invalidation

Push event query key factory ile local cache key'e çevrilir. Query stale işaretlenir. Active view fresh data'yı background refetch eder. Inactive query yalnızca stale kalabilir ve sonraki kullanımda update olur. Her event bütün cache'i temizlememelidir.

Targeted Refetch

Kullanıcı currently visible critical entity üzerinde ise event sonrası hemen refetch yapılabilir. Background tab için yalnızca invalidate yeterli olabilir. Bu yaklaşım network maliyetini düşürür. Event frequency çok yüksekse debounce veya batch uygulanabilir. UI update rate kullanıcı algısı ve render maliyetiyle dengelenmelidir.

Polling mi Server-Push mı?

Polling belirli aralıklarla server'a sorarken push server değişiklik olduğunda client'a event gönderir. Veri değişim sıklığı düşükse sürekli push connection gereksiz olabilir. Çok sık ve kritik update varsa polling hem gecikmeli hem maliyetli hale gelebilir. Window focus refetch basit business uygulamalarında yeterli freshness sağlayabilir. Architecture gerçek update frequency, connection sayısı ve stale tolerance üzerinden seçilmelidir.

refetchInterval

Query library belirli interval ile background refetch yapabilir. Implementation basittir. Update olmasa bile request gönderildiği için network ve server maliyeti vardır. Hidden tab behavior ve mobile battery dikkate alınmalıdır. Interval business freshness gereksiniminden türetilmelidir.

Window Focus Refetch

Kullanıcı tab'a geri döndüğünde stale query'lerin refetch edilmesi pratik ve düşük maliyetli stratejidir. Kullanıcı görmüyorken sürekli polling yapmaya gerek kalmaz. Gerçek zamanlı dashboard için yeterli değildir. Form edit ekranında background update conflict yaratabilir. Refetch sonucu UX domain'e göre yönetilmelidir.

WebSocket

Yüksek frekanslı bidirectional interaction için WebSocket güçlüdür. Connection sayısı backend infrastructure üzerinde maliyet oluşturur. Mobile network değişimlerinde reconnect logic gerekir. Cache invalidation dışında real-time payload da taşınabilir. Basit nadir update için gereğinden ağır çözüm olabilir.

SSE

SSE server-to-client update stream gereken use case'lerde daha basit model sunar. EventSource HTTP tabanlıdır. Client-to-server mutation ayrı request kullanır. Proxy timeout ve concurrent connection limitleri değerlendirilebilir. Resource update notification için yeterli olabilir.

Veri Değişim Frekansı

Reference data günde bir değişiyorsa push connection gereksizdir. Stock saniyede değişiyorsa beş dakikalık polling kabul edilemez. Domain verisinin gerçek update dağılımı ölçülmelidir. Aynı application içinde farklı resource'lar farklı strategy kullanabilir. Freshness matrix bu kararları merkezi hale getirir.

Connection Maliyeti

Persistent connection server file descriptor, memory ve mobile radio kullanımı oluşturabilir. Çok sayıda idle client maliyeti büyütür. Polling de her interval request overhead taşır. CDN push event çözmez ve origin capacity planlanmalıdır. Cost model kullanıcı sayısı ve update rate ile hesaplanabilir.

Offline-First Veri Tutarlılığı

Offline-first modelde application network bağlantısını zorunlu kabul etmeden local data üzerinden çalışır. Read operation local database'den yapılabilir ve write operation pending mutation queue'ya eklenebilir. Connection geri geldiğinde queue server ile senkronize edilir. Server'da aynı data değişmişse conflict oluşur. Bu nedenle offline-first caching değil tam bir distributed data synchronization problemidir.

Local Read

UI önce IndexedDB veya başka local source üzerinden data okur. Network bulunursa background sync latest changes'i getirir. Local record version metadata taşır. Kullanıcı stale data görüyorsa updated time gösterilebilir. Critical action öncesinde server confirmation gerekebilir.

Offline Write

Kullanıcı network yokken form veya task değişikliğini local database'e yazabilir. Operation pending status alır. UI değişikliği hemen gösterir. Server ID henüz yoksa client-generated stable ID kullanılabilir. Validation'ın yalnızca server'da bilinen kısmı reconnect sonrası hata üretebilir.

Mutation Queue

Pending operation'lar sırayla veya dependency graph'a göre saklanır. Her mutation idempotency key taşıyabilir. Retry duplicate server write oluşturmamalıdır. Queue user account ile ilişkilendirilmelidir. Logout unsynced operation varsa kullanıcıya açık karar sunulmalıdır.

Network Reconnect

Browser online event tek başına server'ın gerçekten erişilebilir olduğunu garanti etmez. Sync engine retry request ile connectivity doğrular. Backoff server veya network sorununda agresif request'i önler. Queue processing UI thread'i bloklamamalıdır. Reconnect sırasında latest server snapshot önce veya sonra alınacağı domain'e göre belirlenir.

Server Synchronization

Pending mutation server'a gönderilir ve success response local entity'yi günceller. Server-generated version, ID ve updatedAt local record'a yazılır. Remote changes ayrıca çekilir. Sync checkpoint duplicate data transferini azaltabilir. Partial success transaction boundary ile yönetilmelidir.

Conflict

Server version client'ın edit ettiği base version'dan değişmiş olabilir. Automatic merge yalnızca güvenli field'larda yapılmalıdır. Manual conflict screen kullanıcıya iki version'ı gösterebilir. Last write wins data kaybı riski taşır. Conflict rate ürün tasarımının offline behavior için uygunluğunu gösteren metric olabilir.

Offline Mutation Queue Nasıl Tasarlanmalıdır?

Offline mutation queue yalnızca request URL ve body listesinden ibaret olmamalıdır. Operation identity, ordering, retry sayısı, base version ve user context gibi metadata gerekir. Request server tarafında idempotent olmalıdır. Conflict response normal error'dan ayrı ele alınır. Success sonrasında local cache authoritative server response ile güncellenir.

Pending Mutation

Her offline write persistent queue'ya pending state ile eklenir. UI entity üzerinde unsynced badge gösterebilir. Operation body ve gerekli auth-independent metadata saklanır. Token gibi kısa ömürlü secret payload içine gömülmemelidir. Sync sırasında current authentication context kullanılmalıdır.

Idempotency Key

Network response kaybolduğunda client aynı mutation'ı tekrar gönderebilir. Server idempotency key aynı operation'ın iki kere uygulanmasını önler. Payment ve create operation'larında özellikle önemlidir. Key client tarafından stable üretilip queue entry ile saklanabilir. Server retention süresi retry window ile uyumlu olmalıdır.

Ordering

Bazı mutation'lar birbirine bağımlıdır. Önce offline oluşturulan entity daha sonra update edilebilir. Queue bu order'ı korumalı veya dependency graph kullanmalıdır. Bağımsız mutation'ları paralel göndermek sync süresini azaltabilir. Out-of-order response local reconciliation'ı bozmamalıdır.

Retry

Transient network veya 5xx hata belirli backoff ile retry edilebilir. Validation 4xx hatasını sonsuza kadar retry etmek yanlış olur. Retry count ve next attempt time persistent tutulabilir. Kullanıcı manual retry yapabilmelidir. Server rate limit response backoff planına dahil edilmelidir.

Conflict

Version mismatch otomatik retry ile çözülmez. Latest server data alınmalı ve merge policy uygulanmalıdır. Kullanıcı intervention gerekebilir. Conflict queue entry pending yerine blocked state alabilir. Telemetry en çok conflict üreten operation tiplerini gösterir.

Success Sonrası Local Cache Güncelleme

Server success response local optimistic record'ı replace veya merge eder. Temporary ID gerçek server ID ile değişebilir. Related query cache invalidate edilmelidir. Queue entry transaction içinde silinirse duplicate retry riski azalır. BroadcastChannel diğer tab'lara update sinyali gönderebilir.

Client ve Server Aynı Veriyi Değiştirirse Ne Olur?

Aynı entity farklı actor'lar tarafından eşzamanlı değiştirildiğinde tek doğru generic çözüm yoktur. Last write wins, server wins, client wins veya manual merge farklı business anlamları taşır. Version-based conflict detection önce çakışmayı görünür hale getirir. Sonra domain hangi değişikliğin korunacağını belirler. Veri tutarlılığı cache library seçimi değil conflict semantics seçimidir.

Last Write Wins

En son server'a ulaşan write önceki değeri ezer. Uygulaması basittir. Collaborative text veya finansal data için sessiz veri kaybı oluşturabilir. User preference gibi düşük riskli alanlarda kabul edilebilir. Timestamp ordering distributed clock farklarından etkilenebilir.

Server Wins

Conflict olduğunda server current value korunur ve client değişikliği reddedilir. Güvenlik ve centrally controlled configuration için mantıklı olabilir. Kullanıcı kendi edit'ini kaybettiği için açıklayıcı UI gerekir. Client latest data'yı alıp tekrar edit yapabilir. Offline uzun session'larda frustration oluşturabilir.

Client Wins

Client değeri server current state üzerine zorla yazılır. User-owned draft gibi bazı use case'lerde uygun olabilir. Başka actor değişikliğini kaybetme riski vardır. Server yine authorization ve validation uygulamalıdır. “Client wins” güvenlik açısından client'a sınırsız yetki verilmesi anlamına gelmez.

Version-Based Conflict Detection

Client base version gönderir ve server current version ile karşılaştırır. Farklıysa write uygulanmadan conflict response dönülür. Bu yaklaşım kayıp update'i sessizce engeller. UI merge veya overwrite seçeneği sunabilir. ETag ve If-Match HTTP seviyesinde bu modeli destekler.

Manual Merge

Karmaşık document veya form conflict'inde kullanıcı iki version'ı karşılaştırabilir. Field-level diff hangi tarafın ne değiştirdiğini gösterir. Merge sonucu yeni mutation olarak gönderilir. UX maliyeti yüksektir ancak kritik data kaybını önler. Conflict nadirse kabul edilebilir yaklaşım olabilir.

Domain-Specific Resolution

Shopping cart quantity toplama, calendar event conflict veya document edit aynı merge kuralını kullanmamalıdır. Domain operation semantic bilgisi taşıyabilir. Increment operation absolute set değerinden daha kolay merge edilebilir. Backend event model conflict resolution'ı destekleyecek şekilde tasarlanabilir. Generic cache katmanı domain kararını yalnızca uygulayabilir.

Veri Türüne Göre Freshness Politikası

Bütün veriye tek TTL vermek kolay ama yanlış bir yaklaşımdır. Static asset yıllarca değişmeyebilir, stok saniyeler içinde değişebilir. User profile birkaç dakika eski kalabilirken permission değişikliği güvenlik nedeniyle daha hızlı uygulanmalıdır. Freshness class listesi ürün ve mühendislik ekipleri tarafından ortak oluşturulmalıdır. Her sınıf staleTime, HTTP cache, invalidation ve fallback davranışına bağlanabilir.

Static Asset

Content hash taşıyan static asset immutable kabul edilebilir. Bir yıl gibi uzun browser cache uygulanabilir. Yeni content yeni URL üretir. Manual invalidation ihtiyacı minimumdur. Deployment retention eski client'ların asset erişimini korumalıdır.

Blog/Content

Blog article çoğu zaman birkaç dakika eski kalabilir. CDN stale-while-revalidate güçlü performans sağlar. Edit publish olduğunda purge veya revalidation event ile daha hızlı update yapılabilir. HTML SEO crawl freshness ihtiyacı ayrıca düşünülmelidir. UpdatedAt UI için gösterilebilir.

User Profile

Profile data user tarafından zaman zaman değiştirilir. Query cache birkaç dakika staleTime kullanabilir. Mutation sonrası local cache direct update edilmelidir. Başka tab değişiklikleri BroadcastChannel ile invalidate edilebilir. Account switch cache key user context'i içermelidir.

Feed

Feed sürekli yeni item alabilir ancak her saniye exact consistency şart olmayabilir. Kısa staleTime ve background refetch kullanılabilir. “Yeni gönderiler” indicator kullanıcı kontrolü sağlayabilir. Push event yalnızca yeni content geldiğini bildirebilir. Endless list merge ve duplicate prevention önemlidir.

Price

Price business açısından yüksek doğruluk gerektirir. Listing seviyesinde kısa cache toleransı olabilir. Checkout'ta server-side current price validation zorunlu olmalıdır. Promotion update push invalidation tetikleyebilir. Stale price incident metric izlenmelidir.

Inventory

Inventory yoğun satışta çok hızlı değişebilir. UI availability approximate olabilir. Add-to-cart veya checkout sırasında server reservation doğrulaması yapılmalıdır. Push invalidation veya kısa polling kullanılabilir. Cache-first yaklaşım güvenilir değildir.

Permissions

Permission UI visibility için cached tutulabilir ancak güvenlik kararı server'da yeniden uygulanmalıdır. Role değişikliği event ile invalidate edilmelidir. Long staleTime access revoke gecikmesi yaratmamalıdır. Logout bütün permission cache'lerini temizlemelidir. Cross-tab auth sync kritik önemdedir.

Financial Data

Financial data freshness ve privacy açısından en yüksek sınıfa girebilir. Browser persistent cache tamamen devre dışı bırakılabilir. Response timestamp ve reconciliation gösterilebilir. Transaction status server source of truth olmalıdır. Security policy cache directive'lerini belirlemelidir.

Fiyat ve Stok Bilgisi Nasıl Cache Edilmelidir?

Fiyat ve stok hızlı UI gerektirirken eski bilgi göstermenin doğrudan business maliyeti olduğu veri türleridir. Listing sayfasında kısa süreli cache kullanıcı deneyimini iyileştirebilir. Mutation veya inventory event geldiğinde ilgili cache invalidate edilmelidir. Checkout kritik karar noktası olduğu için server current price ve stock tekrar doğrulamalıdır. Cache yalnızca hızlı görüntüleme katmanı olarak kalmalıdır.

Stale Data'nın Business Maliyeti

Eski fiyat kullanıcıda güven kaybı oluşturabilir. Stokta görünen ürünün checkout'ta bitmiş olması conversion'ı düşürebilir. Yanlış indirim legal veya operasyonel sorun doğurabilir. Bu nedenle stale tolerance ürün yöneticisiyle rakamsal olarak tanımlanmalıdır. Performance improvement yanlış bilgi pahasına kabul edilmemelidir.

Network-First

Product detail veya cart route fresh price için network-first yaklaşım kullanabilir. Offline fallback varsa data stale olarak etiketlenir. Timeout durumunda kullanıcının kritik action'ı server doğrulanmadan tamamlanmamalıdır. HTTP cache kısa validator policy kullanabilir. Query layer deduplicate ederek aynı page içindeki tekrar request'leri azaltır.

Kısa staleTime

TanStack Query price query'sine birkaç saniye veya düşük dakika staleTime verilebilir. Gerçek değer business update frequency'ye göre belirlenmelidir. Window focus refetch kullanıcı tab'a döndüğünde güncelliği artırır. Mutation veya server event staleTime bitmeden invalidation yapabilir. Tek mekanizmaya bağımlı kalınmamalıdır.

Mutation/Push Invalidation

Admin price update olduğunda domain event client'lara yayınlanabilir. İlgili product query stale işaretlenir. Active product detail hemen refetch yapar. Category list background update alabilir. Event delivery kaçırılırsa periodic revalidation fallback gerekir.

Checkout'ta Server-Side Revalidation

Client checkout request ürün ID ve quantity gönderir, final price server tarafından current catalog üzerinden hesaplanır. Client cached total yalnızca preview olabilir. Fark varsa kullanıcıya onay ekranı gösterilebilir. Stok reservation atomic backend transaction içinde yapılmalıdır. Frontend cache hiçbir zaman ödeme tutarının authoritative kaynağı olmamalıdır.

Kullanıcı Yetkileri Cache Edilmeli mi?

Permission verisi performans için client'ta cache edilebilir ancak gerçek authorization kontrolü olarak kullanılmamalıdır. UI hangi menü veya butonun gösterileceğini cached permission ile hızlı belirleyebilir. Kullanıcı role başka yerde değiştiğinde cache invalidate edilmelidir. Server kritik endpoint'te her request'in yetkisini bağımsız doğrular. Frontend cache güvenlik boundary değil kullanıcı deneyimi optimizasyonudur.

Permission Cache

Permission list login sonrasında query cache veya memory içinde tutulabilir. Değişim sıklığı düşükse uzun staleTime düşünülebilir. Role revocation event daha erken invalidate edebilir. Account switch cache reset yapmalıdır. Persistent storage'a yazmak gerçekten gerekli değilse kaçınılmalıdır.

UI Authorization ile Gerçek Security Farkı

Butonu gizlemek kullanıcının API endpoint'e request göndermesini engellemez. DevTools veya custom request ile client kontrolü bypass edilebilir. Bu nedenle UI permission yalnızca usability içindir. Server her action'da authorization uygular. Cache stale olsa bile security sonucu server tarafından korunmalıdır.

Server-Side Authorization

Backend request token, session ve resource ownership üzerinden permission kontrolü yapmalıdır. Client'ın gönderdiği “isAdmin” gibi field güvenilir kaynak değildir. Cache permission güncel olmadığı için server 403 döndürebilir. UI bu durumda permission query'yi invalidate edip kullanıcıya açıklama gösterebilir. Security event cross-tab logout veya access change tetikleyebilir.

Permission Değişikliğinde Invalidation

Admin kullanıcı rolünü değiştirdiğinde active session bunu mümkün olduğunca hızlı öğrenmelidir. WebSocket veya SSE event query invalidation sağlayabilir. Polling veya window focus refetch fallback olabilir. Revocation kritikse server authorization anında etki eder. UI birkaç saniye sonra yeni menu state'e geçebilir.

Logout Sonrası Temizlik

Permission cache logout sonrasında mutlaka temizlenmelidir. Memory query cache, persisted query state ve user-specific IndexedDB data kapsam dahilindedir. Cross-tab logout bütün tab'lara bildirilmelidir. Service Worker user cache varsa ilgili entry'ler silinmelidir. Yeni kullanıcı önceki account permission'ını görmemelidir.

Logout Sırasında Hangi Cache'ler Temizlenmelidir?

Logout yalnızca auth token veya cookie'yi kaldırmak değildir. User-specific data farklı browser cache ve application storage katmanlarında kalabilir. Query cache, memory state, IndexedDB ve Service Worker cache gözden geçirilmelidir. Shared public static asset cache'i silmek gereksizdir. Cleanup veri sahipliğine göre hedefli yapılmalıdır.

Query Cache

User-specific query'ler logout sonrasında clear veya remove edilmelidir. Public reference data korunabilir. En basit güvenli model QueryClient tamamen clear edip login sonrası yeniden yüklemektir. Large public cache kaybı önemliyse namespace bazlı cleanup yapılabilir. Account switch automated test ile doğrulanmalıdır.

Memory State

Global store içinde user profile veya role data kalmamalıdır. Logout reducer state'i güvenli anonymous default'a döndürmelidir. Pending UI modal user-specific data gösterebilir ve kapatılmalıdır. In-memory derived selector'lar yeni state ile yeniden hesaplanır. Browser bfcache restore senaryosu ayrıca kontrol edilmelidir.

IndexedDB'deki User-Specific Data

Offline snapshot ve pending mutation user account'a bağlıdır. Logout davranışı bu data'nın silinip silinmeyeceğini product gereksinimine göre belirler. Shared cihaz güvenliği genellikle cleanup gerektirir. Unsynced data varsa kullanıcıya kayıp riski bildirilmelidir. Store key user ID içeriyorsa targeted delete kolaylaşır.

Service Worker User Cache

Runtime Cache Storage içinde personalized API response varsa logout sırasında silinmelidir. Public image veya app shell cache'i korunabilir. Cache entry key user context içermiyorsa leakage riski daha yüksektir. Preferable yaklaşım hassas API response'u Service Worker cache'e hiç koymamaktır. Cleanup success telemetry güvenlik açısından yararlı olabilir.

Cross-Tab Logout

BroadcastChannel logout event diğer tab'lara iletilmelidir. Receiver auth UI'ı kapatır ve user cache temizliği yapar. Background tab daha sonra restore olduğunda stale authenticated view göstermemelidir. Server session invalid olduğu için API request zaten reddedilir, ancak local UI hızlı temizlenmelidir. bfcache pageshow kontrolü ek güvenlik katmanı sağlar.

Auth Cookie/Token

Server session cookie logout endpoint tarafından invalidated edilmelidir. HttpOnly cookie JavaScript tarafından doğrudan silinemeyebilir. Token storage modeli security architecture'a bağlıdır. Refresh token revocation gerekiyorsa server tarafında uygulanmalıdır. Cache cleanup auth invalidation'ın tamamlayıcısıdır, alternatifi değildir.

Cache Poisoning Nedir?

Cache poisoning cache'e yanlış veya saldırgan tarafından manipüle edilmiş response'un yazılıp daha sonra başka request'lere sunulmasıdır. Eksik cache key, yanlış Vary veya user-specific response'un public caching'e girmesi risk oluşturur. Error page veya redirect bile yanlış süre cache edilirse geniş kullanıcı kitlesini etkileyebilir. Security-sensitive cache configuration otomatik ve manual test içermelidir. Cache performance katmanı aynı zamanda attack surface oluşturabilir.

Yanlış Response'un Cache'e Yazılması

Cache key request'i tam temsil etmiyorsa farklı varyant response aynı entry altında saklanabilir. Attacker özel header veya query ile cache'i beklenmedik content'le doldurmaya çalışabilir. CDN normalization kuralları önemlidir. Application input response header'a veya body'ye yansıyorsa security review gerekir. Cache entry source ve Age header incident analysis için loglanabilir.

Public Personalized Data

User-specific response yanlışlıkla public ve shared max-age ile yayınlanırsa CDN başka kullanıcıya aynı body'yi sunabilir. Bu en ciddi cache configuration hatalarındandır. Authenticated endpoint default policy güvenli olmalıdır. Integration test farklı user credential ile aynı URL response'unu kontrol edebilir. Security scanner cache header analizine dahil edilebilir.

Eksik Cache Key

Tenant, language veya content negotiation response'u değiştiriyorsa key bunu içermelidir. Eksik context farklı representation'ların çakışmasına neden olur. Fazla context ise hit rate kaybı yaratır. Cache key specification merkezi tutulmalıdır. CDN config değişikliği application release kadar dikkatli review edilmelidir.

Yanlış Vary

Response Accept-Language'a göre değişiyor ancak Vary yoksa cache yanlış dilde content sunabilir. Daha kritik header farklılıklarında güvenlik sorunu doğabilir. Vary '*' caching'i pratik olarak devre dışı bırakabilir. 304 response'larda da uygun Vary consistency korunmalıdır. Production header snapshot testleri regression'ı yakalayabilir.

Error Response Caching

500 veya yanlış 404 response uzun cache'e girerse sorun origin düzeldikten sonra bile devam edebilir. CDN negative caching policy bilinmelidir. Service Worker custom strategy yalnızca başarılı response'ları cache etmeye dikkat etmelidir. Workbox CacheableResponsePlugin status filtrelemesi sağlayabilir. Error cache TTL kısa ve bilinçli tutulmalıdır.

Security Sonuçları

Cache poisoning XSS, data leakage veya authorization bypass etkisine kadar büyüyebilir. Shared cache geniş blast radius oluşturur. Incident response yalnızca origin düzeltmesi değil CDN purge ve browser cache recovery de içerebilir. Cache key ve header değişiklikleri threat modeling kapsamına alınmalıdır. Performance optimization güvenlik kontrolünden muaf değildir.

User-Specific API Response Nasıl Güvenli Cache Edilir?

Kullanıcıya özel API response'u cache etmeden önce gerçekten caching ihtiyacı olup olmadığı sorulmalıdır. Çok hassas veya hızlı değişen data için no-store en basit güvenli yaklaşımdır. Cache gerekiyorsa private policy, doğru user/tenant key ve logout cleanup birlikte uygulanmalıdır. Shared CDN layer personalization context'i güvenli biçimde ayırmıyorsa response public cache'e girmemelidir. Frontend query cache de account context'i key içinde taşımalıdır.

Cache Etmeme Seçeneği

Her response cache edilmek zorunda değildir. Account security, financial veya one-time token verisi network'ten fresh alınabilir. Performance başka katmanlarda optimize edilebilir. Server latency yüksekse önce backend bottleneck düzeltilmelidir. Cache correctness riskini kabul etmek zorunlu değildir.

private

Cache-Control: private response'un shared cache yerine private browser cache'te kalmasını sağlar. Freshness süresi ayrıca belirlenmelidir. Shared cihaz ve logout riski yine değerlendirilir. Çok hassas data için private yeterli olmayabilir. Query cache persistence bundan bağımsız olarak ayrı kontrol edilir.

Doğru Cache Key

Client query cache user veya tenant context'i içermelidir. Service Worker Cache Storage kullanılıyorsa URL aynı olsa bile kullanıcı ayrımının nasıl yapılacağı çözülmelidir. Authorization header Cache API matching behavior'ı ve custom key logic dikkatle incelenmelidir. Basit güvenli çözüm personalized API'yi Service Worker cache dışında tutmaktır. Complexity güvenlik riskini artırıyorsa performans kazanımı vazgeçilebilir.

Authorization Context

Server response authorization context'e bağlıdır. Session değiştiğinde cached result otomatik güvenilir olmaktan çıkar. Query client auth state change event ile resetlenebilir. Tenant switch aynı user içinde de cache separation gerektirir. Permission server tarafında yeniden uygulanmaya devam eder.

Logout Cleanup

Logout event user cache namespace'lerini temizlemelidir. IndexedDB, query cache ve Cache Storage ayrı katmanlardır. Cleanup sırasında public static cache korunabilir. Cross-tab broadcast diğer session'lara aynı işlemi yaptırır. Failure durumunda application anonymous mode'a geçmeden önce sensitive UI state sıfırlanmalıdır.

Hassas Veri İçin no-store

Hassas response'un browser HTTP cache'te saklanmaması isteniyorsa no-store kullanılabilir. Application code aynı data'yı memory veya IndexedDB'ye yazmamalıdır. Security policy bütün storage yollarını kapsamalıdır. Screenshot veya browser extension gibi farklı riskler ayrı değerlendirilir. No-store cache stratejisinin yalnızca bir parçasıdır.

Cache Stampede Tarayıcı Katmanında Olur mu?

Cache stampede genellikle backend cache için konuşulsa da çok sayıda browser client aynı TTL sonunda aynı anda origin'e yöneldiğinde benzer trafik dalgası oluşabilir. Özellikle büyük deployment veya sabit expiration zamanı bu etkiyi güçlendirir. stale-while-revalidate ve CDN edge caching origin üzerindeki yükü azaltabilir. Query library aynı tab içindeki duplicate request'i deduplicate edebilir ancak farklı kullanıcıları birleştiremez. TTL jitter backend veya CDN seviyesinde expiration dağılımını yayabilir.

Çok Sayıda Client'ın TTL Sonunda Origin'e Gitmesi

Bir milyon client aynı resource'u aynı saatte cache'e aldıysa max-age aynı anda dolabilir. Bir sonraki trafik dalgasında revalidation request sayısı artar. CDN shared cache çoğunu origin'den uzak tutabilir. Origin ETag check hafif olsa bile connection ve request processing maliyeti vardır. Expiration distribution load test'te modellenebilir.

Stale-While-Revalidate

Shared cache stale response'u hızlı sunarken background revalidation yapabilir. Birçok CDN request coalescing ile aynı resource revalidation'ını tek origin request'e düşürebilir. Browser düzeyinde her client yine kendi request'ini yapabilir. Backend cache ve CDN birlikte stampede riskini azaltır. Stale tolerance resource'a uygun olmalıdır.

Request Deduplication

Aynı tab içinde birkaç component aynı query'yi aynı anda isterse tek in-flight promise paylaşılabilir. Bu yalnızca client-local stampede'i önler. Farklı tab veya kullanıcılar arasında otomatik deduplication olmaz. Service Worker aynı origin tab'ları arasında bazı request'leri merkezi ele alabilir ancak architecture daha karmaşık hale gelir. Shared CDN daha doğal global deduplication katmanıdır.

CDN/Backend Cache

Browser caching origin load'u azaltır ancak global kullanıcı kitlesi için shared cache daha güçlüdür. CDN edge aynı resource'u birçok client'a sunar. Backend application cache database yükünü ayrıca azaltır. Her katmanın TTL'i farklı olduğunda stale behavior anlaşılmalıdır. Source of truth ve invalidation signal bütün zincirde takip edilebilir olmalıdır.

TTL Jitter

TTL jitter expiration süresine küçük random fark ekleyerek çok sayıda entry'nin aynı anda expire olmasını önler. Browser Cache-Control max-age client başına random üretmek her architecture'da pratik değildir. Backend veya CDN cache TTL jitter daha kolay uygulanabilir. Query refetch interval client session başlangıcına göre doğal dağılım gösterebilir. Traffic pattern gözlemlenmeden optimization yapılmamalıdır.

Request Deduplication Nedir?

Request deduplication aynı semantic data için eşzamanlı başlayan birden fazla request'i tek network operation altında birleştirmektir. Modern component architecture'da aynı user profile veya settings farklı component'ler tarafından istenebilir. Query library key üzerinden ortak in-flight promise paylaşabilir. Bu sayede component sayısı backend request sayısını gereksiz artırmaz. Deduplication freshness veya cross-user caching yerine yalnızca aynı request'in tekrarını azaltır.

Aynı Query İçin Eşzamanlı Request'ler

Header, sidebar ve page body aynı user query'yi mount anında isteyebilir. Custom fetch hook her component'te ayrı request başlatabilir. Query client ortak key gördüğünde tek fetch yeterli olabilir. Response bütün observer'lara dağıtılır. Query key farklı yazılırsa deduplication gerçekleşmez.

Tek In-Flight Promise

İlk request başladığında cache pending promise'i saklayabilir. Sonraki aynı key caller'lar bu promise'e bağlanır. Success veya error tek network result üzerinden paylaşılır. Request tamamlandıktan sonra normal cache freshness kuralları devreye girer. Cancellation semantics bir observer ayrıldığında diğerlerini bozmamalıdır.

Query Library Deduplication

TanStack Query gibi server state library'leri query identity üzerinden request sharing sağlar. SWR de aynı key ile benzer davranış sunabilir. Custom component fetch yerine merkezi query key design bu nedenle değerlidir. Deduplication window library implementation'ına göre değişebilir. Production request count gerçek kazanımı gösterir.

Component Sayısı ile Request Sayısını Ayırmak

Component architecture data dependency'yi compose ederken network architecture bundan bağımsız optimize edilebilir. Beş component aynı user entity'yi kullanabilir ama tek query request yeterlidir. Component unmount cache entry'nin anında yok olması anlamına gelmez. Bu ayrım UI code'u daha modüler hale getirir. Query cache data fetching ownership'i component tree'den daha merkezi yönetir.

SSR ve Client Cache Birlikte Nasıl Kullanılır?

SSR server'ın ilk HTML'i üretmek için data fetch etmesini sağlar, ancak client hydrate olduktan sonra aynı data'yı tekrar fetch etmek gereksiz olabilir. Query dehydration server cache state'ini client'a taşır. Client bu state'i hydrate ederek ilk render'da aynı data'yı kullanır. dataUpdatedAt gibi metadata freshness hesabını server fetch zamanına bağlar. staleTime yanlışsa hydration sonrasında hemen duplicate refetch oluşabilir.

Server Fetch

Server request sırasında page için gerekli query'leri fetch eder. User-specific request query client instance'ı request scope'ta tutulmalıdır. Shared global query cache user data leakage oluşturabilir. Fetch sonucu server rendering ve dehydration için kullanılır. Server cache backend caching ile ayrıca optimize edilebilir.

Dehydration

Dehydration query cache'in serializable state'ini HTML veya streaming payload içinde client'a gönderir. Yalnızca gerekli query'ler dahil edilmelidir. Hassas data HTML source'a istemeden yazılmamalıdır. Payload size initial response'u büyütür. Large dataset için selective dehydration kullanılır.

Client Hydration

Client QueryClient dehydrated state'i cache'e yükler. Component aynı key'i kullandığında data hazır bulunur. UI loading state göstermeden render olabilir. Query freshness server fetch zamanına göre değerlendirilmelidir. Server ve client query key helper aynı logic'i kullanmalıdır.

dataUpdatedAt

Query data'nın ne zaman fetch edildiğini belirleyen metadata freshness hesabı için önemlidir. Hydration zamanı data'nın gerçek fetch zamanı değildir. Server saatinin doğru olması gerekir. Cache edilmiş SSR HTML çok eskiyse query dataUpdatedAt da eski olmalıdır. Bu sayede client gerektiğinde background refetch yapabilir.

Initial Data'nın Staleness'i

Server initial data 30 saniye önce alındıysa client bunu sıfır yaşında kabul etmemelidir. Updated metadata doğru taşınmalıdır. staleTime resource tipine göre belirlenir. Kullanıcı UI'ı hızlı cached data ile görürken background refresh olabilir. Critical data için hydration sonrası immediate revalidation seçilebilir.

Double Fetch Problemi

SSR data client cache'e doğru hydrate edilmezse component mount tekrar aynı API request'i gönderir. staleTime sıfır olduğunda hydrate edilmiş query de background refetch yapabilir ve bu her zaman hata değildir. Network maliyeti istenmiyorsa kısa staleTime kullanılabilir. Server markup CDN'de uzun cache'te ise client refresh güncelliği korumak için özellikle değerli olabilir. Double fetch'in gerçekten gereksiz olup olmadığı freshness requirement'a göre değerlendirilmelidir.

SSR Hydration Sonrası Stale Data

SSR server response üretildiği an ile browser hydration tamamlandığı an arasında veri değişebilir. CDN cached HTML kullanılıyorsa bu fark daha da büyüyebilir. Client query cache server snapshot'ını başlangıç data olarak kullanır ve background revalidation ile günceller. Server Component ve Client Component farklı fetch layer kullanıyorsa aynı resource için iki source of truth oluşmamalıdır. Version metadata bu sınırın yönetilmesini kolaylaştırır.

Server'da Render Edilen Veri

Server render snapshot belirli zamanın verisidir. Kullanıcı HTML'i aldığında data artık değişmiş olabilir. Bu normal distributed system davranışıdır. Critical mutation öncesi latest server state tekrar doğrulanmalıdır. UI updatedAt gösterebilir.

Client Query Cache

Hydration sonrası query cache server snapshot'ını local cache olarak sahiplenir. staleTime dolduğunda refetch yapar. Mutation update aynı cache key üzerinde uygulanır. Server-rendered markup ile query key uyuşmazsa duplicate state oluşur. Shared data contract kullanılmalıdır.

Background Refetch

Client ilk render'ı bozmadan server'dan yeni data alabilir. Değişiklik varsa UI update edilir. Büyük layout farkı flicker oluşturabilir. User form edit ediyorsa server refresh local input'u ezmemelidir. Reconciliation component design'ın parçasıdır.

Server Component ile Client Component'in Ayrışması

Server Component server'da fresh data çekip markup üretirken Client Component kendi query cache'ini kullanabilir. Aynı entity iki farklı zaman snapshot'ı taşıyabilir. Boundary'de initial data veya version metadata paylaşılmalıdır. Server re-render navigation ile client invalidation behavior uyumlu olmalıdır. Framework cache katmanları ayrıca belgelenmelidir.

Tek Source of Truth Tasarımı

Authoritative state server'da kalıyorsa bütün client cache'ler onun kopyası olarak görülmelidir. Mutation server version'ı değiştirir ve invalidation event üretir. SSR, query cache ve IndexedDB aynı resource version'ını metadata ile takip edebilir. Bu model stale bug'larını daha açıklanabilir hale getirir. “En güncel hangisi” sorusunun sistemde tek cevabı olmalıdır.

Multi-Layer Cache Tutarlılığı Nasıl Kurulur?

Tarayıcı İçi Caching Stratejileri ve Veri Tutarlılığı çalışmasının en önemli aşaması birden fazla cache katmanını tek bütün olarak modellemektir. Önce source of truth belirlenmeli, ardından her cache katmanının hangi veri için var olduğu yazılmalıdır. Freshness süresi, invalidation sinyali, fallback ve version metadata ayrı tanımlanır. Bir query cache refetch yaptığında altındaki Service Worker'ın eski response döndürmesi gibi double-cache problemleri böylece görünür hale gelir. Basit ve sahipliği belli cache mimarisi çoğu zaman daha fazla cache katmanından daha güvenilirdir.

Source of Truth'u Belirlemek

Her resource için authoritative kaynağın server database, local offline database veya başka sistem olduğu açık olmalıdır. Cache'ler bu kaynağın geçici kopyalarıdır. Offline-first app geçici olarak local authority kabul edebilir. Sync sonunda conflict resolution source of truth modeline dayanır. Belirsiz source ownership veri kaybının temel nedenlerinden biridir.

Her Cache Katmanının Owner'ını Belirlemek

HTTP cache server header ile, query cache frontend data layer ile, Service Worker runtime cache PWA layer ile yönetilebilir. Her ekip aynı resource için bağımsız TTL belirlerse behavior tahmin edilemez hale gelir. Owner policy ve monitoring sorumluluğunu taşır. Cross-team cache contract dokumente edilmelidir. Bir cache kaldırıldığında kimse şaşırmamalıdır.

Freshness Süresini Belirlemek

Freshness business data toleransına göre tanımlanır. Static asset sonsuz semantic freshness'e yakın olabilir. Feed saniyeler, profile dakikalar, inventory çok daha kısa süre ister. HTTP max-age ve query staleTime aynı olmak zorunda değildir. Effective stale window bütün katmanların birleşimi üzerinden hesaplanmalıdır.

Invalidation Signal'ını Belirlemek

TTL dışında mutation, domain event, logout veya deployment cache invalidation sinyali olabilir. Hangi event hangi cache'i etkiliyor açık bir tablo ile gösterilebilir. Push event kaçarsa fallback revalidation bulunmalıdır. Invalidation idempotent olmalıdır. Signal version metadata ile ilişkilendirildiğinde out-of-order event yönetimi kolaylaşır.

Fallback Davranışını Belirlemek

Network yoksa hangi data stale kullanılabilir ve hangisi hata göstermelidir önceden belirlenir. Stale-if-error public content'te uygun olabilir. Payment veya permission için fail closed gerekebilir. UI stale badge veya last updated time gösterebilir. Failure UX cache architecture'ın ayrılmaz parçasıdır.

Version Metadata Kullanmak

ETag, updatedAt, schema version, API version ve client app version farklı uyumluluk boyutlarını taşır. Cache entry metadata hangi sürümle üretildiğini gösterebilir. New app incompatible persisted cache'i discard edebilir. Mutation conflict entity version üzerinden tespit edilir. Version bilgisi stale bug root cause analizini hızlandırır.

Cache Invalidation Ownership Nedir?

Cache invalidation ownership bir cache entry'nin ne zaman güncelleneceğine kimin karar verdiğini tanımlar. Mutation yapan kod, event consumer, Service Worker veya TTL farklı owner adaylarıdır. Birden fazla bağımsız owner aynı resource'u farklı kuralla değiştirirse race condition oluşabilir. Tek ana policy ve açık fallback daha güvenlidir. Ownership code review ve observability sorumluluğunu da kapsar.

Kim Cache'i Günceller?

Query cache mutation success callback tarafından update edilebilir. Server push event yalnızca invalidate edebilir. Service Worker network response ile runtime cache'i yenileyebilir. HTTP cache server header kurallarıyla çalışır. Bu akış diagram halinde gösterilmelidir.

Mutation Yapan Kod

Mutation resource'u değiştirdiği için ilgili cache'leri bilmek için doğal noktadır. Success sonrası direct cache update veya invalidation yapabilir. Farklı feature ekipleri aynı resource'u mutate ediyorsa ortak helper kullanılmalıdır. Mutation failure cache'i fresh işaretlememelidir. Event-driven backend değişiklikleri yalnızca client mutation'a güvenmeyi yetersiz kılar.

Event Consumer

Server domain event veya BroadcastChannel consumer cache invalidate edebilir. Event payload resource identity taşır. Consumer duplicate event'e dayanıklı olmalıdır. Event kaybolursa periodic refetch fallback gerekir. Monitoring invalidation event processing latency'sini ölçebilir.

Service Worker

Service Worker runtime cache'in teknik owner'ı olabilir. Network response geldikçe cache entry update eder. Application query cache bu layer'ın stale policy'sini bilmelidir. User logout Service Worker'a cleanup mesajı gönderebilir. Cache strategy implementation PWA ekibinin sorumluluğunda açıkça belgelenmelidir.

TTL

TTL event olmadan zaman bazlı invalidation sağlar. Uygulaması kolaydır ancak gerçek data change anını bilmez. Çok uzun TTL stale risk, çok kısa TTL yüksek request maliyeti oluşturur. Event-driven invalidation ile daha uzun TTL güvenli hale gelebilir. TTL fallback safety net olarak kullanılabilir.

Birden Fazla Owner Olmasının Riskleri

Query mutation cache'i güncellerken background refetch daha eski response ile overwrite edebilir. Service Worker aynı anda stale cache döndürebilir. Out-of-order event yeni state'i eski version'a çekebilir. Version comparison ve cancelation race condition'ı azaltır. Ownership matrix hangi actor'ın authoritative update yapabileceğini sınırlar.

Cache Version Metadata

Version metadata cache entry'nin hangi API, schema, application ve resource sürümüne ait olduğunu anlamayı sağlar. Deployment sonrası persisted data'nın yeni code ile uyumlu olup olmadığı böylece kontrol edilebilir. Entity updatedAt veya ETag freshness ve conflict için kullanılabilir. Tek bir version field bütün sorunları çözmez. Her metadata farklı compatibility katmanını temsil eder.

API Version

API response contract major change içeriyorsa client version compatibility önemlidir. URL veya header tabanlı API version kullanılabilir. Persisted cache entry hangi response shape'e ait olduğunu bilmelidir. New client eski cache'i parse edemiyorsa discard veya migrate eder. Backward-compatible API old open tab'ları korur.

Schema Version

IndexedDB veya persisted query data schema version local formatı tanımlar. Application startup version mismatch görürse migration çalıştırabilir. Migration başarısızsa yeniden fetch edilebilir cache silinebilir. User-created offline data daha dikkatli korunmalıdır. Schema version code repository'de migration history ile eşleşmelidir.

UpdatedAt

UpdatedAt entity'nin server'daki son değişim zamanını gösterebilir. UI “son güncelleme” bilgisi sunabilir. Cache merge sırasında newer record seçimine yardımcı olur. Clock precision conflict için her zaman yeterli değildir. Strong version ID ile birlikte kullanılabilir.

ETag

ETag HTTP representation version bilgisidir. Cache revalidation ve If-Match concurrency için kullanılabilir. IndexedDB record metadata olarak da saklanabilir. Local edit base ETag üzerinden conflict kontrolü yapabilir. Server ETag generation distributed node'larda consistent olmalıdır.

Client App Version

Cache entry belirli frontend release tarafından üretilmiş olabilir. New release incompatible serialization bekliyorsa app version check gerekir. Service Worker cache name release ID taşıyabilir. Query persisted cache buster app build hash kullanabilir. Old client server API ile backward-compatible kalmalıdır.

Cache Entry Version

Tek cache içinde farklı resource format sürümleri bulunabilir. Entry-level version migration'ı daha granular yapar. Full cache clear yerine yalnızca eski formatlar silinebilir. Bu yaklaşım büyük offline dataset'te değerli olabilir. Metadata storage overhead düşük tutulmalıdır.

Cache Tutarlılığı İçin Event-Driven Yaklaşım

Event-driven cache invalidation veri değiştiğinde TTL bitmesini beklemek yerine ilgili client'lara sinyal iletmeyi amaçlar. Database mutation domain event üretir, backend WebSocket veya SSE ile browser'a update bildirir. Browser query cache'i invalidate eder ve gerektiğinde fresh data refetch eder. Aynı event BroadcastChannel üzerinden diğer tab'lara da yayılabilir. Bu model stale window'u azaltır ancak event kaybına karşı periodic revalidation fallback'i yine gerekir.

Database Mutation

Authoritative record backend transaction içinde değişir. Mutation success domain event oluşturmak için doğal noktadır. Transaction commit olmadan event yayınlamak stale veya phantom update üretebilir. Outbox pattern event reliability'yi artırabilir. Resource version event payload'a eklenmelidir.

Domain Event

ProductPriceChanged gibi semantic event raw database row update'ten daha anlamlıdır. Consumer hangi cache key'lerin etkilendiğini bilir. Event tenant ve resource ID taşır. Sensitive payload minimum tutulur. Schema version event evolution'ı yönetir.

WebSocket/SSE

Backend event browser'a persistent channel üzerinden taşınır. Connection auth current user veya tenant scope'u uygular. Client yalnızca yetkili resource event'lerini almalıdır. Reconnect sonrası kaçırılan update'ler snapshot fetch ile telafi edilir. Sequence ID gap detection için kullanılabilir.

Browser Invalidation

Client event'i aldıktan sonra related query key'i stale işaretler. Cache entry hemen silinmek zorunda değildir. Visible route fresh response için refetch yapabilir. Background route next mount'a kadar bekleyebilir. Invalidation latency metric event arrival ile UI freshness arasını ölçebilir.

Background Refetch

Cache invalidate edilince kullanıcı cached data görmeye devam ederken network request başlayabilir. Response newer version ise UI güncellenir. Out-of-order older response version check ile reddedilebilir. Request deduplication burst event'lerinde duplicate fetch'i azaltır. Batch invalidation network load'u kontrol eder.

Cross-Tab Broadcast

Server event'i alan bir tab BroadcastChannel ile diğer tab'lara invalidate mesajı gönderebilir. Alternatif olarak her tab ayrı server connection tutabilir. Tek connection paylaşımı daha ileri architecture gerektirir. Basit sistemde duplicate connections kabul edilebilir. Cross-tab event payload versioned olmalıdır.

Cache Gözlemlenebilirliği

Cache stratejisi ölçülmeden optimize edildiğinde hit rate yüksek görünürken stale data incident sayısı artabilir. Cache hit, miss, network request ve revalidation metrikleri performans boyutunu gösterir. Stale response, storage usage ve offline fallback oranı correctness ve resilience hakkında bilgi verir. Browser telemetry privacy-safe biçimde aggregate edilmelidir. Web caching ve frontend performans danışmanlığı yakınımda gibi bir hizmet arandığında yalnızca header ayarı değil bu ölçüm sistemi de değerlendirme kriteri olmalıdır.

Cache Hit Rate

Hit rate toplam eligible request içinde cache'ten karşılanan oranı gösterir. HTTP, CDN, query ve Service Worker hit'leri ayrı ölçülmelidir. Yüksek hit rate latency ve origin cost avantajı sunabilir. Yanlış stale policy de hit rate'i yapay olarak yükseltebilir. Metric freshness incident ile birlikte yorumlanmalıdır.

Cache Miss Rate

Miss rate resource'un cache'te bulunamadığı veya kullanılabilir olmadığı durumları gösterir. Deployment sonrası yeni hashed asset doğal miss oluşturur. Çok yüksek miss yanlış cache key cardinality veya kısa TTL göstergesi olabilir. User-specific data için yüksek miss tamamen normal olabilir. Resource class bazında target belirlenmelidir.

Network Request Count

Page veya interaction başına API request sayısı query deduplication kalitesini gösterir. Aynı key için duplicate request regression alert oluşturabilir. Background refetch ve push event source ayrı etiketlenmelidir. Request sayısını sıfıra indirmek amaç değildir. Güncellik için gerekli request korunmalıdır.

Revalidation Count

ETag veya Last-Modified conditional request sayısı HTTP freshness davranışını gösterir. Çok sık revalidation long max-age kullanılabilecek asset'lerde gereksiz network round trip anlamına gelebilir. HTML için yüksek revalidation beklenebilir. Resource class karşılaştırması yapılmalıdır. CDN revalidation origin ve browser revalidation ayrı izlenebilir.

304 Rate

Conditional request'lerin ne kadarının 304 ile sonuçlandığını gösterir. Çok yüksek oran resource'un çoğunlukla değişmediği halde sık validation yapıldığını gösterebilir. max-age artırmak latency azaltabilir. Güncellik kritik HTML için bu oran kabul edilebilir. 304 body taşımadığı için bandwidth yine korunur.

Stale Response Rate

Uygulama bilerek stale cache fallback kullandığında bu oran ölçülebilir. Network failure veya stale-while-revalidate first response ayrı etiketlenebilir. Kritik data için stale rate sıfıra yakın hedeflenebilir. Public content'te belirli oran kabul edilebilir. Kullanıcı complaint ile stale telemetry ilişkilendirilebilir.

Storage Usage

IndexedDB ve Cache Storage toplam kullanımı cihaz storage baskısı riskini gösterir. Estimate API yaklaşık data sağlar. Application cache type bazında kendi entry size metadata'sını tutabilir. Growth trend cleanup bug'ını ortaya çıkarabilir. Storage budget release acceptance kriterine eklenebilir.

Offline Fallback Rate

Network failure nedeniyle cache fallback kullanılan request sayısı gerçek offline veya unstable network kullanımını gösterir. Bu metric offline feature'ın değerini kanıtlayabilir. Aynı zamanda origin outage sinyali olabilir. Geography ve network class segmentleri teşhisi kolaylaştırır. Critical data fallback safety ayrıca izlenmelidir.

Veri Tutarlılığı İçin İzlenmesi Gereken Metrikler

Cache performans metriği yalnızca hız ve hit oranından oluşmamalıdır. Invalidation'ın ne kadar sürede UI'a yansıdığı, kaç stale incident oluştuğu ve optimistic mutation failure oranı veri kalitesini gösterir. Cross-tab sync failure veya conflict rate architecture'ın nerede zorlandığını ortaya çıkarır. Teknik ekip bu metrikleri business impact ile ilişkilendirebilir. Cache observability correctness'i production'da ölçülebilir hale getirir.

Invalidation Latency

Authoritative data değişimi ile client cache'in stale işaretlenmesi arasındaki süredir. Push sisteminde milisaniye veya saniye seviyesinde olabilir. TTL-only sistemde dakikalar sürebilir. Resource freshness SLA ile karşılaştırılır. Event pipeline hop'ları trace ID ile izlenebilir.

Mutation-to-Fresh-UI Latency

Kullanıcı mutation başlattıktan sonra UI'ın server-confirmed current state göstermesine kadar geçen süreyi ölçer. Optimistic UI ayrı metric olarak daha hızlı olabilir. Success response, cache reconciliation ve related refetch toplam süreyi oluşturur. Long latency user confusion yaratabilir. Target interaction criticality'ye göre belirlenir.

Stale-Data Incidents

Kullanıcıya yanlış fiyat, eski permission veya outdated profile gösterilen doğrulanmış olaylar sayılabilir. Log ve support ticket correlation yapılabilir. Incident severity data class'a göre değişir. Zero stale impossible olabilir ancak critical class için çok düşük target gerekir. Root cause hangi cache layer'ın stale kaldığını belirtmelidir.

Conflict Rate

Version-based mutation conflict sayısı collaborative veya offline workflow yoğunluğunu gösterir. Yüksek oran UI'ın uzun stale window kullandığını gösterebilir. Conflict resolution UX kullanıcı effort'unu artırır. Event-driven invalidation rate'i düşürebilir. Domain model last-write-wins'e geçmeden önce data loss riski analiz edilmelidir.

Failed Optimistic Updates

Optimistic mutation'ların kaçının rollback ile sonuçlandığı ölçülebilir. Failure yüksekse kullanıcı sık sık önce başarı sonra hata görür. Bu durumda pessimistic UI daha güvenilir olabilir. Server validation rule client'ta erken kontrol edilebilir. Network failure ile business validation ayrı kategorize edilmelidir.

Cross-Tab Sync Failures

Logout veya mutation event diğer tab'a ulaşmadığında stale UI oluşabilir. Broadcast message sent/received telemetry sınırlı biçimde tutulabilir. Version mismatch nedeniyle message parse error izlenebilir. Window focus refetch güvenli fallback sağlar. Critical auth event server-side session invalidation sayesinde yine korunmalıdır.

Chrome DevTools ile Cache Debugging

Chrome DevTools cache problemlerini network ve storage katmanlarında ayrı ayrı incelemek için temel araçları sunar. Network tab response'un memory cache, disk cache veya 304 üzerinden geldiğini gösterebilir. Application panel Cache Storage, IndexedDB ve Service Worker durumunu görmenizi sağlar. Disable Cache seçeneği test koşulunu değiştirir ve production behavior ile karıştırılmamalıdır. Cache bug'ında her katmanı kontrollü biçimde bypass ederek kaynağı izole etmek en etkili yöntemdir.

Network Tab

Network panel request URL, status, timing ve response header bilgilerini gösterir. Size kolonunda memory cache veya disk cache notları görülebilir. Age, Cache-Control ve ETag header'ları incelenir. Service Worker tarafından response verildiyse ilgili işaretler ayrıca görülebilir. Preserve log redirect ve navigation zinciri analizini kolaylaştırır.

Memory Cache

Resource memory cache'ten geldiyse network transfer olmadan hızlı response alınabilir. Browser implementation bu cache'i kendisi yönetir. Header değişikliği test ederken cached entry sonucu yanıltabilir. Hard reload veya disable cache ile behavior karşılaştırılır. Application memory query cache bundan farklı katmandır.

Disk Cache

Disk cache browser restart veya tab lifecycle dışında daha uzun resource reuse sağlayabilir. Static asset repeat load'larında görülebilir. Hash'lenmiş immutable asset için beklenen davranıştır. Dynamic HTML yanlış disk cache policy ile stale kalabilir. Response header ve request cache mode birlikte kontrol edilir.

304

304 conditional request'in server'daki resource değişmediğini doğruladığını gösterir. Response body tekrar indirilmez. Network panel cached body ile 304 metadata'yı birlikte sunabilir. Çok sık 304 resource'un max-age süresinin düşük olduğunu gösterebilir. ETag ve Last-Modified request header'ları incelenebilir.

Disable Cache

DevTools açıkken Disable Cache browser HTTP cache behavior'ını test amacıyla bypass eder. Production kullanıcı bu modda değildir. Service Worker Cache Storage ayrı kalabilir. Bu nedenle “disable cache yaptım ama eski response geliyor” Service Worker veya application query cache sinyali olabilir. Debug adımları katman bazında yapılmalıdır.

Application Panel

Application panel Service Workers, Cache Storage, IndexedDB ve Web Storage gibi client persistence katmanlarını gösterir. Cache entry request ve response incelenebilir. IndexedDB store record'ları görüntülenebilir. Service Worker unregister ve update testleri yapılabilir. Production bug reproduction sırasında data'yı silmeden önce mevcut state screenshot veya export ile kaydetmek faydalıdır.

Cache Storage

Cache name ve entry listesi Application panelde görülebilir. Eski version cache'lerin cleanup edilip edilmediği kontrol edilir. Same URL'nin farklı cache name içinde duplicate bulunması double-caching işareti olabilir. Response header cache entry ile birlikte incelenir. Manual delete test amacıyla yapılabilir.

IndexedDB

Database version, object store ve record'lar DevTools üzerinden görüntülenebilir. Schema migration sonrası expected field'lar kontrol edilir. Pending mutation queue debug edilebilir. Büyük data view browser panelini yavaşlatabilir. Version upgrade blocked problemi başka tab connection'larıyla birlikte test edilir.

Service Workers

Service Worker'ın installing, waiting veya active durumu Application panelde görülebilir. Update on reload test için kullanılabilir. Production lifecycle farklı olabileceği için force update davranışı gerçek kullanıcıyı tam temsil etmez. Controlled page ve worker source URL doğrulanır. Cache strategy logları development build'de eklenebilir.

Cache Bug'ı Hangi Katmanda Nasıl Bulunur?

Stale veri görüldüğünde ilk refleks bütün cache'leri temizlemek problemi geçici olarak gizler ancak kök nedeni göstermez. Bunun yerine query cache, Service Worker, HTTP cache, CDN, backend cache ve database sırasıyla kontrol edilmelidir. Katmanlar tek tek bypass edilerek ilk yanlış response'un nerede oluştuğu bulunur. Request'e unique cache-busting query yalnızca teşhis için kullanılabilir. Root cause hangi layer'ın yanlış freshness veya key policy uyguladığını açıkça belirtmelidir.

Query Cache

DevTools veya query devtool ile cache'teki data ve updatedAt kontrol edilir. Manual refetch yapıldığında data düzeliyorsa staleTime veya invalidation problemi olabilir. Refetch yine eski response alıyorsa alt network katmanına bakılır. Query key tenant veya filter context'i içeriyor mu doğrulanır. Mutation success callback cache'i yanlış overwrite ediyor olabilir.

Service Worker

Network request Service Worker tarafından intercept ediliyor mu kontrol edilir. Worker bypass veya unregister sonrası data düzeliyorsa runtime cache strategy sorumludur. Cache Storage entry version ve timestamp incelenir. Route matcher API endpoint'i yanlış CacheFirst'e sokmuş olabilir. New worker waiting state deployment stale problemine yol açabilir.

HTTP Cache

Service Worker yokken normal fetch cached old response döndürüyorsa response Cache-Control ve validator'lara bakılır. Hard reload sonucu değişiklik ipucu verir. Same URL immutable yanlış yapılandırılmış olabilir. ETag server content değişmesine rağmen aynı kalıyor olabilir. Request Vary header matching kontrol edilir.

CDN

Origin doğrudan request güncel, public hostname eski response veriyorsa CDN cache şüphelidir. Age, cache-status veya vendor-specific debug header incelenebilir. Purge sonrası data düzeliyorsa invalidation policy sorgulanır. Cache key query veya auth context'i eksik olabilir. CDN configuration source control ve test sürecine alınmalıdır.

Backend Cache

CDN bypass edilmiş request bile eski response döndürüyorsa application veya distributed cache kontrol edilir. Cache key tenant veya locale ayrımı yapmıyor olabilir. Mutation invalidation backend cache'i temizlememiş olabilir. TTL çok uzun olabilir. Server trace cache hit ve database version bilgisini loglayabilir.

Database

En alt authoritative data gerçekten beklenen değeri içeriyor mu kontrol edilir. Mutation transaction rollback olmuş olabilir. Read replica replication lag eski data sunabilir. Cache problemi sanılan şey database consistency davranışı olabilir. Request hangi database node'a gittiği trace ile görülmelidir.

Katmanları Tek Tek Bypass Etme

Test kontrollü sırayla yapılmalıdır. Önce application query cache bypass edilir, sonra Service Worker, HTTP cache ve CDN ayrı incelenir. Direkt origin endpoint veya debug header kullanılabilir. Her aşamada aynı request ID ve resource version kaydedilir. Bu yöntem “cache'i temizleyince düzeldi” seviyesinden gerçek kök neden analizine geçiş sağlar.

Deployment Sonrası Stale Cache Problemleri

Deployment yeni JavaScript yayınlamakla bitmez, açık browser tab'ları ve persistent cache'ler eski version ile yaşamaya devam edebilir. Eski HTML eski chunk, yeni client eski IndexedDB schema veya persisted query cache eski API response shape kullanabilir. Service Worker waiting state ek version katmanı oluşturur. API contract backward compatibility deployment güvenliğinin temelidir. Cache-friendly deployment old client'ların belirli süre çalışacağını varsayar.

Eski HTML

HTML uzun cache almışsa kullanıcı yeni deployment manifest'ini görmez. Entry document revalidation policy kullanılmalıdır. CDN purge veya short s-maxage yardımcı olabilir. Personalized HTML private policy gerektirebilir. HTML version response header debug için eklenebilir.

Eski JavaScript

Açık tab eski bundle code'u kullanmaya devam eder. Server API yeni release ile eski contract'ı hemen kaldırırsa tab bozulur. Backward-compatible API transition period uygulanmalıdır. Eski chunk dosyaları CDN'de bir süre tutulmalıdır. Client version telemetry ne kadar eski release kaldığını gösterir.

Service Worker

Yeni worker waiting state'te olabilir ve kullanıcı eski cache strategy ile devam edebilir. Aggressive skipWaiting yeni code ile eski page state'i karıştırabilir. Update UX açık tasarlanmalıdır. Critical security patch farklı policy gerektirebilir. Worker version log ve dashboard'da izlenmelidir.

IndexedDB Schema

New client database version artırırken başka tab upgrade'i bloklayabilir. Migration old data'yı dönüştürmelidir. Rollback eski code'un yeni schema'yı anlayıp anlamadığı dikkate alınmalıdır. User-created offline data silinmemelidir. Versionchange event handling production testine dahil edilmelidir.

Query Cache Persistence

Persisted query cache localStorage veya IndexedDB'den new app startup'ta restore edilebilir. Response schema değiştiyse deserialize sonrası component hata verebilir. Cache buster app version veya API schema version'a bağlanabilir. Public stable data migrate edilebilir. Hassas user data logout ve version mismatch durumunda temizlenmelidir.

API Contract Değişikliği

Field remove veya semantic change old client'ları kırabilir. Expand-and-contract migration yaklaşımı daha güvenlidir. Önce server hem eski hem yeni client'ı destekler. Client adoption yeterli olduktan sonra eski contract kaldırılır. API version telemetry karar zamanını gösterir.

Cache-Friendly Deployment Nasıl Tasarlanır?

Cache-friendly deployment yeni sürüm yayınlandığında eski client'ların aniden kırılmadığı release modelidir. Hashed asset, backward-compatible API, versioned Service Worker cache ve güvenli IndexedDB migration birlikte çalışır. Persisted query data gerektiğinde buster ile temizlenir. Eski client compatibility belirli support window içinde korunur. Deployment rollback ve partial rollout senaryoları cache testlerinin parçası olmalıdır.

Hashed Assets

JS ve CSS content hash URL kullanmalıdır. Yeni release yeni asset üretir. Eski tab eski URL'ye erişmeye devam eder. CDN asset retention support window'u kapsar. HTML yeni manifest'i kısa revalidation ile alır.

Backward-Compatible API

Server yeni field eklerken eski field'i bir anda kaldırmamalıdır. Client adoption izlenir. Contract değişikliği version veya capability negotiation ile yönetilebilir. Old browser tab günler sonra request yapabilir. Breaking change deployment planında explicit olmalıdır.

Service Worker Cache Version

New worker yeni app shell cache'i kullanır. Old worker kendi cache'iyle açık tab'ları çalıştırabilir. Cleanup başka active version'a zarar vermemelidir. Workbox precache manifest revision handling bu işi kolaylaştırır. Update notification kullanıcı kontrolünü koruyabilir.

IndexedDB Migration

Schema version increment migration transaction ile uygulanır. Old tab versionchange event alır. Migration test fixture production'daki birkaç eski schema version'ını kapsar. Büyük cache data yeniden fetch edilebiliyorsa migration yerine discard daha basit olabilir. User-generated offline data asla sırf kolaylık için silinmemelidir.

Query Cache Buster

Persisted cache key app release veya schema version buster içerebilir. Incompatible release eski persisted snapshot'ı restore etmez. Compatible release cache reuse ederek hızlı startup sağlar. Buster her deployment değişirse caching faydası azalır. Yalnızca gerçek compatibility boundary'de güncellenmelidir.

Old Client Compatibility

Server log client version header üzerinden active old version dağılımını izleyebilir. Support window dolmadan breaking API kaldırılmaz. Critical security requirement daha hızlı forced update gerektirebilir. User unsaved state göz önünde bulundurulur. Progressive rollout old ve new client'ı aynı anda test eder.

Tarayıcı İçi Caching'de En Sık Yapılan Hatalar

Caching hataları genellikle tek bir header yanlışından değil bütün veri türlerine aynı policy uygulanmasından doğar. Static asset ile fiyat verisini aynı TTL üzerinden yönetmek buna örnektir. Service Worker, query cache ve browser cache birlikte kullanıldığında ownership belirsizliği stale response üretir. Security tarafında user-specific data'nın shared cache'e girmesi çok daha ağır sonuç yaratabilir. Cache tasarımının basit, ölçülebilir ve veri sınıfına göre farklılaşmış olması gerekir.

Her Şeyi Cache'lemek

Cache performans sağladığı için her response'u saklamak doğru değildir. Hassas veya real-time data cache için uygun olmayabilir. Çok büyük cache storage pressure oluşturur. Invalidation kodu application complexity'sini artırır. Cache yalnızca ölçülebilir fayda sağlayan resource'a eklenmelidir.

Her Şeye Aynı TTL Vermek

Country list ile inventory aynı değişim hızına sahip değildir. Global 5-minute TTL birine gereksiz kısa, diğerine tehlikeli uzun olabilir. Freshness matrix oluşturulmalıdır. TTL business riskinden türetilir. Server push varsa bazı data daha uzun fallback TTL kullanabilir.

no-cache ile no-store'u Karıştırmak

No-cache saklamayı engellemez, reuse öncesi validation ister. No-store cache'te saklamamayı hedefler. Yanlış kullanım gereksiz network veya güvenlik açığı oluşturabilir. Header code comment ve documentation ile açıklanmalıdır. Automated response header testleri regression'ı yakalar.

User-Specific Data'yı Public Cache'lemek

Bu hata başka kullanıcının private response'unu görmesine yol açabilir. Shared CDN caching personalized endpoint'te default kapalı olmalıdır. Cache key ve Vary security review görmelidir. Public directive yalnızca gerçekten ortak content'e verilmelidir. Incident durumunda purge ve session safety planı gerekir.

Vary Gereksinimini Unutmak

Aynı URL language veya encoding'e göre farklı response veriyorsa cache bunu bilmelidir. Vary eksikliği yanlış representation sunar. Gereksiz geniş Vary de hit rate'i azaltır. Content negotiation architecture açık yazılmalıdır. CDN behavior integration test ile doğrulanmalıdır.

HTML'i Uzun Süre Immutable Cache'lemek

HTML new asset manifest'in taşıyıcısıdır. Aynı URL altında değişiyorsa immutable yanlış seçimdir. Kullanıcı deployment sonrasında eski application version'a kilitlenebilir. Revalidation veya kısa edge TTL kullanılmalıdır. Hashed subresource'lar ise uzun immutable cache alabilir.

Service Worker Cache Versioning Yapmamak

Runtime ve precache entry'leri yeni release ile uyumsuz hale gelebilir. Cache name veya revision manifest versioning gereklidir. Eski cache cleanup yapılmalıdır. Aggressive delete eski tab'ı bozmamalıdır. Deployment test farklı worker state'lerini kapsamalıdır.

localStorage'ı Database Gibi Kullanmak

Büyük JSON payload localStorage'da synchronous parse ve write maliyeti oluşturur. Query ve index ihtiyacı karşılanmaz. Schema migration manual hale gelir. IndexedDB daha uygun persistent structured storage sunar. Küçük preference localStorage'da kalabilir.

Mutation Sonrası Invalidation Yapmamak

Server state değiştiğinde query cache eski kalır. Kullanıcı başka route'a gidip geri döndüğünde eski value görebilir. Mutation success ilgili key'leri update veya invalidate etmelidir. Cross-tab update ayrıca gerekebilir. Mutation dependency map automated test ile doğrulanabilir.

Optimistic Update İçin Rollback Tasarlamamak

Optimistic UI yalnızca success case düşünülürse server failure'da yanlış state kalır. Previous snapshot veya reversible patch saklanmalıdır. Concurrent mutation race condition ayrıca test edilmelidir. Error UI kullanıcıya net durum göstermelidir. Critical operation'da optimistic approach gereksiz olabilir.

Cross-Tab Tutarlılığını Unutmak

İki tab farklı memory cache taşır. Logout ve mutation diğer tab'a anında yansımayabilir. BroadcastChannel veya focus refetch çözüm sunar. Auth event daha yüksek priority taşımalıdır. Multi-tab test QA senaryolarına eklenmelidir.

Browser Storage'ın Silinebileceğini Unutmak

Best-effort storage browser tarafından evict edilebilir. Cache miss recovery bulunmalıdır. Offline user-generated unsynced data ayrı koruma sınıfına alınmalıdır. Persistent storage gerektiğinde istenebilir. Storage failure application boot'u tamamen durdurmamalıdır.

Cache Hit Rate Ölçmeden TTL Optimize Etmek

TTL artırmanın gerçekten request veya latency azalttığı ölçülmelidir. Hit rate zaten düşükse key fragmentation olabilir. Çok yüksek hit rate stale incident pahasına gelmiş olabilir. Resource class bazlı metric gerekir. Performance ve correctness aynı dashboard'da görülmelidir.

Production-Ready Browser Cache Checklist

Production cache kontrolü yalnızca Cache-Control header'a bakmakla tamamlanmaz. Static asset versioning, HTML revalidation, API freshness, query key, persistent storage ve logout güvenliği birlikte doğrulanmalıdır. Her başlık automated test ve production metric ile desteklenebilir. Checklist deployment review sırasında tekrar kullanılmalıdır. Kurumsal web uygulaması caching ve performans optimizasyon hizmeti kapsamında da bu kontroller uygulamanın gerçek veri sınıflarına uyarlanmalıdır.

Static Assets

Static asset kontrolünde URL versioning ve long-lived cache policy birlikte incelenir. Content değiştiğinde filename değişmelidir. CDN ve browser aynı resource'u güvenli biçimde uzun süre tutabilmelidir. Eski asset deployment sonrasında belirli retention süresince erişilebilir kalmalıdır. Asset manifest ile HTML version eşleşmesi test edilmelidir.

Content hash var mı?

JavaScript, CSS ve build-time image dosyalarında content hash bulunmalıdır. Hash yalnızca deployment numarası değil gerçek content değişimiyle ilişkilendirilirse cache verimi yükselir. Değişmeyen vendor chunk yeni release'te tekrar indirilmez. Build determinism hash churn'ünü azaltır. CI asset filename pattern'ini doğrulayabilir.

Long max-age var mı?

Hashed asset kısa max-age alıyorsa browser her ziyaret veya kısa aralıkta gereksiz validation yapabilir. Uzun max-age repeat visit performansını iyileştirir. Aynı URL altında content değişiyorsa uzun policy kullanılmamalıdır. CDN ve browser header'ları ayrı kontrol edilir. Production curl veya integration test header değerini doğrular.

Immutable doğru mu?

Immutable yalnızca URL'nin freshness süresi boyunca gerçekten değişmeyeceği resource'a verilmelidir. Content hash bu garantiyi sağlar. HTML veya mutable avatar URL'sine immutable eklenmemelidir. Yanlış kullanım purge sonrası bile browser stale copy yaratabilir. CI static asset path'leri için policy whitelist kullanabilir.

HTML

HTML application version discovery katmanıdır. Yeni asset manifest ve server-rendered data burada bulunabilir. Long immutable cache yerine revalidation veya uygun kısa freshness tercih edilir. Personalized HTML shared cache güvenliği açısından ayrıca incelenir. Deployment sonrası client'ın yeni HTML'i ne kadar sürede gördüğü ölçülmelidir.

Revalidation yapılıyor mu?

HTML no-cache ve ETag gibi validator ile tekrar kullanılmadan doğrulanabilir. Değişmediyse 304 bandwidth tasarrufu sağlar. CDN edge HTML caching varsa purge veya short s-maxage policy bulunmalıdır. Browser back navigation bfcache kullanabileceği için pageshow freshness ayrıca ele alınır. Header testi yalnız normal navigation değil reload behavior'ını da kapsar.

Yeni asset URL'leri hızlı geliyor mu?

Deployment sonrası HTML'in new hashed chunk listesine geçiş süresi ölçülmelidir. CDN stale HTML uzun süre eski release'e bağlayabilir. Active old tab normal olarak eski code kullanabilir. New navigation beklenen release ID'yi almalıdır. Synthetic monitor HTML içindeki build ID değişimini takip edebilir.

API

API caching policy resource freshness ve personalization seviyesine göre belirlenmelidir. Public reference endpoint ile authenticated account endpoint aynı header set'ini kullanmamalıdır. Validator, TTL ve shared cache davranışı contract dokümanında yer almalıdır. Error response caching ayrıca kontrol edilir. Mutation sonrası ilgili cache katmanlarına invalidation sinyali ulaşmalıdır.

Freshness gereksinimi belirlendi mi?

Her endpoint için verinin kabul edilebilir maksimum stale süresi tanımlanmalıdır. Bu değer teknik ekip tarafından rastgele seçilmemelidir. Product ve domain ekipleri business maliyetini belirtmelidir. HTTP max-age ve query staleTime buna göre belirlenir. Critical transaction server revalidation ile korunur.

Personalized veri korunuyor mu?

User-specific response shared cache'e girmemelidir veya güvenli partition uygulanmalıdır. Cache key tenant context'i doğru taşımalıdır. private veya no-store policy uygun yerde kullanılır. Logout client cache cleanup yapar. Security test farklı kullanıcılarla cache leakage kontrolü yapmalıdır.

Query Cache

Query cache server state lifecycle'ını frontend içinde yönetir. Key identity, staleTime ve mutation invalidation üç temel kontroldür. Persisted cache kullanılıyorsa app version compatibility eklenir. Cross-tab ve push event ihtiyacı resource'a göre değerlendirilir. Devtool ve RUM request count unexpected duplicate fetch'i gösterir.

Query key doğru mu?

Resource ID, filter, pagination ve tenant response'u etkiliyorsa key'e eklenmelidir. Aynı semantic query deterministic key üretmelidir. Key factory merkezi kullanılabilir. Eksik context data leakage, fazla context düşük hit rate oluşturur. Automated tests representative key üretimini karşılaştırabilir.

staleTime doğru mu?

staleTime bütün query'lerde tek global değer olmamalıdır. Data freshness sınıfına göre seçilmelidir. Reference data uzun, inventory kısa süre kullanabilir. Server push event gerektiğinde early invalidation yapabilir. Request count ve stale incident metric ayarı doğrular.

Mutation invalidation var mı?

Her mutation hangi query'leri etkilediğini bilmelidir. Direct cache update yeterli değilse related list invalidate edilir. Global invalidate network maliyetini artırır. Cross-tab ve server event mutation dışı değişiklikleri kapsar. Integration test mutation sonrası iki farklı view'ın current data gösterdiğini doğrular.

Persistent Cache

IndexedDB veya persisted query storage schema ve storage lifecycle sorumluluğu getirir. Cache version metadata new deployment ile uyumu kontrol eder. Quota ve eviction normal durum olarak ele alınır. User-generated offline data normal cache'ten ayrı priority taşır. Cleanup ve migration production telemetry ile izlenmelidir.

Schema version var mı?

Stored data format değiştiğinde version mekanizması bulunmalıdır. IndexedDB database version veya persisted payload schemaVersion kullanılabilir. New code eski data'yı migrate veya discard eder. Critical user data discard edilmeden önce recovery gerekir. Migration testleri birkaç eski release snapshot'ı kullanmalıdır.

Storage quota yönetiliyor mu?

Usage tahmini ve cache entry sınırları izlenmelidir. Runtime image cache sınırsız büyümemelidir. Quota error kullanıcı deneyimini bozmadan handle edilir. Low-priority cache önce temizlenir. Offline unsynced data mümkün olduğunca korunur.

Security

Caching security tasarımından ayrı ele alınamaz. User-specific content shared cache'e sızmamalıdır. Logout bütün relevant client cache katmanlarını temizlemelidir. Hassas data persistence minimum tutulmalıdır. Cache poisoning ve account switch testleri release güvenlik checklist'inde yer almalıdır.

Logout cleanup var mı?

Query cache ve memory user state logout ile temizlenmelidir. IndexedDB user records policy'ye göre silinir. Service Worker personalized cache entry varsa cleanup yapılır. Cross-tab event diğer tab'ları anonymous state'e geçirir. bfcache restore authenticated content'i yeniden doğrular.

Hassas veri cache dışında mı?

Hassas endpoint no-store gerektirebilir. Application bu response'u localStorage veya persistent query cache'e yazmamalıdır. Memory içinde tutulması gerekiyorsa session lifecycle ile temizlenir. Log ve analytics payload da sensitive field taşımamalıdır. Security data classification cache policy'nin girişidir.

Uçtan Uca Tarayıcı Cache ve Veri Tutarlılığı Mimarisi

Uçtan uca cache mimarisi farklı teknikleri rastgele eklemek yerine sıralı karar süreciyle kurulmalıdır. Önce veri sahipliği ve freshness sınıfları tanımlanır, ardından HTTP, query cache, Service Worker ve persistent storage katmanları ihtiyaç oldukça eklenir. Versioning, invalidation ve logout davranışı ilk tasarımın parçası olmalıdır. Observability olmadan TTL optimizasyonu yapılmamalıdır. Aşağıdaki adımlar kurumsal ölçekte uygulanabilir bir kontrol sırası sunar.

1. Verinin Source of Truth'unu Belirleyin

Her resource için authoritative kaynağı yazın. Normal online application'da server database çoğu data için source of truth olur. Offline-first use case local database'i geçici authority yapabilir. Cache entry'nin kaybolması durumunda ne olacağı bu karardan çıkar. Takım içinde farklı source varsayımları bulunmamalıdır.

2. Verileri Freshness Sınıflarına Ayırın

Static, low-change, frequently changing ve critical gibi sınıflar oluşturun. Her sınıf maksimum stale tolerance taşısın. Price ve permission gibi alanları public content'ten ayırın. Bu tablo max-age, staleTime ve fallback seçimini yönlendirsin. Business owner değerleri onaylasın.

3. Statik Asset'ler İçin Hashing Kullanın

JS, CSS ve build image content hash URL kullansın. Böylece uzun cache güvenli olur. Değişiklik yeni URL üretsin. HTML manifest latest asset'i göstersin. Eski asset retention açık tab'ları korusun.

4. HTTP Cache-Control Politikalarını Tanımlayın

Resource class başına response header policy belirleyin. Hashed asset uzun max-age immutable alabilir. HTML revalidation kullanabilir. Personalized response private veya no-store olabilir. CDN s-maxage ayrıca tanımlanabilir.

5. ETag/Revalidation Kurun

Mutable ama tekrar indirmenin maliyetli olduğu resource validator kullanabilir. ETag stable version semantics taşısın. no-cache revalidation gereken içerikte uygulanabilir. 304 rate izlenerek freshness window optimize edilir. ETag concurrency control için de kullanılabilir.

6. Query Key ve staleTime Tasarlayın

Client server-state cache identity'lerini merkezi key factory ile üretin. Tenant ve filter context'i unutmayın. staleTime data sınıfından türesin. Default refetch behavior anlaşılmadan tamamen kapatılmasın. Query devtool ile cache state gözlemlensin.

7. Mutation Invalidation Kurun

Her mutation affected query set'i tanımlasın. Server response direct cache update için kullanılsın. Aggregate ve related list gerektiğinde invalidate edilsin. Cross-tab update event'i eklenebilir. Invalidation latency ölçülsün.

8. Optimistic Update Gereksinimini Belirleyin

Her mutation optimistic olmak zorunda değildir. Düşük risk ve yüksek kullanıcı beklentisi olan action'lar seçilsin. Rollback ve concurrent mutation planı yapılsın. Version conflict desteklensin. Failure rate yüksekse model tekrar değerlendirilsin.

9. Offline Gerekiyorsa Service Worker Ekleyin

Service Worker yalnızca static asset caching için zorunlu değildir. Offline requirement varsa app shell ve network strategy tanımlansın. User-specific sensitive data runtime cache dışında tutulabilir. Worker lifecycle ve update UX tasarlansın. Workbox standart pattern'leri kolaylaştırabilir.

10. Büyük Persistent Veri İçin IndexedDB Kullanın

Large dataset, offline queue ve structured cache IndexedDB'de tutulabilir. localStorage büyük API payload için kullanılmasın. Object store ve index gerçek query pattern'e göre tasarlansın. Browser restart sonrası cache version doğrulansın. Storage eviction recovery bulunsun.

11. Cache Versioning Ekleyin

Service Worker cache name, persisted query schema ve API response version açık tutulmalıdır. Deployment incompatibility detect edilmelidir. Re-fetchable cache gerektiğinde discard edilebilir. User-created offline data migrate edilmelidir. Version metadata observability'yi güçlendirir.

12. Cross-Tab Sync Kurun

Logout ve critical mutation farklı tab'lara yayılmalıdır. BroadcastChannel same-origin uygulamalarda pratik çözümdür. Message küçük invalidation event taşısın. Tab offline veya suspended durumda event kaçırabileceği için focus refetch fallback kalsın. Auth event yüksek priority işlenmelidir.

13. Server-Push Invalidation Gereksinimini Değerlendirin

Data saniyeler içinde değişiyor ve stale tolerance düşükse WebSocket veya SSE değerlendirilebilir. Nadir update için polling daha basit olabilir. Push event cache'i invalidate etsin ve fresh data normal API'den alınsın. Reconnect gap recovery bulunsun. Connection cost kullanıcı sayısıyla hesaplanmalıdır.

14. Logout/Account Switch Cache Cleanup Yapın

User identity değiştiğinde bütün user-scoped cache'ler resetlenmelidir. Query key user context taşısın. IndexedDB ve Service Worker personalized data temizlensin. Public immutable cache korunabilir. Multi-tab logout automated test içinde yer alsın.

15. Storage Quota ve Eviction'ı Yönetin

Cache entry sayısı ve origin usage izlenmelidir. LRU veya TTL cleanup uygulanabilir. navigator.storage estimate yaklaşık kapasite gösterir. Offline-critical data düşük priority image cache'ten ayrı korunur. QuotaExceededError recovery test edilir.

16. SSR/Hydration Tutarlılığını Test Edin

Server query snapshot client cache'e doğru dehydrate edilmelidir. dataUpdatedAt freshness'i server fetch zamanından hesaplasın. Same query hydration sonrası gereksiz duplicate fetch yapıyor mu incelensin. Cached HTML ve client query staleTime birlikte test edilsin. Server Component ile client cache aynı entity version'ını anlayabilsin.

17. Cache Metrics Toplayın

Hit, miss, revalidation, stale response ve invalidation latency ölçülsün. Metric cache layer bazında ayrıştırılsın. Release ID regression analizi sağlasın. Storage growth gözlemlensin. Performance improvement correctness incident ile birlikte değerlendirilsin.

18. Offline ve Stale-Data Testleri Yapın

Network tamamen kapalı, yavaş ve kesintili senaryolar test edilsin. Cache stale olduğunda UI doğru uyarıyı versin. Offline mutation reconnect sonrası sync edilsin. Conflict senaryosu otomatik testte yer alsın. Critical endpoint stale fallback kullanmasın.

19. Deployment Cache Testleri Yapın

Old tab açıkken new release yüklenmesi test edilsin. Service Worker waiting state kontrol edilsin. Eski asset URL'leri erişilebilir kalsın. IndexedDB migration başka tab ile denenmeli­dir. API backward compatibility synthetic client sürümleriyle doğrulanmalıdır.

20. Gerçek Kullanıcı Verisiyle TTL'leri Sürekli Optimize Edin

Başlangıç TTL değerleri hipotezdir. Production hit rate, request count ve stale incident verisi gerçek sonucu gösterir. Çok kısa TTL network cost yaratıyorsa artırılabilir. Çok uzun TTL stale business incident oluşturuyorsa düşürülür veya event invalidation eklenir. Cache policy yaşayan engineering configuration olarak yönetilmelidir.

Tarayıcı İçi Caching İçin En İyi Programlama Dili Hangisidir?

Tarayıcı içi caching konusunda tek bir en iyi programlama dili yoktur. Browser API'leri çoğunlukla JavaScript üzerinden kullanıldığı için JavaScript ve TypeScript frontend tarafında temel araçlardır. HTTP caching ise backend hangi dilde yazılırsa yazılsın protocol semantics üzerinden çalışır. WebAssembly bazı ağır local processing use case'lerinde tamamlayıcı olabilir. Asıl yetkinlik dil seçmekten çok HTTP, browser networking, storage ve consistency modellerini anlamaktır.

JavaScript

Fetch API, Service Worker, Cache Storage, IndexedDB ve BroadcastChannel doğrudan JavaScript ecosystem içinde kullanılır. Browser lifecycle event'leri JavaScript ile yönetilir. Cache strategy prototype etmek için temel dildir. Async behavior ve event loop bilgisi storage ve network code kalitesini etkiler. JavaScript bilmek HTTP semantics öğrenmenin yerine geçmez.

TypeScript

TypeScript query key, cache entry metadata ve event payload gibi yapılara static type güvenliği ekler. Büyük codebase'de API response schema değişikliklerini daha erken yakalamaya yardımcı olur. Versioned BroadcastChannel message union type ile modellenebilir. Type sistemine aşırı güvenip runtime migration validation atlanmamalıdır. Persisted data her zaman eski veya beklenmeyen shape taşıyabilir.

Service Workers

Service Worker code'u TypeScript ile geliştirilip build sırasında JavaScript'e dönüştürülebilir. Worker global type definitions doğru configuration gerektirir. Request route ve cache strategy type helper'ları hata riskini azaltır. Runtime browser behavior yine test edilmelidir. Worker bundle mümkün olduğunca küçük tutulmalıdır.

TanStack Query

TypeScript query function response ve query key factory'lerde güçlü developer experience sağlar. Mutation variables ve cache update function type-safe olabilir. API schema generation ile server-client contract tutarlılığı iyileşir. Type correctness freshness correctness anlamına gelmez. staleTime ve invalidation yine runtime behavior'dır.

IndexedDB

Native IndexedDB API generic database schema type sağlamaz. Wrapper library TypeScript mapping sunabilir. Migration sırasında eski persisted record runtime validation gerektirir. Zod benzeri schema validation kullanılabilir ancak ek bundle maliyeti değerlendirilmelidir. Type definition data migration'ın yerini tutmaz.

WebAssembly Gereken Senaryolar

WebAssembly cache mekanizmasının kendisi için gerekli değildir. Büyük local search, compression veya computation offline dataset üzerinde çalışıyorsa yardımcı olabilir. IndexedDB'den alınan data WASM memory'sine aktarılırken copy maliyeti oluşabilir. Basit caching için gereksiz architecture yüküdür. Profiling gerçek CPU bottleneck göstermeden eklenmemelidir.

Backend Dilinden Bağımsız HTTP Caching

Cache-Control, ETag, Vary ve conditional request HTTP standardına aittir. Backend Node.js, Go, Java veya başka dilde olabilir. Önemli olan response header ve validator semantics'in doğru uygulanmasıdır. CDN aynı protocol bilgilerini kullanır. Ekip dil framework helper'ının default behavior'ını bilmelidir.

Dilden Daha Önemli Olan HTTP ve Browser Temelleri

Bir geliştirici no-cache ile no-store farkını bilmiyorsa hangi frontend framework'ünü kullandığı çok az fark yaratır. HTTP freshness, validator, request key ve browser lifecycle temel konulardır. Service Worker eklemek bu temelleri daha önemli hale getirir. Query library yalnızca abstraction sunar. Güçlü performans mühendisi abstraction'ın altındaki protocol behavior'ı anlayabilmelidir.

Frontend Alanında Yazılımcı Olmak İçin Caching Konusunda Neler Öğrenilmeli?

Frontend caching öğrenme sırası en alttaki browser ve network temellerinden başlamalıdır. Önce HTTP request-response lifecycle, sonra Cache-Control ve validators anlaşılmalıdır. JavaScript ile query cache ve Service Worker daha sonra eklenebilir. IndexedDB ve offline-first senaryolar distributed state problemini öğretir. Security ve observability olmadan caching bilgisi production ortamı için eksik kalır.

HTTP

Method, status code, header ve conditional request temel bilgidir. GET ile mutation method'larının cache semantics farkı öğrenilmelidir. ETag, If-None-Match ve 304 akışı elle curl ile test edilebilir. Vary ve authorization caching güvenlik açısından önemlidir. Protocol behavior framework'ten bağımsızdır.

Browser Networking

DevTools waterfall ve cache source okumak caching pratiğinin temelidir. DNS, connection ve HTTP cache request timing anlaşılmalıdır. Reload ile hard reload farkı test edilebilir. Service Worker intercept network path'i değiştirir. Network debugging gerçek bug üzerinde yapılınca bilgi daha kalıcı olur.

Cache-Control

max-age, private, no-cache ve no-store ilk öğrenilecek directive'lerdir. Sonra immutable ve stale-while-revalidate eklenebilir. Shared cache için s-maxage anlaşılmalıdır. Header kombinasyonları gerçek response üzerinde denenmelidir. Security-sensitive endpoint için safe default düşünülmelidir.

JavaScript

Promise, async flow ve event lifecycle bilinmelidir. Fetch cache modes ve AbortController query behavior'ını anlamayı kolaylaştırır. Memory cache Map ile basit prototype yapılabilir. Race condition ve out-of-order response test edilmelidir. JavaScript concurrency model caching consistency ile doğrudan ilişkilidir.

Service Workers

Register, install, waiting, activate ve fetch lifecycle öğrenilmelidir. CacheFirst, NetworkFirst ve SWR elle küçük demo üzerinde uygulanabilir. Sonra Workbox abstraction incelenebilir. Update lifecycle production deployment açısından özellikle önemlidir. Offline mode ve multi-tab test yapılmalıdır.

IndexedDB

Object store, key, index ve transaction kavramları öğrenilmelidir. Version upgrade başka tab ile test edilmelidir. Persistent storage ve quota davranışı anlaşılmalıdır. Offline mutation queue gerçek proje deneyimi sağlar. Wrapper library kullanılsa bile native lifecycle bilinmelidir.

TanStack Query / SWR

Query key, staleTime, invalidation ve mutation cache update kavramları temel konulardır. Devtool ile query state gözlemlenmelidir. SSR hydration ve persisted cache daha ileri konulardır. Library default behavior değiştirilmeden önce anlaşılmalıdır. Server state ile UI state ayrımı öğrenme sürecini kolaylaştırır.

Offline-First Architecture

Offline-first caching değil synchronization problemidir. Mutation queue, idempotency ve conflict resolution öğrenilmelidir. Local source of truth ile server authority farkı anlaşılmalıdır. Network reconnect happy path dışında partial failure test edilmelidir. Domain-specific merge konusu önemli ileri seviyedir.

Security

Cache poisoning, public personalized response ve auth cleanup öğrenilmelidir. localStorage token riskleri anlaşılmalıdır. Client permission gerçek authorization değildir. Logout multi-tab ve bfcache restore senaryoları test edilmelidir. Security review cache header configuration'ı da kapsamalıdır.

Observability

Hit rate tek başına yeterli değildir. Stale incident, invalidation latency ve storage usage izlenmelidir. DevTools local teşhis, RUM production görünümü sağlar. Release ID cache regression'ı deployment ile ilişkilendirir. Measurement olmadan TTL tuning tahmine dayanır.

Open Source ve İşbirliği ile Browser Caching

Browser caching konusunda gelişmenin etkili yollarından biri açık kaynak projelerin gerçek issue ve implementation'larını incelemektir. Service Worker, query caching ve IndexedDB wrapper projeleri farklı trade-off'ları doğrudan gösterir. Küçük documentation veya test katkılarıyla başlanabilir. Cache bug'ları özellikle race condition ve lifecycle bilgisi kazandırır. İşbirliği yapılan çözümü yalnız çalıştırmak değil neden doğru olduğunu açıklama becerisini de geliştirir.

Workbox

Workbox source ve documentation cache strategy implementation'ını anlamak için iyi referanstır. Strategy lifecycle ve plugin hook'ları incelenebilir. Expiration veya precache issue'ları gerçek browser edge case'lerini gösterir. Küçük reproduction repository hazırlamak katkı için değerlidir. Hazır API kullanmadan önce altındaki pattern anlaşılmalıdır.

TanStack Query

TanStack Query issue'ları staleTime, mutation race ve SSR hydration gibi gerçek problem örnekleri içerir. Query core implementation server state cache modelini anlamayı kolaylaştırır. Documentation improvement da değerli katkıdır. Reproduction test yazmak concurrency bilgisini geliştirir. Kullanıcıya özel business rule library responsibility ile karıştırılmamalıdır.

SWR

SWR stale-while-revalidate pattern'in application data layer'daki yorumunu gösterir. Deduplication ve revalidation trigger'ları incelenebilir. Küçük app demo ile network behavior gözlemlenebilir. Issue discussion farklı UX beklentilerini ortaya çıkarır. HTTP SWR directive ile library SWR kavramı karşılaştırılabilir.

Dexie.js

Dexie.js IndexedDB üzerinde daha ergonomik API sunan açık kaynak projelerden biridir. Transaction ve schema upgrade behavior'ı incelenebilir. Wrapper kullanırken native IndexedDB constraint'lerini öğrenmek önemlidir. Sync veya live query use case'leri ileri çalışma alanı sağlar. Technical tool olarak proje outline'ındaki persistence konularını uygulamaya dönüştürmek için kullanılabilir.

idb

idb native IndexedDB API'sini Promise tabanlı daha modern kullanım biçimine yaklaştıran küçük abstraction sunar. API yüzeyi sınırlı olduğu için native concept'lerle bağlantıyı görmek kolaydır. Upgrade ve blocked event handling örnekleri incelenebilir. TypeScript kullanımı schema tasarımına yardımcı olur. Wrapper database architecture kararını sizin yerinize vermez.

Service Worker Cookbook'ları

Küçük cache strategy örnekleri Service Worker davranışını öğrenmek için faydalıdır. Cache-first ve network-first pattern manuel yazılarak anlaşılabilir. Production security ve versioning ihtiyaçları demo'dan daha geniştir. Örneği doğrudan kopyalamak yerine request class ve failure behavior analiz edilmelidir. Offline testing farklı browser'larda yapılmalıdır.

GitHub Üzerinden Cache Strategy Katkıları

Açık kaynak PWA'da stale asset issue bulmak gerçek debugging deneyimi sağlar. Network trace ve reproduction adımları issue kalitesini artırır. Pull request before-after behavior test içermelidir. Cache key veya Service Worker lifecycle değişikliği backward compatibility açısından review edilir. Bu çalışmalar portföyde ölçülebilir frontend performance örneği oluşturur.

PWA Açık Kaynak Projeleri

PWA projeleri Service Worker, offline storage ve deployment update problemlerini aynı yerde gösterir. App shell ve dynamic data stratejileri karşılaştırılabilir. Multi-tab ve migration issue'ları gerçek kullanıcı geri bildirimlerinden öğrenilebilir. Storage quota gibi laboratuvar dışında zor görülen sorunlarla karşılaşılır. Küçük issue'larla başlanıp sync architecture çalışmalarına ilerlenebilir.

Diyarbakır Yazılım Topluluğu İçin Proje Fikirleri

Browser caching konusu yalnız anlatımla değil küçük laboratuvar projeleriyle çok daha iyi öğrenilir. Aynı API üzerinde farklı cache strategy'lerin latency ve stale data davranışı karşılaştırılabilir. Multi-tab, offline mutation ve deployment migration gibi senaryolar ekip halinde test edilebilir. Diyarbakır Yazılım Topluluğu bünyesinde geliştirilebilecek örnek projeler hem frontend hem backend katmanları arasında ortak çalışma fırsatı yaratır. Topluluğun mevcut projeleri için https://www.diyarbakiryazilim.com.tr/projects adresi incelenebilir.

Offline-First PWA Atölyesi

Katılımcılar basit task uygulamasını önce online-only olarak geliştirip sonra offline-first modele dönüştürebilir. App shell Service Worker ile cache edilir. Entity data IndexedDB'de tutulur. Offline mutation queue reconnect sonrasında server'a sync edilir. Son bölümde aynı kaydı iki cihazın değiştirdiği conflict senaryosu çözülür.

Service Worker Cache Lab

Aynı resource CacheFirst, NetworkFirst ve StaleWhileRevalidate ile ayrı route'larda test edilebilir. DevTools offline ve slow network profilleri kullanılır. Her stratejinin ilk ve tekrar yükleme süresi ölçülür. Stale content örneği özellikle oluşturulur. Katılımcılar hangi data için hangi strategy'nin uygun olduğuna kendi ölçümleriyle karar verir.

TanStack Query Invalidation Workshop

Product list ve detail query'leri ortak key factory ile tasarlanabilir. Mutation sonrası global invalidate ile targeted invalidate request sayıları karşılaştırılır. staleTime değiştiğinde window focus refetch behavior'ı gözlemlenir. Optimistic update failure ve rollback senaryosu eklenir. Workshop server state ile UI state farkını uygulamalı biçimde öğretir.

IndexedDB Offline App Projesi

Katılımcılar structured dataset'i IndexedDB object store içinde saklar. Index üzerinden filtreleme yapılır. Version 2 deployment ile schema migration uygulanır. Başka tab açıkken blocked event bilinçli olarak üretilir. Safe migration UX birlikte tasarlanır.

Cross-Tab Cache Sync Demo

İki tab aynı user profile query'sini açar. Tab A mutation yapınca Tab B önce stale kalır. Daha sonra BroadcastChannel event ile targeted invalidation eklenir. Logout mesajı bütün tab'larda cache cleanup tetikler. bfcache geri dönüş senaryosu da teste dahil edilir.

Cache Debugging Hackathon'u

Hazırlanan uygulamaya bilinçli cache bug'ları eklenebilir. Yanlış Vary, eski Service Worker, yanlış query key ve CDN-like cache simulation farklı görevler olur. Ekipler katmanları tek tek bypass ederek root cause bulur. Yalnız cache temizlemek puan getirmez ve gerçek neden açıklanmalıdır. Bu çalışma production incident düşünme biçimini güçlendirir.

Açık Kaynak PWA Starter Projesi

Topluluk reusable PWA starter geliştirerek Service Worker update, IndexedDB migration ve query cache örneklerini bir araya getirebilir. Her strategy neden seçildiğini açıklayan documentation taşımalıdır. Automated offline ve multi-tab test eklenebilir. Proje farklı etkinliklerde geliştirilmeye devam edebilir. Diyarbakır Yazılım Topluluğu hakkında daha fazla bilgi için https://www.diyarbakiryazilim.com.tr/about adresi kullanılabilir.

Sık Sorulan Sorular

Browser caching konusunda soruların önemli bölümü hangi cache katmanının seçileceği ve stale verinin nasıl önleneceği etrafında toplanır. Tek cevap bütün veri türlerine uygulanamaz. Static asset ile permission veya inventory aynı freshness politikasına sahip olmamalıdır. HTTP cache, query cache ve persistent storage ayrı görevler üstlenir. Aşağıdaki cevaplar production uygulamalarında karar vermeyi kolaylaştıracak temel çerçeveyi özetler.

Browser cache nedir?

Browser cache daha önce indirilen resource veya verilerin sonraki kullanımda tekrar ağdan alınmasını azaltan depolama mekanizmalarının genel adıdır. HTTP cache bunun en temel örneğidir. Service Worker Cache Storage ve application query cache ayrı katmanlardır. Her cache farklı lifecycle ve invalidation modeli kullanır. Bu nedenle “browser cache'i temizledim” ifadesi bütün cached state'in temizlendiğini garanti etmez.

HTTP cache nasıl çalışır?

Browser request için matching cached response arar. Response fresh ise doğrudan reuse edilebilir. Stale ise ETag veya Last-Modified validator ile conditional request yapılabilir. Server değişiklik yoksa 304 döndürür. Cache-Control freshness ve reuse davranışının temel kontrolüdür.

no-cache ile no-store arasındaki fark nedir?

No-cache response'un saklanabileceği ancak tekrar kullanılmadan önce revalidation gerektiği anlamına gelir. No-store response'un cache'te saklanmamasını ister. Güncel HTML için no-cache sık kullanılan seçimdir. Hassas response için no-store daha uygun olabilir. Application query cache bu HTTP directive'lerinden bağımsız çalışabilir.

ETag nedir?

ETag belirli resource representation sürümünü tanımlayan response header'ıdır. Client cached ETag'i If-None-Match ile server'a gönderir. Server aynı version mevcutsa 304 döndürebilir. If-Match ile optimistic concurrency control için de kullanılabilir. Resource değiştiğinde ETag'in de değişmesi gerekir.

304 Not Modified nedir?

304 conditional request sonucunda cached resource'un hâlâ geçerli olduğunu bildirir. Response body tekrar gönderilmez. Browser mevcut cached body'yi kullanır. Network round trip devam eder ancak bandwidth maliyeti düşer. 304 rate revalidation politikasının davranışını anlamak için izlenebilir.

Stale-while-revalidate nedir?

Stale-while-revalidate cached response'u hızlı biçimde sunup arka planda güncel version'ı isteme stratejisidir. Kullanıcı düşük latency alır. İlk response kısa süre eski olabilir. Public content ve düşük riskli data için uygundur. Price veya permission gibi critical data için bilinçli kullanılmalıdır.

Service Worker cache nedir?

Service Worker Cache Storage programatik request-response cache'idir. Application hangi request'in nasıl cache edileceğini kontrol eder. Cache-first, network-first ve SWR gibi strategy uygulanabilir. Entry expiration ve versioning application sorumluluğundadır. HTTP cache ile aynı mekanizma değildir.

HTTP cache ile Cache Storage arasındaki fark nedir?

HTTP cache server header ve browser HTTP semantics ile yönetilir. Cache Storage JavaScript veya Service Worker tarafından açık biçimde yönetilir. Aynı request iki katmandan da geçebilir. Bir cache'i temizlemek diğerini otomatik temizlemez. Double-caching stale bug'larının önemli nedenlerinden biridir.

IndexedDB ne zaman kullanılmalıdır?

Büyük structured data, offline-first entity ve browser restart sonrası tutulması gereken cache için IndexedDB uygundur. Küçük preference için gereğinden ağır olabilir. Schema versioning ve migration sorumluluğu vardır. Storage browser tarafından evict edilebilir. User-generated offline data için persistence ve sync ayrıca tasarlanmalıdır.

localStorage cache için uygun mudur?

Küçük preference ve basit metadata için uygundur. Büyük API payload'ları synchronous read-write nedeniyle önerilmez. String-only olduğu için JSON serialization gerekir. Hassas data kalıcı tutulmamalıdır. Structured büyük veri için IndexedDB daha uygundur.

TanStack Query staleTime nedir?

staleTime query data'nın ne kadar süre fresh kabul edildiğini belirler. Süre içinde normal stale-trigger refetch'leri yapılmaz. Süre dolduğunda data cache'te kalabilir ancak background revalidation yapılabilir. Değer data türüne göre seçilmelidir. Mutation invalidation staleTime bitmesini beklemeden query'yi stale yapabilir.

staleTime ile gcTime arasındaki fark nedir?

staleTime freshness süresidir. gcTime ise inactive query cache entry'sinin memory'de ne kadar tutulacağını belirler. Stale data cache'te bulunmaya devam edebilir. Fresh data component tarafından kullanılmıyorsa inactive olabilir. İki ayarın aynı değerde olması gerekmez.

Mutation sonrası cache nasıl temizlenir?

Mutation sonrası ilgili query invalidate edilebilir. Server response doğrudan cache'e yazılabilir. Related list veya aggregate query'ler refetch edilebilir. Optimistic update kullanılıyorsa success reconciliation ve failure rollback gerekir. Global cache clear yerine targeted invalidation tercih edilir.

Optimistic update nedir?

Server response gelmeden UI'ın beklenen başarılı sonuçla güncellenmesidir. Kullanıcı daha hızlı feedback alır. Failure durumunda cache rollback yapılmalıdır. Concurrent mutation ve version conflict dikkatle yönetilir. Critical veya yüksek failure olasılıklı işlemde pessimistic yaklaşım daha güvenli olabilir.

İki browser tab'ı arasındaki cache nasıl senkron tutulur?

BroadcastChannel aynı origin tab'ları arasında invalidate ve logout mesajı taşımak için kullanılabilir. Tab A mutation yapınca Tab B ilgili query'yi stale işaretleyebilir. Window focus refetch event kaçırıldığında fallback sağlar. Auth logout bütün tab'lara hızlı yayılmalıdır. Server push ayrı tab'larda real-time update için ek mekanizma olabilir.

Browser cache otomatik silinebilir mi?

Evet, browser storage pressure altında best-effort storage'ı evict edebilir. HTTP cache de browser'ın kendi eviction policy'sine tabidir. Cache miss normal behavior olarak ele alınmalıdır. Persistent storage belirli offline-critical data için istenebilir. Kullanıcı site verisini manuel olarak da temizleyebilir.

Kullanıcı logout olduğunda cache temizlenmeli midir?

User-specific query cache ve memory state temizlenmelidir. IndexedDB ve Service Worker personalized data varsa policy'ye göre silinmelidir. Public static asset cache'i gereksiz yere temizlenmez. Cross-tab logout diğer tab'larda da aynı cleanup'ı yapmalıdır. Hassas data yeni session'a kesinlikle sızmamalıdır.

Cache poisoning nedir?

Yanlış veya manipüle edilmiş response'un cache'e girip sonraki kullanıcı veya request'lere sunulmasıdır. Eksik cache key ve yanlış Vary önemli nedenlerdir. Personalized data'nın public shared cache'e girmesi ciddi security incident oluşturabilir. Error response caching de operasyonel sorun yaratabilir. Cache configuration security test kapsamına alınmalıdır.

Browser caching veri tutarlılığını nasıl etkiler?

Cache server state'in client üzerinde kopyasını oluşturduğu için belirli süre farklı version'ların var olmasına izin verir. TTL, revalidation, mutation invalidation ve push event bu farkı kontrol eder. Birden fazla cache katmanı varsa stale window büyüyebilir. Version metadata hangi copy'nin daha yeni olduğunu anlamayı kolaylaştırır. Cache performans kazanımı correctness ölçümüyle birlikte yönetilmelidir.

Tarayıcı içi caching stratejileri web uygulamalarında nasıl uygulanır?

Önce resource'lar statik, sık değişen, kullanıcıya özel ve kritik gibi freshness sınıflarına ayrılır. Static hashed asset için uzun HTTP cache, server state için query cache, offline büyük data için IndexedDB gibi uygun katman seçilir. Mutation sonrası invalidation ve logout cleanup baştan tasarlanır. Service Worker yalnızca gerçek offline veya programmatic cache ihtiyacı varsa eklenir. Sonuç production hit rate, stale incident ve request count üzerinden doğrulanmalıdır.

Cache-Control ETag ve stale-while-revalidate kullanılarak önbellek yönetimi nasıl optimize edilir?

Cache-Control resource'un freshness ve reuse politikasını tanımlar. ETag stale response'un server'da değişip değişmediğini düşük bandwidth ile doğrulamayı sağlar. Stale-while-revalidate ise düşük riskli content'te cached response'u hızlı gösterip background update yapabilir. Üç mekanizma birbirinin alternatifi değil farklı görevleri yerine getirir. Resource'un değişim hızı ve stale data maliyeti uygun kombinasyonu belirlemelidir.

Tarayıcı önbelleğinde güncel olmayan verilerin gösterilmesi nasıl önlenir ve veri tutarlılığı nasıl sağlanır?

İlk adım verinin source of truth'unu ve kabul edilebilir stale süresini tanımlamaktır. Mutation sonrası targeted invalidation, HTTP revalidation ve gerektiğinde server push update kullanılabilir. Query ve Service Worker gibi birden fazla cache katmanı aynı resource'u saklıyorsa freshness ownership açık olmalıdır. Version, ETag veya updatedAt metadata eski response'un yeni state'i ezmesini önlemeye yardımcı olur. Production'da invalidation latency ve stale data incident oranı izlenmelidir.

Service Worker Cache API LocalStorage ve IndexedDB hangi veri önbellekleme senaryolarında tercih edilmelidir?

Service Worker Cache Storage request-response ve offline asset stratejileri için uygundur. localStorage tema veya dil gibi küçük string preference'larda pratik seçimdir. IndexedDB büyük structured dataset, offline entity ve mutation queue için daha güçlüdür. Query cache ise aktif server state lifecycle'ını memory içinde yönetmek için kullanılabilir. Aynı veriyi gereksiz yere dört farklı katmanda tutmak yerine her katmana açık görev verilmelidir.

Tarayıcı caching stratejileri ve veri tutarlılığı optimizasyonu konusunda yakınımda danışmanlık veya eğitim nerede bulabilirim?

Bu konuda danışmanlık veya eğitim değerlendirirken yalnızca browser cache'i açıp kapatan bir yaklaşım yerine HTTP, Service Worker, query cache, IndexedDB, security ve production monitoring'i birlikte ele alan çalışma tercih edilmelidir. Özellikle kurumsal uygulamalarda cache key, account isolation, deployment versioning ve stale-data ölçümü birlikte incelenmelidir. Frontend memory yönetimi ve performans optimizasyonunun caching ile ilişkili tarafları için https://www.diyarbakiryazilim.com.tr/posts/frontend-de-memory-leak-analizi-ve-performans-iyilestirme içeriği de değerlendirilebilir. Diyarbakır çevresindeki teknik topluluk çalışmaları ve iletişim için https://www.diyarbakiryazilim.com.tr/about adresinden bilgi alınabilir. Mevcut uygulamanın gerçek network ve cache davranışı ölçülmeden genel TTL önerisiyle yetinmemek en sağlıklı başlangıçtır.

Sonuç

Tarayıcı İçi Caching Stratejileri ve Veri Tutarlılığı doğru uygulandığında web uygulamasını daha hızlı, daha dayanıklı ve daha ekonomik hale getirir, fakat cache sayısını artırmak tek başına kalite sağlamaz. Sağlam yaklaşım önce source of truth'u belirler, sonra her veri türü için freshness maliyetini hesaplar ve yalnızca ihtiyaç duyulan cache katmanlarını ekler. Static asset hashing, HTTP revalidation, query invalidation, Service Worker versioning, IndexedDB migration, cross-tab sync ve logout cleanup birbirinden ayrı değil aynı veri yaşam döngüsünün parçalarıdır. Kurumsal uygulamanızda stale data, gereksiz API trafiği, deployment sonrası eski bundle veya çoklu tab tutarsızlığı gibi sorunlar yaşıyorsanız mevcut cache zincirini uçtan uca ölçmek en doğru başlangıçtır. Caching mimarinizi, frontend performansınızı ve veri tutarlılığı yaklaşımınızı birlikte değerlendirmek için Diyarbakır Yazılım Topluluğu ile https://www.diyarbakiryazilim.com.tr üzerinden iletişime geçebilirsiniz.

share
share:

İletişim

Birlikte inşa edelim

İşbirliklerine, ilginç sorunlara ve kod, tasarım ile diğer konular hakkında sohbetlere açığız.

bize ulaş→

Bizi başka yerlerde bulun

GitHub
@diyarbakir-yazilim
Twitter
@diyaryazilim
LinkedIn
diyarbakir-yazilim-toplulugu
Instagram
@diyarbakiryazilim
YouTube
@diyarbakiryazilim
Slack
diyarbakiryazilim
WhatsApp
Topluluğa Katıl
Email
info@diyarbakiryazilim.org
Sevgiyle ve kodla inşa ediliyor

© 2026 Diyarbakır Yazılım Topluluğu — Tüm hakları saklıdır.