Web Dev App Dev SEO & GEO Blog Contact Start a Project
Case Study May 29, 2026 16 min read

Case Study: How We Cut a Heritage E-Commerce Site's Load Time from 6 Seconds to 180ms

Slow websites kill sales. We encountered a heritage e-commerce client in Rajasthan whose beautiful traditional craft products were struggling to sell online because their site took over 6 seconds to load on mobile devices. This directly impacted their bottom line, costing them thousands in lost revenue every month.

The Problem: A Legacy Site Losing Revenue

Our client, an established online retailer of traditional Rajasthani textiles and handicrafts, faced a critical challenge. Their e-commerce platform, built several years ago on a popular open-source CMS with numerous plugins, had become a bottleneck for their business growth. While their desktop experience was passable at around 3.5 seconds load time, the mobile experience was abysmal, consistently clocking in at over 6 seconds. This meant that customers browsing intricate sarees or handcrafted jewellery on their phones often abandoned their carts before pages even fully loaded.

The impact was clear: mobile bounce rates hovered at 70%, and mobile conversion rates were a dismal 0.8%. Google data indicates that for every second a page takes to load, conversion rates drop by an average of 4.42%. For our client, this translated into hundreds of thousands of rupees in lost sales each month, especially considering the growing trend of mobile shopping in Tier-2 Indian cities. Their PageSpeed Insights score for mobile was a shocking 28, indicating severe performance issues that also hurt their search engine visibility. They needed a fundamental shift, not just minor tweaks.

Our Solution: A Multi-Pronged Performance Overhaul

Our team approached this challenge with a comprehensive strategy, focusing on server-side, frontend, and code-level optimisations. We didn't just apply quick fixes; we re-engineered the site for speed from the ground up.

Deep-Dive Audit and Stack Analysis

We began with an exhaustive audit of their entire technology stack. This involved analysing server logs, database performance, third-party script impact, and every line of CSS and JavaScript. We identified the primary culprits: oversized images, render-blocking scripts, inefficient database queries, and a server infrastructure that was simply not equipped to handle their traffic or the demands of a modern e-commerce site. The existing setup was a classic example of "The Real Cost of WordPress: Why Indian SMBs Are Paying Too Much for Too Little," where a once-simple platform becomes a performance drain.

Server-Side Optimisation

The first major step was upgrading their infrastructure. We migrated the entire e-commerce application from shared hosting to a dedicated, high-performance cloud server instance located in India, specifically Mumbai, to minimise latency for their primary audience. We configured NGINX as a reverse proxy and web server, known for its superior performance in handling concurrent connections compared to Apache. Database queries were scrutinised and indexed for optimal speed. We enabled HTTP/2 for multiplexing requests over a single connection, significantly reducing overhead. Server-side caching, implemented with Redis, was put in place to store frequently accessed data and reduce database load.

Frontend Performance Engineering

With the server foundation solid, we turned our attention to the user-facing elements.

  • Image Optimisation: This was a massive win. We converted all product images to WebP format, which offers superior compression without noticeable quality loss. We implemented lazy loading for all images below the fold, ensuring that only visible content loaded immediately. Responsive image techniques were used to serve appropriately sized images based on the user's device.
  • Critical CSS & JavaScript: We identified and inlined the critical CSS required for the initial page render, deferring all other stylesheets. Similarly, non-essential JavaScript was deferred or loaded asynchronously to prevent it from blocking the rendering path. All CSS and JavaScript files were minified and concatenated to reduce file sizes and the number of HTTP requests.
  • Font Optimisation: Custom fonts, while aesthetically pleasing, can be heavy. We self-hosted fonts, subsetted them to include only necessary characters, and used font-display: swap to ensure text remained visible during font loading.
  • Caching Strategy: Beyond server-side caching, we implemented robust browser caching policies, instructing browsers to store static assets locally for extended periods, drastically speeding up return visits.

Code Refactoring and Platform Modernisation

