- i only speak liquid
- Posts
- "i only speak liquid" #80: Liquid & Site Speed & Loops
"i only speak liquid" #80: Liquid & Site Speed & Loops
Written by Elisa (a Storetasker Expert)
Hey everyone,
This is Elisa’s 4th and final edit of “i_only_speak_liquid”! Sad!
But don’t worry: In 2 weeks, we’ll have another writer for y’all.
Elisa’s been a gem of a writer for us these last few weeks, read her edits here:
—
Elisa is a 14-year e-commerce vet who’s worked with a bunch of DTC brands as a freelancer, full-time employee, and agency dev.
She’s passionate about taking old things and making them better, so she loves working with brands with chaotic old codebases to build new features and improve site speed.
Ofc: She’s an expert on Storetasker 😉 apply here.
Let’s dive in 🤿
What I’ve been thinking about: Liquid & Site Speed & Loops
My first Shopify agency hired only front-end developers. It was a great team with some sharp minds and one very, very misguided belief: if it happens on the server, it’s fast.
Liquid can be slow, as we learned when one team built a client a “super collections” page that showed twenty collections with just over fifty products each. Before the page would even start loading, the browser would spend a full twenty seconds thinking about it.
I was the developer who got to diagnose and fix the issue.
It turns out, it was the nested loops. Servers are fast, but if you’re looping through twenty collections with fifty products each and each of those products has ten variants with a variant metafield that has ten images each - that’s 100k things the server has to get through.
Since then, Liquid’s gotten a lot faster, but the memories of that site remain: to me, loops are still no good very bad things to be avoided at all costs. Here’s how I do that.
Do it Ten Times:
Say I need to generate a gallery of ten identical images for each variant on our super collections page. Because we’re writing good code, it makes the most sense to do this:
{% for collection in super_collections_array %}
{% for product in collection.products %}
{% for variant in product.variants %}
{% for j in (1..10) %}
{% assign collection = variant_image_array[j] %}
<img src=”www.imageurl.com” data-etc=”other stuff” />
{% endfor %}
{% endfor %}
{% endfor %}
{% endfor %}
But because we’re avoiding nested loops and we know we’ve got 10 variant images, this is a better choice for site speed:
{% for collection in super_collections_array %}
{% for product in collection.products %}
{% for variant in product.variants %}
{% assign image = variant_image_array[1] %}
<img src=”www.imageurl.com” data-etc=”other stuff” />
{% assign image = variant_image_array[2] %}
<img src=”www.imageurl.com” data-etc=”other stuff” />
{% assign image = variant_image_array[3] %}
<img src=”www.imageurl.com” data-etc=”other stuff” />
...
etc.
{% endfor %}
{% endfor %}
{% endfor %}
If we have to change anything in the image, we’ve gotta do it ten times. Let’s make a separate snippet for the image that looks like this:
{% assign image = variant_image_array[i] %}
<img src=”www.imageurl.com” data-etc=”other stuff” />
And use it as follows:
{% for collection in super_collections_array %}
{% for product in collection.products %}
{% for variant in product.variants %}
{% render 'separate-image-snippet', i: 1 %}
{% render 'separate-image-snippet', i: 2 %}
{% render 'separate-image-snippet', i: 3 %}
...
etc.
{% endfor %}
{% endfor %}
{% endfor %}
Now we’ve cut one nested loop out, but it’s not difficult to edit the image if we need to.
Use Capture:
Say you’re on a PDP. You’ve got variant images, variant swatches, variant-specific ingredients, descriptions, and so on.
You can loop through your variants every single time you’re rendering one of these things as shown in this very shorthand code block:
<product-images>
{% for variant in product.variants %}
<img />
{% endfor %}
</product-images>
<product-swatches>
{% for variant in product.variants %}
<swatch />
{% endfor %}
</product-swatches>
<product-ingredients>
{% for variant in product.variants %}
<ingredients />
{% endfor %}
</product-ingredients>
<product-descriptions>
{% for variant in product.variants %}
<descriptions />
{% endfor %}
</product-descriptions>
But we can replace these four loops with one:
{% liquid
assign product_images = ''
assign product_swatches = ''
assign product_ingredients = ''
assign product_description = '' %}
{% for variant in product variants %}
{% capture product_images %}
{{ product_images }}
<img />
{% endcapture %}
{% capture product_swatches %}
{{ product_swatches }}
<swatch />
{% endcapture %}
{% capture product_ingredients %}
{{ product_ingredients }}
<ingredients />
{% endcapture %}
{% capture product_descriptions %}
{{ product_descriptions }}
<descriptions />
{% endcapture %}
{% endfor %}
<product-images>
{{ product_images }}
</product-images>
<product-swatches>
{{ product_swatches }}
</product-swatches>
<product-ingredients>
{{ product_ingredients }}
</product-ingredients>
<product-descriptions>
{{ product_descriptions }}
</product-descriptions>
I especially like this format because it lets me get an overview of the structure of the page.
Hopefully this gives you something to think about!
3 links you can’t miss:
1 app I like:
Imgix - though it’s not technically a Shopify app, Imgix is basically Shopify’s image filters on steroids. It even lets you convert PNGs & JPGs to next-gen formats like AVIF and WebP - right from your Liquid.
One learning as a freelancer:
Sometimes, I feel like half my work is undoing the damage done by someone in a hurry. Don’t be afraid to ask for the time you need to do the thing right the first time.
Let’s stay in touch - find me here on Linkedin.
-Elisa