The Dumbest Performance Fix Ever: How I Saved a Client 5 Seconds of Load Time
Sometimes the biggest performance wins don't come from complex engineering, but from deleting code. Here is how I sped up a Shopify store by 5000% in minutes.

In the world of web development, we often fetishize complexity. We talk about tree-shaking, edge caching, database indexing, and WebAssembly. We act like every performance problem requires a Ph.D. in Computer Science to solve.
But sometimes, the problem is just plain dumb. And the solution is even dumber.
This is the story of the easiest, most embarrassing, yet highest-impact performance fix of my career as a Shopify Developer.
The Scene of the Crime
A panicked client reached out to me on Upwork. They were a scaling fashion brand doing decent volume, but their conversion rate had tanked overnight. They had just launched a new homepage design, and it was dragging.
We're not talking "needs a little optimization" slow. We're talking "go make a coffee while the page loads" slow. The Time to First Byte (TTFB) was consistently hovering around 6 to 8 seconds. In e-commerce, that is a death sentence.
The Investigation
I assumed the worst. massive unoptimized images, 50 third-party apps loading scripts, maybe some heavy video background.
But when I looked at the timeline, the browser wasn't even receiving data for the first 6 seconds. The delay was entirely server-side. In the Shopify world, that usually means one thing: Liquid code gone wrong.
I opened up the theme editor and started hunting. It didn't take long to find the smoking gun in index.liquid.
The Culprit
Right in the middle of the homepage template, I found a block of code intended to display "Trending Products."
The logic seemed innocent enough on the surface. The client wanted to show 8 products that were tagged with 'New' and 'Summer', sorted by price.
Here is what the code looked like (simplified):
{% assign trending_products = '' %}
{% for product in collections['all'].products %}
{% if product.tags contains 'New' and product.tags contains 'Summer' %}
{% assign trending_products = trending_products | append: product.handle | append: ',' %}
{% endif %}
{% endfor %}
{% assign trending_array = trending_products | split: ',' | sort_natural %}
{% for handle in trending_array limit: 8 %}
{% render 'product-card', product: all_products[handle] %}
{% endfor %}Do you see it?
They were iterating through collections['all'].products. In Shopify, collections['all'] contains every single product in the store. This store had over 4,000 products.
On every single page load, the server was being asked to:
- Load 4,000 product objects into memory.
- Loop through every single one.
- Check string arrays for tags.
- Build a massive string.
- Split and render.
It was a brute-force search running on every request. It was hitting Shopify's memory limits, causing internal throttling, and choking the page rendering.
The "Dumb" Fix
I didn't write a better sorting algorithm. I didn't implement caching. I didn't use an API.
I deleted the code.
Then, I went into the Shopify Admin:
- Clicked Products > Collections.
- Created a new Automated Collection called "Trending Homepage".
- Set conditions:
Tag is equal to NewANDTag is equal to Summer. - Set Sort order:
Price: Low to High.
Then I went back to the code and wrote:
{% for product in collections['trending-homepage'].products limit: 8 %}
{% render 'product-card', product: product %}
{% endfor %}The Result
Total time to implement: 3 minutes.
Lines of code: Reduced by 15.
Page Load Time: 8.2s → 0.4s.
The client was stunned. They thought they needed a server upgrade (which you can't even do on Shopify) or a complete rebuild. They were ready to pay thousands of dollars for a "performance audit."
The Lesson
As developers, we love code. We love control. But on platforms like Shopify (or Next.js, or WordPress), the platform is usually smarter than we are.
Native features—like Shopify's automated collections—are indexed, cached, and optimized by engineers who work at the platform level. Attempting to replicate database-level logic in the templating layer is a trap.
Before you write a complex loop, ask yourself: "Is there a button for this?"
Sometimes, the smartest engineering decision is knowing when not to code at all.
Tags
Comments (0)
Leave a Comment
No comments yet. Be the first to share your thoughts!