Our team also undertook significant code refactoring. This involved simplifying the theme, removing unused plugins and functionalities, and streamlining the core application logic. We focused on reducing DOM complexity and ensuring that server responses were lean and efficient. This wasn't just about tweaking settings; it was about making the underlying code more efficient, aligning with principles we apply when building Sub-200ms Websites: The Full Technical Blueprint for PHP Developers.

The Results: Tangible Growth and Improved User Experience

The transformation was dramatic and immediate. Within weeks of deployment, the client's website performance metrics soared, directly translating into business growth.

Metric Before (Mobile) After (Mobile)
Initial Load Time 6.2 seconds 180 ms
First Contentful Paint 4.8 seconds 90 ms
Largest Contentful Paint 5.5 seconds 150 ms
PageSpeed Score 28 92
Mobile Conversion Rate 0.8% 2.1%

The overall load time for mobile users plummeted from an average of 6.2 seconds to a blistering 180 milliseconds. Desktop load times also saw a significant reduction, dropping from 3.5 seconds to under 120 milliseconds. The client's PageSpeed Insights score for mobile jumped from 28 to a remarkable 92, and desktop scores hit 98.

More importantly, these technical improvements directly impacted their business. Mobile conversion rates surged by 162%, climbing from 0.8% to 2.1% within three months of the optimisations. Overall, the site's conversion rate increased by 28%. This meant for an average order value of ₹2,500, the client saw an additional ₹3.2 lakhs in revenue monthly from mobile alone, a direct return on their investment in performance. Bounce rates on mobile devices decreased by 35%, indicating a much more engaged user base. The improved Core Web Vitals also positively influenced their search engine rankings, increasing organic visibility. This case perfectly illustrates how crucial performance is, especially for Indian businesses where mobile-first access is dominant. Google Developer Guidelines consistently highlight the importance of speed for user experience and SEO.

Frequently Asked Questions

How can we optimize ultra-high-resolution, texture-heavy product images for heritage crafts without losing delicate visual details like zari threadwork or stone carvings?

Heritage e-commerce sites (such as those selling luxury Banarasi silk, hand-woven Pashmina shawls, or intricate Rajasthani handicraft carvings) face a direct conflict between page speed and visual fidelity. Standard high-ratio lossy compression algorithms can blur fine details, introduce block artifacts, and shift subtle color profiles, rendering the product unappealing and driving down conversion rates. To resolve this, developers must implement a sophisticated, multi-layered digital asset management (DAM) and delivery architecture.

First, rather than using uniform compression rates, implement custom, adaptive formats based on asset types. While standard web content performs exceptionally well with standard AVIF or WebP lossy compression at low quality targets (e.g., 65-75%), heritage crafts require a higher baseline quality ceiling—typically AVIF at a quality of 82–85 or WebP at 85–88. Additionally, the sRGB color profile must be explicitly preserved during encoding. Stripping color metadata to save 2–3 KB can result in dull or inaccurate product hues under different device displays, leading to high return rates.

Second, employ a hybrid zoom architecture. Instead of serving a massive 3MB high-resolution original image on page load, serve a highly compressed but visually crisp WebP/AVIF baseline image (around 40-70KB) that conforms to the viewport size. This baseline image is loaded lazily with the loading="lazy" attribute, and its critical viewport equivalent is preloaded with fetchpriority="high". The ultra-high-definition asset (which contains the raw, zoomable details) should only be fetched asynchronously on-demand when the user hovers or clicks to zoom into the product image. This zoom interface can utilize a dynamic tile-loading library or an asynchronous canvas-based rendering engine, preventing heavy payloads from interfering with core performance metrics.

Third, leverage responsive markup. Use the HTML5 <picture> element with comprehensive srcset definitions to serve the exact pixel density needed for the requesting client. For instance, a mobile device with a 2x device pixel ratio (DPR) should receive a 600px width image, whereas a high-resolution desktop screen gets a 1200px image, with appropriate density descriptors:

