Caching Strategies
Caching must be treated as part of storefront architecture, not as a final patch. In YuiCraftPlugin projects, the main target is to cache expensive read paths while preserving dynamic correctness for cart, checkout, account, and form interactions.
Practical Caching Layers
1) Template/Fragment cache
Use Twig cache blocks for expensive but mostly static rendering sections.
{% set cacheKey = 'catalog-list-' ~ (category.id ?? 'root') %}
{% cache using key cacheKey for 3600 %}
{% include 'yui/components/catalog/toolbar/amount' %}
{% endcache %}
Use this for:
- category sidebars
- marketing content fragments
- static-ish page modules
Do not use this for:
- cart totals
- checkout forms
- customer session-sensitive fragments
2) Query/data cache
Cache expensive query results only when the same result is reused frequently and invalidation is clear.
{% set products = craft.yuiProducts(
['id', 'title', 'uri', 'yuiPrice'],
{ enabled: true },
{'id': 3},
16,
['productMediaAsset']
).cache(900).all() %}
Prefer short-to-medium TTL for catalog data that changes often.
3) HTTP/browser cache
Use HTTP caching headers for assets and truly static responses. Keep dynamic account/cart/checkout responses uncached unless you have strict vary rules.
Recommended Strategy by Page Type
- Product listing: cacheable fragments and query results
- Product detail: partial cache for expensive related blocks, not for session state
- Cart: avoid caching user totals/actions region
- Checkout: avoid caching any token or customer-sensitive form fragment
- Account: minimal caching; prefer per-request correctness
Minification and Inline JS/CSS
When inline code is required, gate minification by isMinifyEnabled() and wrap only stable code in cache blocks.
{% set jsContent %}
window.shopConfig = { currency: '{{ craft.getSiteCurrency() }}' };
{% endset %}
{% if isMinifyEnabled() %}
{% cache using key 'shop-config-inline-js' %}
{% minify js %}
{{ jsContent }}
{% endminify %}
{% endcache %}
{% else %}
{{ jsContent }}
{% endif %}
Invalidation Rules
Always define invalidation before introducing a cache block.
Checklist:
- What event updates this data?
- Which key prefix should be rotated?
- Is TTL enough, or do you need active invalidation?
- Can stale output break checkout or pricing correctness?
Security Warning: CSRF and Session Data
Never cache CSRF token output directly.
If a cached page still needs a valid CSRF token, use async token rendering:
{{ craft.renderFormToken()|raw }}
Reference: renderFormToken
Debug and Verification Workflow
After adding caching:
- measure first uncached response
- measure warm-cache response
- verify cart/checkout/account behavior
- verify content invalidates after update
- verify form submit still uses valid token
Do not merge caching changes without this verification pass.