# SFCC Önbellek Rehberi: Page Cache, Custom Cache ve eCDN

URL: https://www.ozanaltinbas.com/tr/makale/sfcc-caching
Author: Ozan Altinbas (Ozan Altınbaş), SFCC Technical Architect
Published: 2026-11-12
Category: Performans ve SEO | Tags: SFCC, Önbellek, Performans, SFRA

---

Salesforce B2C Commerce'te önbellek tek bir ayardan ibaret değildir. Bir istek eCDN'den, web katmanındaki page cache'ten (sayfa önbelleği) ya da uygulama sunucusundan yanıtlanabilir; her katmanın kendi API'si, kendi geçersiz kılma (invalidation) kuralları ve kendine özgü hata biçimleri vardır. Salesforce'un [Caching Strategies for Salesforce B2C Commerce](https://developer.salesforce.com/docs/commerce/sfra/guide/caching-strategies-sk.html) dokümanı yaygın yanılgıyı açıkça adlandırır: önbellek, "birkaç template'e `<iscache>` eklemekten" ibaret değildir.

Bu rehber bir isteği katman katman takip ediyor; SFRA cache middleware, `dw.system.Response`, `caches.json` ve `dw.system.CacheMgr` için minimal ve doğru kod veriyor ve neyin nerede önbelleğe alınacağını gösteren bir tabloyla bitiyor. Aktarılan her limit Salesforce dokümantasyonundan geliyor. Platformun genel resmi için [SFCC rehberiyle](https://www.ozanaltinbas.com/tr/sfcc) başlayın.

---

## Önbellek katmanlarına genel bakış

Salesforce'un kuralı, önbellekteki içeriği alışverişçiye olabildiğince yakından sunmaktır; çünkü isteğin geçtiği her katman zaman ve kapasite maliyeti demektir.

| Katman | Ne tutar | Nasıl kontrol edilir | Nasıl temizlenir |
|---|---|---|---|
| eCDN | Edge'de statik storefront içeriği | `Cache-Control` TTL, fingerprint'li asset URL'leri | TTL'in dolması veya CDN Zones API purge |
| Static content cache (web katmanı) | Görseller, CSS, JS | Business Manager'da sitenin Cache sekmesindeki TTL | Business Manager, `InvalidateCache` job step'i, replikasyon |
| Page cache (web katmanı) | Controller yanıtlarının tamamı ve remote include parçaları | `response.setExpires()`, SFRA cache middleware veya `<iscache>` | TTL'in dolması, replikasyon, Business Manager |
| SCAPI web katmanı önbelleği | Uygun Shopper API `GET` yanıtları | Page caching açık; Custom API'lerde `setExpires()` | Kendi TTL ve invalidation kuralları (web katmanı önbellek dokümanına bakın) |
| Custom cache (uygulama sunucusu) | Pahalı hesaplamaların veya dış çağrıların sonuçları | `caches.json` ve `dw.system.CacheMgr` | `expireAfterSeconds`, kod aktivasyonu, replikasyon |
| Request ve session | İstek veya alışverişçi bazlı veri | Modül kapsamı, `request.custom`, `session.privacy` | İsteğin veya oturumun sonu |

Custom object'ler bu listede bilerek yok: uygulama sunucuları arasında tutarlıdırlar ama her okuma tüm katmanlardan geçer; yani önbellek değil, depolamadırlar.

---

## SFCC page cache nasıl çalışır?

Page cache, web katmanında, uygulama sunucularının önünde durur. Salesforce onu, anahtarı **query string dahil tam URL** olan bir key-value deposu olarak tanımlar. Hit durumunda web katmanı saklanan yanıtı sunar ve içindeki remote include'ları aynı şekilde çözer; miss durumunda uygulama sunucusunu çağırır ve yanıt önbelleğe alınabilir olarak işaretlenmişse saklar. Bundan üç sonuç çıkar:

1. **Hit durumunda kodunuz çalışmaz.** Controller, middleware, hook veya loglama yoktur; uygulama ve depolama katmanlarına yük binmez.
2. **Her farklı URL ayrı bir kayıttır.** Farklı bir parametre değeri, fazladan bir parametre ya da farklı bir parametre sırası yeni kayıtlar oluşturur. Salesforce'un adını koyduğu anti-pattern, ürün tile'larına pozisyon parametresi eklemektir: aynı tile, arama sonucundaki her pozisyon için ayrı ayrı önbelleğe alınır.
3. **Varsayılan olarak hiçbir şey önbelleğe alınmaz.** [`dw.system.Response` referansına](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_system_Response.html) göre yanıtlar yalnızca kod bunu açıkça istediğinde önbelleğe alınır.

Trailhead'in [Implement Caching in the Web-Server Layer](https://trailhead.salesforce.com/content/learn/modules/b2c-implement-cache/b2c-implement-cache-web-server) ünitesine göre **Administration > Global Preferences > Feature Switches** altındaki iki feature switch işe yarar: **Web Adapter Cache Key Ignore by Query String**, kampanya ID'si gibi anlamsız parametreleri anahtardan çıkarır; **Enable 404 response caching overrides** ise 404 yanıtlarının önbelleğe alınmasını sağlar.

### Business Manager'da page caching'i etkinleştirme

Page caching, site bazında **Administration > Sites > Manage Sites > (site) > Cache** altında **Enable Page Caching** ile ayarlanır; kapalıyken `<iscache>` yok sayılır. [Content Cache dokümantasyonu](https://developer.salesforce.com/docs/commerce/sfra/guide/b2c-content-cache.html) ayarları instance türüne göre kısıtlar:

| Instance türü | Kısıtlama |
|---|---|
| Sandbox veya development | Yok |
| Staging | Production ayarına ait değerler değiştirilemez |
| Production | Page cache kapatılamaz ve Cache sekmesindeki TTL en az 24 saattir |

Salesforce, değişiklikleri anında görmek için sandbox ve staging'de page caching'i kapatmayı önerir. Yeni bir endpoint'i test ederken tekrar açın; aksi hâlde önbellek hataları ancak production'da ortaya çıkar.

---

## Önbellek sürelerini belirleme: SFRA middleware, script API ve `<iscache>`

Önbellek süresini iki API belirler: `dw.system.Response#setExpires()` ve ISML `<iscache>` tag'i. İkisi de tek bir template'e değil **yanıtın tamamına** uygulanır ve süre birden fazla kez ayarlanırsa en düşük değer kazanır. Salesforce script API'yi güçlü biçimde önerir; çünkü iç içe template'lerde süreyi hangisinin belirlediğini anlamak zordur.

### SFRA: cache middleware

SFRA'nın `app_storefront_base` cartridge'ı `cartridge/scripts/middleware/cache.js` dosyasıyla gelir. SFRA 6.1'de bu dosya dört fonksiyon export eder:

| Middleware | Önbellek süresi | Kişiselleştirilmiş (`price_promotion`) | Base SFRA'daki örnekler |
|---|---|---|---|
| `applyDefaultCache` | 24 saat | Hayır | `Home-Show`, `Page-Show`, `Page-Include` |
| `applyPromotionSensitiveCache` | 24 saat | Evet | `Product-Show`, `Tile-Show` |
| `applyShortPromotionSensitiveCache` | 1 saat | Evet | `Search-Show`, `Search-ShowAjax` |
| `applyInventorySensitiveCache` | 30 dakika | Hayır | Kendi route'larınız için hazır |

Middleware yalnızca `res.cachePeriod`, `res.cachePeriodUnit` ve `res.personalized` değerlerini ayarlar; route tamamlandığında SFRA'nın `server.js` dosyası bunları `setExpires()` çağrısına ve kişiselleştirme varsa `setVaryBy('price_promotion')` çağrısına çevirir:

```javascript
'use strict';

var server = require('server');
var cache = require('*/cartridge/scripts/middleware/cache');

// Brand-Show: haftada birkaç kez değişen bir landing sayfası.
// applyDefaultCache, res.cachePeriod = 24 (saat) ayarlar.
server.get('Show', cache.applyDefaultCache, function (req, res, next) {
    res.render('brand/landing', { brandId: req.querystring.bid });
    next();
});

module.exports = server.exports();
```

Hazır fonksiyonların karşılamadığı bir TTL için `res.cachePeriod` ve `res.cachePeriodUnit` değerlerini ayarlayan küçük bir middleware yazın (SFRA `'minutes'` değerini okur, geri kalan her şeyi saat sayar); böylece politika route imzasında görünür kalır.

### SFRA dışında: `setExpires()` ve `setVaryBy()`

SFRA dışı bir controller'da veya bir Custom API script'inde response API'sini doğrudan çağırın. `setExpires()`, epoch'tan bu yana geçen milisaniyeyi ya da bir `Date` nesnesini alır:

```javascript
// Bu yanıtı 30 dakika önbellekte tut
response.setExpires(Date.now() + 30 * 60 * 1000);

// Yalnızca çıktı gerçekten price book veya promosyona göre değişiyorsa
response.setVaryBy('price_promotion');
```

Önbellek süreleri sabit olmak zorunda değil: Caching Strategies dokümanı, ürün sayfasının TTL'ini `availabilityModel.isOrderable(n)` ile kademelendirir; stok derinse uzun, tükenmek üzereyse kısa.

### Template'lerde `<iscache>`

Bu tag'e SiteGenesis'te ve eski cartridge'larda hâlâ rastlarsınız. [`iscache` element referansına](https://developer.salesforce.com/docs/commerce/sfnext/guide/b2c-iscache.html) göre `relative` sayfayı belirli bir süre sonra, `daily` ise günün sabit bir saatinde geçersiz kılar:

```html
<iscomment>Sayfa oluşturulduktan 24 saat sonra geçersiz olur</iscomment>
<iscache type="relative" hour="24" />

<iscomment>Her gün 03:30'da geçersiz olur</iscomment>
<iscache type="daily" hour="3" minute="30" />

<iscomment>Kişiselleştirilmiş: her price book ve promosyon kombinasyonu için bir kayıt</iscomment>
<iscache type="relative" hour="1" varyby="price_promotion" />
```

Tuzak local include'lardadır: template'teki **ve local olarak include edilen tüm template'lerdeki** en düşük ayar sayfanın tamamını belirler. Paylaşılan bir partial'da unutulmuş kısa bir `<iscache>`, onu kullanan her sayfanın süresini sessizce kısaltır.

---

## Remote include: kişiselleştirilmiş parçalar içeren önbellekli sayfalar

`<isinclude template="...">` bir **local include**'dur: aynı istekte render edilir ve aynı önbellek kaydının parçası olur. `<isinclude url="...">` ise bir **remote include**'dur: web katmanı onu kendi önbellek politikasıyla ayrı bir istek olarak çeker ve sonucu önbellekteki çerçevenin içine yerleştirir. Bir gün boyunca önbellekte duran bir sayfanın alışverişçinin oturum durumunu yine de gösterebilmesi bu sayede olur. SFRA'nın header'ı tam olarak bunu yapar:

```html
<iscomment>pageHeader.isml: bu satırların çevresindeki sayfa önbellektedir; her include ayrı bir istektir</iscomment>
<isinclude url="${URLUtils.url('Account-Header')}" />
<isinclude url="${URLUtils.url('Cart-MiniCart')}" />
<isinclude url="${URLUtils.url('Page-IncludeHeaderMenu')}" />
```

`Account-Header` ve `Cart-MiniCart`, `server.middleware.include` kullanır (doğrudan gelen istekleri reddeder) ve cache middleware'leri yoktur; dolayısıyla her istekte render edilirler. `Page-IncludeHeaderMenu` ise `applyDefaultCache` kullanır, çünkü menü herkes için aynıdır.

- **Yalnızca çıktıyı değiştiren parametreleri geçirin.** Include URL'leri de birer önbellek anahtarıdır.
- **İç içe geçmeyi sığ tutun.** Salesforce'un [troubleshooting ünitesi](https://trailhead.salesforce.com/content/learn/modules/b2c-implement-cache/b2c-implement-cache-troubleshoot) üç ile yedi seviye arasını önerir; ne kadar az, o kadar iyi.
- **Geçersiz kılma pipeline bazındadır.** `Home-Show`'u geçersiz kılmak, içindeki remote include'ları yenilemez.
- **Mevcut dinamik include'ları yeniden kullanın.** Salesforce'un örneği: her tile için bir wishlist kalbi render etmek yerine wishlist'i zaten dinamik olan bir include'da data attribute olarak sunun ve ikonları client tarafında güncelleyin.

Page Designer da aynı modeli kullanır: `PageMgr.renderPage()`, iç içe iki remote include üzerinden render eder: görünürlük parmak izini (visibility fingerprint) hesaplayan `__SYSTEM__Page-Include` ve `__SYSTEM__Page-Render`. Bu yüzden her görünürlük varyasyonu ayrı önbelleğe alınır. Content slot'lar da remote include içinde sunulur.

---

## Kişiselleştirilmiş önbellek: `price_promotion` neye göre ayrışır?

`setVaryBy()` referansı nettir: platform varyantları **price book, promosyon, sıralama kuralı (sorting rule) ve A/B test segmenti** kombinasyonuna göre ayırır ve desteklenen tek değer `price_promotion`'dır. Başka bir yolla kişiselleştirilmiş bir sayfa **önbelleğe alınmamalıdır**, çünkü alışverişçiler yanlış varyantı görür. İstekteki herhangi bir şey vary-by ayarladığında yanıtın tamamı kişiselleştirilmiş sayılır ve kayıt sayısı her price book ve promosyon kombinasyonuyla katlanır.

- HTML'de fiyat veya promosyon ibaresi varsa: SFRA'nın PDP, tile ve arama için yaptığı gibi promosyona duyarlı bir önbellek kullanın.
- Başka bir şeye göre değişen çıktı (alışverişçi adı, sepet, session verisi): önbelleksiz bir remote include'a veya client tarafı bir çağrıya taşıyın.
- Sayfada fiyat yoksa vary-by da olmasın. Hit oranından yer, karşılığında hiçbir şey vermez.

---

## `dw.system.CacheMgr` ile custom cache

Bir yanıt page cache'e alınamıyorsa (sepet, checkout, hesap, önbelleksiz include'lar) içindeki pahalı işi önbelleğe alın. [Custom Caches dokümantasyonu](https://developer.salesforce.com/docs/commerce/sfra/guide/b2c-custom-caches.html) tipik adayları sayar: birleştirilmiş konfigürasyon, mağaza stoku gibi dış sistem yanıtları ve "bu ürünün herhangi bir varyantı promosyonda mı" gibi türetilmiş veriler.

### Limitler ve davranış

- Tüm custom cache'ler için **uygulama sunucusu başına** yaklaşık **20 MB** ayrılır; bir code version en fazla **100** cache destekler.
- Kayıtlar **128 KB** ile sınırlıdır. Daha büyük bir loader sonucu kodunuza döner ama saklanmaz ve custom warn log'a bir uyarı düşer.
- Cache'ler **uygulama sunucusu başınadır** ve senkronize edilmez; `invalidate(key)` yalnızca mevcut sunucudaki kaydı siler.
- Aktif code version'da bir dosya değiştiğinde, bir code version aktive edildiğinde ve veri ya da kod replikasyonundan sonra tüm custom cache'ler temizlenir.
- Yalnızca primitive değerler ve ağaç yapılı nesneler saklanabilir ve okumalar değiştirilemez (immutable) kopyalar döndürür; `undefined` ve Script API nesnelerine izin verilmez ([`dw.system.Cache` referansı](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_system_Cache.html)).

### Cache tanımlama: package.json ve caches.json

Cartridge kök dizinindeki `package.json`, tanım dosyasını kendisine göreli bir yolla gösterir. Cartridge zaten hook kaydediyorsa `caches` anahtarını aynı dosyaya ekleyin:

```json
{
  "hooks": "./hooks.json",
  "caches": "./caches.json"
}
```

Ardından cache'leri `caches.json` içinde tanımlayın:

```json
{
  "caches": [
    { "id": "StorefrontConfig", "expireAfterSeconds": 3600 },
    { "id": "ExternalStoreStock", "expireAfterSeconds": 60 }
  ]
}
```

Her `id` code version genelinde benzersiz olmalıdır (tekrar eden bir ID cache'i devre dışı bırakır ve hata loglar); `expireAfterSeconds` isteğe bağlıdır. [`CacheMgr.getCache()`](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/scriptapi/html/api/class_dw_system_CacheMgr.html), ID hiçbir `caches.json` içinde tanımlı değilse exception fırlatır. Cartridge yapısı için [cartridge geliştirme rehberine](https://www.ozanaltinbas.com/tr/makale/sfcc-cartridge-development) bakın.

### Önbellek üzerinden okuma

`get(key, loader)` kullanın: önbellekteki değeri döndürür ya da miss durumunda loader'ı çalıştırıp sonucu saklar.

```javascript
'use strict';

var CacheMgr = require('dw/system/CacheMgr');
var Site = require('dw/system/Site');

function getStorefrontConfig() {
    var siteId = Site.getCurrent().getID();
    // Anahtarı site ve locale ile kapsamlayın; anahtara asla kişisel veri koymayın (anahtarlar loglarda görünebilir)
    var key = siteId + '_' + request.locale + '_config';

    return CacheMgr.getCache('StorefrontConfig').get(key, function loadConfig() {
        // Yalnızca miss durumunda, bu uygulama sunucusunda çalışır
        var raw = Site.getCurrent().getCustomPreferenceValue('storefrontConfigJson');
        return raw ? JSON.parse(raw) : null; // yalnızca düz veri; asla undefined döndürmeyin
    });
}

module.exports = { getStorefrontConfig: getStorefrontConfig };
```

`storefrontConfigJson`, elinizdeki pahalı kaynağın yerini tutan bir örnektir. Miss'lere göre tasarlayın: kayıtlar her an düşebilir ve her sunucu kendi kopyasını ısıtır. Tek bir istek içinde tekrar kullanılan değerler için modül düzeyinde bir değişken ya da `request.custom` yeterlidir; alışverişçiye özel küçük veriler için `session.privacy`'yi tercih edin, çünkü `session.custom`'a yazmak platformun dinamik customer group'ları yeniden değerlendirmesine yol açar.

---

## Siteyi yormadan geçersiz kılma

Önbellekteki sayfalar TTL dolduğunda, bir veri ya da kod replikasyonu çalıştığında (site önbelleğini otomatik olarak geçersiz kılar) veya biri **Administration > Sites > Manage Sites > (site) > Cache** altında sitenin tamamını ya da tek bir page cache partition'ını geçersiz kıldığında yenilenir.

- **Temizleme kademelidir.** **15 dakika** sürer; dokümantasyon buna "Clear Period" der. Bu süre içinde yeniden tetiklemek süreyi sıfırlar ve önbelleğin hiçbir zaman tam temizlenmemesine yol açabilir.
- **Partition'lar etki alanını daraltır.** Bir partition, `Home-Show` gibi controller'ları gruplar; her biri en fazla 20 pipeline içeren en fazla 10 partition oluşturabilirsiniz. Remote include pipeline'larını ayrı bir partition'a koyun.
- **Replikasyon hedeflenebilir.** Bir replikasyon süreci **Do not invalidate** veya **Invalidate Impacted Cache Partitions** olarak ayarlanabilir; böylece acil bir düzeltme replike edilip yalnızca ilgili partition geçersiz kılınabilir.
- **Job'lar da bunu yapabilir.** `InvalidateCache` job step'i `InvalidatePageCache`, `InvalidateStaticCache` ve isteğe bağlı bir `PageCachePartitionIDs` listesi alır.

Veriler sık sık bayat görünüyorsa nedenini bulun: Salesforce, geçersiz kılmayı tetikleyen zamanlanmış job'ları kontrol etmeyi ve sık fiyat değişiklikleri için granular replikasyon kullanmayı önerir.

---

## eCDN: edge önbelleği ve purge

eCDN statik storefront içeriğini önbelleğe alır. Trailhead'in [Clear eCDN Cache and Configure HSTS](https://trailhead.salesforce.com/content/learn/modules/ecdn-b2c-commerce/ecdn-b2c-commerce-cache-hsts) ünitesine göre bir dosya, `Cache-Control` TTL'i dolana kadar önbellekte kalır; header yoksa varsayılan süre 30 gündür. Statik asset URL'leri bir fingerprint taşır; değişen bir asset yeni bir URL alır ve normal bir deployment purge gerektirmez.

Gerektiğinde CDN Zones API, SCAPI short code host'unuzda `POST /cdn/zones/v1/organizations/{organizationId}/zones/{zoneId}/cachepurge` endpoint'ini sunar. Bir `path` ya da bir `tags` listesi alır (ikisi birden değil) ve `sfcc.cdn-zones.rw` scope'u gerektirir. [B2C CLI bu endpoint'i sarmalar](https://salesforcecommercecloud.github.io/b2c-developer-tooling/cli/ecdn.html):

```bash
b2c ecdn cache purge --tenant-id zzxy_prd --zone my-zone --path "www.example.com/dw/image/v2/realm_instance/*"
```

eCDN purge ile page cache geçersiz kılma ayrı işlemlerdir; bir şeyi temizlemeden önce bayat yanıtı hangi katmanın tuttuğunu bulun.

---

## Headless: SCAPI ve PWA Kit önbelleği

SCAPI, uygun `GET` yanıtlarını (aralarında Shopper Products, Search, SEO, Stores ve Experience var) [server-side web katmanında](https://developer.salesforce.com/docs/commerce/commerce-api/guide/server-side-web-tier-caching.html) önbelleğe alır; bunun için sitede page caching açık olmalıdır.

- **Önbellek anahtarı herhangi bir hook çalışmadan önce hesaplanır.** Price book veya promosyonu değiştiren bir hook anahtarı değiştirmez; bu da hit oranını düşürür ya da yanlış kaydın sunulmasına yol açar. Kişiselleştirmeyi Shopper Context API üzerinden yapın; hook mantığının nereye ait olduğunu [SFCC hook rehberi](https://www.ozanaltinbas.com/tr/makale/sfcc-hooks) anlatıyor.
- **Custom API'ler önbelleğe açıkça dahil edilir.** [Custom API caching](https://developer.salesforce.com/docs/commerce/commerce-api/guide/custom-api-caching.html) sayfasına göre page caching'i açın, ardından script'te `response.setExpires()` çağırın.
- **`personalized=none` sizin verdiğiniz bir sözdür.** Shopper API spesifikasyonları bunu, yanıtın CDN katmanında önbelleğe alınabilmesi için kişiselleştirmeden çıkmak olarak tanımlar. Gereklidir ama yeterli değildir: endpoint'in web katmanında da önbelleğe alınabilir olması gerekir.

PWA Kit'te render edilen HTML, uygulamanın ayarladığı `Cache-Control` header'ına göre Managed Runtime CDN'inde önbelleğe alınır; Retail React App'in ana sayfası `s-maxage` ile birlikte `stale-while-revalidate` gönderir. Daha geniş karşılaştırma için [SFRA vs PWA Kit](https://www.ozanaltinbas.com/tr/makale/sfra-vs-pwa-kit) yazısına bakın.

---

## Önbellek hit oranını ölçme

**Reports & Dashboards** içinde **Technical** sekmesini açın ve toplam işlem süresindeki paya göre sıralayın. Son üç sütun; önbellekten okunan, hesaplanıp önbelleğe yazılan ve her zaman dinamik hesaplanan istekleri gösterir.

- **Son sütunda %100** görmek, endpoint'in önbelleğe alınmadığı anlamına gelir; nedeni genellikle yeni bir route'ta unutulmuş bir direktiftir.
- **Önbelleğe alınan bir endpoint orada %0 göstermelidir.** Aksi, hatalara ya da önbelleği atlayan kod yollarına işaret eder.
- **Kilit sayfaları ve include'ları izleyin:** `Home-Show`, `Search-Show`, `Product-Show`, `Page-Show`, ürün tile'ları, `Page-Include` ve slot'lar. Salesforce'a göre arama tile'ları için ideal değer en az %99 hit oranı ve 1 ms veya altında yanıt süresidir.

Ardından dinamik kalanları **Administration > Operations > Code Profiler** ile profilleyin (Extended Script Development modu, Category equals REQUEST filtresi, Elapsed Time > Sum sıralaması) ve canlıya çıkıştan birkaç gün sonra tüm endpoint'leri gözden geçirin. Daha hızlı yanıtlar Core Web Vitals'a da yansır; o tarafı [SFCC SEO rehberi](https://www.ozanaltinbas.com/tr/makale/commerce-cloud-seo-guide) ele alıyor.

---

## Sık yapılan hatalar

- **Yeni bir route'ta önbellek direktifi olmaması.** Çalışır, sadece %100 dinamiktir.
- **Önbelleğe alınan bir controller'da yan etkiler.** Session yazımları, cookie'ler veya analytics çağrıları yalnızca miss'e neden olan alışverişçi için çalışır, çünkü hit durumunda controller çalışmaz.
- **Önbellekteki bir yanıtta kişiselleştirilmiş çıktı.** Dört vary-by boyutunun dışındaki her şey önbelleksiz bir remote include'a aittir.
- **Her yerde vary-by veya değişken include parametreleri.** İkisi de önbellek kayıtlarını boşuna katlar.
- **Tazelik stratejisi olarak çok kısa TTL'ler.** Partition'lar, granular replikasyon veya hedefli geçersiz kılma daha iyi sonuç verir.
- **Tekrarlanan manuel geçersiz kılma.** Her tetikleme Clear Period'u yeniden başlatır.

---

## Neyi nerede önbelleğe almalı?

| İçerik | Katman | Mekanizma | Başlangıç noktası |
|---|---|---|---|
| Görseller, CSS, JS | eCDN ve static content cache | Fingerprint'li URL'ler, `Cache-Control` | Uzun TTL; rutin purge yok |
| Ana sayfa, içerik ve landing sayfaları | Page cache | `cache.applyDefaultCache` | 24 saat |
| PDP ve ürün tile'ları | Page cache, kişiselleştirilmiş | `cache.applyPromotionSensitiveCache` | 24 saat ve `price_promotion` |
| Arama ve kategori sonuçları | Page cache, kişiselleştirilmiş | `cache.applyShortPromotionSensitiveCache` | 1 saat |
| Stoğa duyarlı parçalar | Page cache | `cache.applyInventorySensitiveCache` veya kademeli `setExpires()` | 30 dakika veya stoğa göre |
| Oturum durumu, mini sepet, hesap | Önbelleksiz remote include | `server.middleware.include`, cache middleware yok | Önbelleğe alınmaz |
| Konfigürasyon, dış API sonuçları | Custom cache | `CacheMgr.get(key, loader)` | `expireAfterSeconds` = kabul edilebilir bayatlık |
| Headless ürün ve arama verisi | SCAPI web katmanı | Page caching açık; kişiselleştirme için Shopper Context | SCAPI web katmanı önbellek dokümanına göre |

---

## Önemli çıkarımlar

- Page cache anahtarı tam URL'dir: URL'leri, özellikle include URL'lerini, çıktıyı değiştirmeyen parametrelerden arındırın.
- `<iscache>` yerine SFRA middleware'ini veya `response.setExpires()`'ı tercih edin; bir yanıttaki en düşük süre kazanır.
- Sayfa çerçevesini önbelleğe alın; alışverişçiye özel parçaları önbelleksiz remote include'larda tutun.
- `price_promotion` price book, promosyon, sıralama kuralı ve A/B segmentini kapsar; başka hiçbir şeyi değil.
- Custom cache'ler sunucu başınadır; toplamda yaklaşık 20 MB, kayıt başına 128 KB sınırı vardır ve kalıcılık garantisi yoktur.
- Partition bazında geçersiz kılın, Clear Period'un bitmesini bekleyin ve her canlıya çıkıştan sonra hit oranlarını kontrol edin.

Yoğun satış döneminden önce bir storefront'un önbellek stratejisine ikinci bir göz isterseniz [hizmet sayfasında](https://www.ozanaltinbas.com/tr/hizmet) nasıl çalıştığıma bakabilir ya da [benimle iletişime geçebilirsiniz](https://www.ozanaltinbas.com/tr/iletisim).

## Ek kaynaklar

- [Caching Strategies for Salesforce B2C Commerce](https://developer.salesforce.com/docs/commerce/sfra/guide/caching-strategies-sk.html): önbellek katmanları, kişiselleştirilmiş önbellek ve Technical raporu.
- [Content Cache](https://developer.salesforce.com/docs/commerce/sfra/guide/b2c-content-cache.html): page ve static cache ayarları, partition'lar ve geçersiz kılma.
- [Custom Caches](https://developer.salesforce.com/docs/commerce/sfra/guide/b2c-custom-caches.html): `caches.json`, limitler ve `CacheMgr` kullanımı.
- [Server-Side Web-Tier Caching](https://developer.salesforce.com/docs/commerce/commerce-api/guide/server-side-web-tier-caching.html): SCAPI'nin Shopper API yanıtlarını nasıl önbelleğe aldığı.
- [Implement Caching in the Web-Server Layer](https://trailhead.salesforce.com/content/learn/modules/b2c-implement-cache/b2c-implement-cache-web-server): page caching, feature switch'ler ve remote include'lar üzerine Trailhead ünitesi.