<picture>
  <source srcset="/images/products/saree-300w.avif 300w, /images/products/saree-600w.avif 600w, /images/products/saree-1200w.avif 1200w" sizes="(max-width: 768px) 100vw, 50vw" type="image/avif">
  <source srcset="/images/products/saree-300w.webp 300w, /images/products/saree-600w.webp 600w, /images/products/saree-1200w.webp 1200w" sizes="(max-width: 768px) 100vw, 50vw" type="image/webp">
  <img src="/images/products/saree-600w.jpg" alt="Intricate Rajasthani Zari Work Saree" width="600" height="600" loading="lazy" decoding="async">
</picture>

Finally, use vectorized SVG boundaries or inline CSS-based BlurHash strings as placeholders. When a user lands on the page, they immediately see a highly styled, fast-rendering blurred version of the image representing the primary color palette of the craft, which transitions smoothly via a hardware-accelerated CSS opacity fade once the target next-gen image is fully parsed by the browser.

What is the optimal automated build pipeline and image compression workflow for scaling large-scale e-commerce catalogs?

Manually optimizing and converting thousands of high-definition craft images is an inefficient, error-prone use of development resources. Dynamic, runtime image compression plugins within legacy CMS platforms are equally problematic, as they exhaust server CPU cycles on each uncached request, leading to massive spikes in Time to First Byte (TTFB). The solution is to establish an automated, decoupled asset processing pipeline that operates entirely out-of-band.

The ideal architecture relies on a file-system observer or a CI/CD build hook. When an administrator or content creator uploads raw product imagery (usually high-resolution JPEGs or TIFFs), a background task is triggered. In a modern setup, this is run either through a server-side daemon using inotify or a GitHub Actions runner. The pipeline utilizes the highly optimized sharp library in a Node.js environment or native system binaries like cwebp, gif2webp, and libsquoosh.

A typical automated bash script runs as follows, converting and generating multi-format responsive variants:

#!/usr/bin/env bash
# Automated Image Optimisation Script for E-Commerce Catalogs
INPUT_DIR="/var/www/uploads/raw"
OUTPUT_DIR="/var/www/html/images/catalog"

mkdir -p "$OUTPUT_DIR"

