Skip to main content
Version: 2.0.0

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.

  • 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:

  1. What event updates this data?
  2. Which key prefix should be rotated?
  3. Is TTL enough, or do you need active invalidation?
  4. 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:

  1. measure first uncached response
  2. measure warm-cache response
  3. verify cart/checkout/account behavior
  4. verify content invalidates after update
  5. verify form submit still uses valid token

Do not merge caching changes without this verification pass.