Cache repeated Liquid filter results with assign
Cache filter results in variables using assign instead of calling the same filter multiple times with the same arguments.
Some filters have a performance cost. Individual calls might be fast (microseconds), but repeated calls add up. The Theme Inspector can show you filters called thousands of times in a single page render, accumulating to 100 ms or more.
Use assign to store filter results in variables, and reuse them instead of calling the filter multiple times. Use the Theme Inspector sandwich view to identify which filters are called most frequently.
Anchor to ExamplesExamples
Less performant:
{%- for product in collection.products -%}
<img src="{{ product.featured_image | image_url: width: 300 }}" />
<img src="{{ product.featured_image | image_url: width: 300 }}" />
{%- comment -%} Calls image_url twice for the same result {%- endcomment -%}
{%- endfor -%}
More performant:
{%- for product in collection.products -%}
{% assign product_image = product.featured_image | image_url: width: 300 %}
<img src="{{ product_image }}" />
<img src="{{ product_image }}" />
{%- endfor -%}
Using the Theme Inspector sandwich view:
- Generate a flame graph for your page.
- Switch to sandwich view.
- Sort by Self time to see cumulative impact.
- Look for operations called hundreds or thousands of times.
- Optimize by caching results or moving operations outside loops.
For example, you might see filter:image_url take 50 µs per call, but it's called 2,000 times (100 ms total).
Anchor to TestingTesting
- Use the Theme Inspector Chrome extension sandwich view to identify repetitive filter calls.
- Sort by Self time to see cumulative impact.
- Compare TTFB before and after caching filter results.
Anchor to ReferencesReferences
image_urlfilterassigntagfortagproduct.featured_image- Debugging common causes for slow loading in Shopify Liquid storefronts
- Avoid deeply nested Liquid loops
- Move operations outside loops
- Cache
block.settingsin a variable
Was this page helpful?