for img in "$INPUT_DIR"/*.{jpg,jpeg,png}; do
  [ -e "$img" ] || continue
  filename=$(basename -- "$img")
  extension="${filename##*.}"
  filename="${filename%.*}"

  # 1. Generate optimised AVIF variants at standard view widths
  avifenc --min 18 --max 24 --speed 6 "$img" "$OUTPUT_DIR/${filename}-600w.avif"
  avifenc --min 18 --max 24 --speed 6 --rescale 1200 1200 "$img" "$OUTPUT_DIR/${filename}-1200w.avif"

  # 2. Generate optimised WebP variants as bulletproof fallback
  cwebp -q 82 -m 6 -sharp_yuv "$img" -o "$OUTPUT_DIR/${filename}-600w.webp"
  cwebp -q 82 -m 6 -sharp_yuv -resize 1200 1200 "$img" -o "$OUTPUT_DIR/${filename}-1200w.webp"

  # 3. Maintain a lightweight progressive fallback JPEG
  jpegtran -copy none -optimize -progressive "$img" > "$OUTPUT_DIR/${filename}-fallback.jpg"
done

For high-volume catalogs, offload this computational overhead entirely by decoupling image hosting from the main application server. This is achieved by linking storage to an S3-compatible bucket (such as AWS S3 or Cloudflare R2) and routing all image requests through an on-the-fly image manipulation proxy like imgproxy or Thumbor deployed on a lightweight container instance.

By applying Cloudflare Workers or CDN caching rules directly in front of this proxy, the very first request for a specific size generates the optimized next-gen asset, caches it at the edge, and subsequently serves it to global users in under 20ms. This prevents the primary e-commerce database and web server from bearing any image-processing overhead.

How does flat JSON product indexing bypass slow database queries in resource-constrained environments?

In traditional e-commerce installations on low-cost or shared servers, database input/output (I/O) is the single most common bottleneck. Relational databases like MySQL must execute costly, non-indexed JOIN operations across complex tables (such as wp_posts, wp_postmeta, and wp_term_relationships in WooCommerce) to render basic search, filtering, and catalog pages. When multiple users filter products simultaneously by attributes like price, fabric, region, and availability, the server CPU utilization spikes to 100%, causing query queues to back up and ballooning page-load times to several seconds.

Flat JSON product indexing bypasses this relational complexity entirely. Instead of querying the database on every page view, the site queries a denormalized, lightweight, static JSON index file containing the entire product catalog. This index file is regenerated only when product inventory or details change, utilizing a database trigger or a save-hook in the admin dashboard.

Below is an architectural example of how a static JSON index is structured and parsed instantaneously in PHP to render a dynamic product catalog page without touching MySQL:

<?php
// Retrieve and decode the flat JSON product index
$catalogFile = __DIR__ . '/data/products_index.json';
if (!file_exists($catalogFile)) {
    // Graceful fallback to database query if index is missing
    $products = fetchProductsFromDatabase();
} else {
    $rawJSON = file_get_contents($catalogFile);
    $products = json_decode($rawJSON, true);
}

// Perform lightning-fast server-side filtering via memory-efficient PHP array filters
$selectedCategory = $_GET['category'] ?? 'all';
$maxPrice = isset($_GET['price_limit']) ? floatval($_GET['price_limit']) : null;

$filteredProducts = array_filter($products, function($product) use ($selectedCategory, $maxPrice) {
    $matchCategory = ($selectedCategory === 'all' || $product['category'] === $selectedCategory);
    $matchPrice = ($maxPrice === null || $product['price'] <= $maxPrice);
    return $matchCategory && $matchPrice;
});

// Render the catalog items
foreach ($filteredProducts as $item) {
    echo '<div class="product-card" data-id="' . htmlspecialchars($item['id']) . '">';
    echo '  <img src="' . htmlspecialchars($item['thumbnail']) . '" alt="' . htmlspecialchars($item['title']) . '" loading="lazy">';
    echo '  <h4>' . htmlspecialchars($item['title']) . '</h4>';
    echo '  <span>₹' . number_format($item['price']) . '</span>';
    echo '</div>';
}
?>

For large-scale catalogs containing thousands of SKUs, transfer this indexing logic entirely to the client side. By loading a compressed static index file (e.g., a 150KB gzip-compressed JSON file containing 2,000 product rows) into browser memory, the client-side JavaScript engine can perform dynamic filtering, fuzzy searching, and sorting in real time as the user types or toggles checkboxes.

This client-side execution renders results in under 5ms, generating zero additional server queries and keeping hosting resource usage exceptionally low, regardless of simultaneous traffic surges.

What are the exact Cache-Control directives and CDN invalidation rules needed to optimize e-commerce speed without serving stale data?

Browser caching is a powerful optimization asset, but a single misconfigured header in an e-commerce ecosystem can cause catastrophic user-experience failures. If dynamic documents—such as the shopping cart, account dashboards, or checkout processes—are cached globally, users may see another customer's sensitive checkout data or be presented with stale inventory counts and outdated pricing. Conversely, failing to cache static files (stylesheets, JavaScript bundles, fonts, and product images) forces the browser to repeatedly download megabytes of identical resources on every single page click.

To manage this complex environment, implement a highly structured Cache-Control strategy. We divide assets into three distinct categories and configure the web server (NGINX or Apache) with precise caching headers for each:

Asset Category Target Resources Optimal Cache-Control Header Key Mechanics
Immutable Static Minified JS, CSS, Web Fonts Cache-Control: public, max-age=31536000, immutable Forces the browser to store assets for 1 year. Any code updates must append a unique hash identifier to the filename to break the cache instantly.
Dynamic Public Product Details, Collection Pages Cache-Control: public, max-age=3600, s-maxage=86400, stale-while-revalidate=60 Edge CDNs cache the document for up to 24 hours. If a request occurs while the cache is stale, the CDN immediately serves the stale version while background-fetching a fresh page.
Dynamic Private Checkout, Shopping Carts, User Portals Cache-Control: no-store, no-cache, must-revalidate, max-age=0 Tells the browser and intermediate proxies never to cache the response, ensuring real-time security and accurate transaction tracking.

Here is an example NGINX configuration block executing these caching policies based on resource types:

# Cache-Control directives for NGINX
location ~* \.(?:css|js|woff2|avif|webp|png|jpg|jpeg)$ {
    expires 1y;
    add_header Cache-Control "public, max-age=31536000, immutable";
    add_header Access-Control-Allow-Origin "*";
    log_not_found off;
    access_log off;
}

location ~* /(?:cart|checkout|my-account|api)/ {
    add_header Cache-Control "no-store, no-cache, must-revalidate, max-age=0";
    add_header Pragma "no-cache";
    expires off;
}

For dynamic but highly static-acting content like product details, rely on CDNs with dynamic tag-based invalidation. By passing custom headers such as Cache-Tag: product-1024 with the HTTP response, the application can issue an API call to the CDN whenever inventory level changes for SKU 1024. The CDN instantly purges only the pages tagged with product-1024, keeping the rest of the site's edge cache intact and maximizing overall cache hit ratios.

How can e-commerce brands achieve sub-300ms Time to First Byte (TTFB) on low-cost shared hosting servers?

While migrating to a dedicated, optimized cloud VPS or containerized platform is the ideal long-term strategy, start-up budgets and business constraints often require working within low-cost, shared hosting environments. Achieving a sub-300ms TTFB on shared servers is highly challenging due to strict CPU limits, limited memory allocations, and bad-neighbor bandwidth issues. However, by fine-tuning PHP configurations, optimizing autoloaders, and implementing aggressive file-system caching, you can squeeze substantial speed gains out of modest infrastructure.

First, maximize PHP execution efficiency. Ensure your hosting dashboard is configured to run the latest stable PHP version (PHP 8.2 or 8.3), which provides significant performance improvements and reduced memory footprints over older versions. Next, inspect the PHP configuration (php.ini or user-defined .user.ini file) and verify that Zend OPcache is fully active and properly configured. OPcache compiles PHP scripts into precompiled bytecode and stores it in server memory, bypassing disk read overhead on subsequent executions.

Apply these optimal OPcache parameters:

; Recommended PHP.ini settings for e-commerce performance
opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.validate_timestamps=1
opcache.revalidate_freq=120

Second, streamline the dynamic execution lifecycle. If your application relies on Composer packages, optimize the class autoloader file. By default, Composer scans the file system dynamically to locate required PHP classes on every single request, which adds substantial disk I/O overhead. Bypass this by generating an optimized class map using the following terminal command during deployment:

composer dump-autoload --optimize --classmap-authoritative

This command converts all dynamic class lookups into a direct, static array map, reducing class-loading latency by up to 50%.

Third, implement disk-based static file generation. Since shared hosts lack sufficient RAM to run in-memory caching solutions like Redis or Memcached, write static HTML pages directly to the server's local storage (such as NVMe drives). When a user requests a product category page, the PHP router checks if a pre-rendered HTML file exists in a cache directory. If present, it streams the static HTML directly to the output buffer in under 10ms, skipping the database connection and templating engine entirely. Combining these techniques will consistently lower your TTFB from several seconds to a responsive 250ms, even on standard, low-cost shared hosting accounts.

We have built lightning-fast solutions for businesses in India. Reach out directly via email to discuss your project.

← All Articles Work With Us →