Fix LCP Issues on Cs Cart (Loading Speed) | OpsBlu Docs

Fix LCP Issues on Cs Cart (Loading Speed)

Improve CS-Cart LCP by optimizing product image thumbnails, enabling block caching, and reducing Smarty template rendering overhead.

Largest Contentful Paint (LCP) measures how long it takes for the main content of your page to become visible. This guide shows you how to optimize LCP on your CS-Cart ecommerce store.

What is LCP?

LCP marks the point when the largest visible element in the viewport finishes rendering. This is typically:

  • Hero image on homepage
  • Product image on product pages
  • Banner image on category pages
  • Featured content blocks

LCP Scoring

  • Good: 0-2.5 seconds (green)
  • Needs Improvement: 2.5-4.0 seconds (orange)
  • Poor: Over 4.0 seconds (red)

Goal: Achieve LCP under 2.5 seconds for 75% of page views.

Diagnosing LCP Issues

Use PageSpeed Insights

  1. Go to PageSpeed Insights
  2. Enter your CS-Cart store URL
  3. Click Analyze
  4. Check the Largest Contentful Paint metric
  5. Review suggestions under Diagnostics

Use Chrome DevTools

  1. Open your CS-Cart store
  2. Press F12 to open DevTools
  3. Go to Performance tab
  4. Click Record (circle icon)
  5. Reload the page
  6. Stop recording
  7. Find LCP marker in timeline
  8. Identify which element is the LCP element

Identify LCP Element

In Chrome DevTools Console:

new PerformanceObserver((list) => {
  const entries = list.getEntries();
  const lastEntry = entries[entries.length - 1];
  console.log('LCP Element:', lastEntry.element);
  console.log('LCP Time:', lastEntry.renderTime || lastEntry.loadTime);
}).observe({type: 'largest-contentful-paint', buffered: true});

Common LCP Elements in CS-Cart

Homepage

  • Hero banner/slider
  • Featured product blocks
  • Category banners

Product Pages

  • Main product image
  • Product image gallery
  • Featured image

Category Pages

  • Category banner
  • First product images in grid

Optimization Strategies

1. Optimize Images (Most Important)

Images are usually the LCP element in CS-Cart stores.

Compress Images

Use Image Optimization Tools:

Configure CS-Cart Image Settings:

  1. Settings → Thumbnails
  2. Set appropriate dimensions:
    • Product detail page: 800x800px (max)
    • Category listing: 300x300px
    • Homepage banners: Match display size
  3. Enable High-quality images only where needed
  4. Use JPEG for photos, PNG for graphics with transparency

Use Modern Image Formats

WebP Format:

Create .htaccess rule to serve WebP when available:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTP_ACCEPT} image/webp
  RewriteCond %{REQUEST_FILENAME}.webp -f
  RewriteRule ^(.*)\.(jpe?g|png)$ $1.$2.webp [T=image/webp,E=accept:1,L]
</IfModule>

<IfModule mod_headers.c>
  Header append Vary Accept env=REDIRECT_accept
</IfModule>

AddType image/webp .webp

Modify CS-Cart Templates to Support WebP:

{* Product image with WebP fallback *}
<picture>
  <source srcset="{$product.main_pair.detailed.image_path}.webp" type="image/webp">
  <img src="{$product.main_pair.detailed.image_path}"
       alt="{$product.product|escape}"
       width="800"
       height="800">
</picture>

Properly Size Images

CS-Cart Thumbnail Settings:

  1. Settings → Thumbnails
  2. Configure sizes to match display:
    • Don't use 2000px images displayed at 400px
    • Match thumbnail size to actual display size
  3. Enable Generate thumbnails automatically

Responsive Images:

{* Responsive product image *}
<img src="{$product.main_pair.detailed.image_path}"
     srcset="{$product.main_pair.detailed.image_path} 800w,
             {$product.main_pair.icon.image_path} 400w,
             {$product.main_pair.detailed.image_path} 1200w"
     sizes="(max-width: 600px) 400px,
            (max-width: 1200px) 800px,
            1200px"
     alt="{$product.product|escape}">

Preload LCP Image

For Critical Images (Hero/Product):

Add to your theme's head.tpl:

{* Preload hero image on homepage *}
{if $runtime.controller == 'index'}
<link rel="preload"
      as="image"
      href="{$homepage_hero_image}"
      fetchpriority="high">
{/if}

{* Preload product image on product page *}
{if $runtime.controller == 'products' && $product.main_pair.detailed.image_path}
<link rel="preload"
      as="image"
      href="{$product.main_pair.detailed.image_path}"
      fetchpriority="high">
{/if}

Priority Hints:

<img src="hero-image.jpg" fetchpriority="high" alt="Hero">

2. Optimize Server Response Time (TTFB)

Slow server response delays LCP.

Enable CS-Cart Caching

Block Cache:

  1. Settings → Caching
  2. Enable Cache product blocks
  3. Enable Cache category blocks
  4. Set cache lifetime: 3600 seconds (1 hour)

Template Cache:

  1. Administration → Storage
  2. Configure Template cache
  3. Enable for production

Database Query Cache:

In config.local.php:

$config['cache_backend'] = 'redis';
$config['cache_redis_server'] = 'localhost';
$config['cache_redis_global_ttl'] = 3600;

Use Redis/Memcached

Install Redis:

# Ubuntu/Debian
sudo apt-get install redis-server php-redis

# Start Redis
sudo systemctl start redis
sudo systemctl enable redis

Configure CS-Cart to use Redis:

File: config.local.php

$config['cache_backend'] = 'redis';
$config['cache_redis_server'] = 'localhost';
$config['cache_redis_port'] = 6379;

Enable PHP OPcache

php.ini configuration:

opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.validate_timestamps=0
opcache.fast_shutdown=1

Verify OPcache:

<?php
phpinfo();
// Search for "opcache"

Database Optimization

Optimize Tables:

-- Run in phpMyAdmin or MySQL client
OPTIMIZE TABLE cscart_products;
OPTIMIZE TABLE cscart_product_descriptions;
OPTIMIZE TABLE cscart_categories;
OPTIMIZE TABLE cscart_category_descriptions;

Add Indexes for Common Queries:

-- If not already indexed
ALTER TABLE cscart_products ADD INDEX idx_status (status);
ALTER TABLE cscart_products ADD INDEX idx_company_id (company_id);

3. Eliminate Render-Blocking Resources

Defer Non-Critical CSS

Extract Critical CSS:

Use tools like:

Inline Critical CSS:

File: design/themes/[theme]/templates/blocks/head_styles.tpl

<style>
/* Inline critical CSS here */
/* Only styles needed for above-the-fold content */
.header { /* ... */ }
.product-image { /* ... */ }
.hero-banner { /* ... */ }
</style>

{* Load full CSS asynchronously *}
<link rel="preload" href="{$styles_path}" as="style"
<noscript><link rel="stylesheet" href="{$styles_path}"></noscript>

Defer JavaScript

CS-Cart JavaScript Settings:

  1. Design → Themes → [Theme]
  2. Enable Minimize JavaScript files
  3. Enable Move JavaScript to bottom

Manual Defer:

{* Defer non-critical scripts *}
<script src="{$script_path}" defer></script>

{* Async for independent scripts *}
<script src="{$analytics_script}" async></script>

Delay Third-Party Scripts:

// Delay GTM and analytics until page interaction
let delayedScripts = false;

function loadDelayedScripts() {
  if (!delayedScripts) {
    delayedScripts = true;

    // Load GTM
    (function(w,d,s,l,i){/* GTM code */})(window,document,'script','dataLayer','GTM-XXX');

    // Load other third-party scripts
  }
}

// Load on interaction or after delay
window.addEventListener('scroll', loadDelayedScripts, {once: true});
window.addEventListener('click', loadDelayedScripts, {once: true});
window.addEventListener('touchstart', loadDelayedScripts, {once: true});
setTimeout(loadDelayedScripts, 5000); // Fallback after 5s

4. Use a Content Delivery Network (CDN)

Configure CS-Cart CDN:

  1. Settings → CDN settings
  2. Enter CDN URL
  3. Enable Use HTTPS
  4. Configure:
    • Images
    • CSS files
    • JavaScript files

Popular CDN Options:

  • Cloudflare (free tier available)
  • KeyCDN
  • BunnyCDN
  • Amazon CloudFront

Cloudflare Setup:

  1. Sign up at cloudflare.com
  2. Add your domain
  3. Update nameservers
  4. Enable Auto Minify for HTML, CSS, JS
  5. Enable Brotli compression
  6. Configure Page Rules for caching

5. Lazy Load Off-Screen Images

Native Lazy Loading:

Modify CS-Cart product templates:

{* Category product grid *}
<img src="{$product.main_pair.icon.image_path}"
     loading="lazy"
     alt="{$product.product|escape}">

Do NOT lazy load LCP image:

{* First/hero image - eager loading *}
<img src="{$hero_image}"
     loading="eager"
     fetchpriority="high"
     alt="Hero">

Lazy Load Product Blocks:

// Intersection Observer for product blocks
document.addEventListener('DOMContentLoaded', function() {
  const productImages = document.querySelectorAll('.ty-grid-list img[data-src]');

  const imageObserver = new IntersectionObserver((entries, observer) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        const img = entry.target;
        img.src = img.dataset.src;
        img.removeAttribute('data-src');
        observer.unobserve(img);
      }
    });
  });

  productImages.forEach(img => imageObserver.observe(img));
});

6. Optimize Web Fonts

Preload Critical Fonts:

<link rel="preload"
      href="/fonts/your-font.woff2"
      as="font"
      type="font/woff2"
      crossorigin>

Use font-display:

@font-face {
  font-family: 'YourFont';
  src: url('/fonts/your-font.woff2') format('woff2');
  font-display: swap; /* Show fallback font immediately */
}

Subset Fonts:

Only include characters you need:

CS-Cart-Specific Optimizations

Disable Unused Add-ons

  1. Add-ons → Manage add-ons
  2. Disable add-ons you don't use
  3. Each add-on can add CSS/JS overhead

Optimize Product Blocks

Limit Products Per Block:

  1. Edit product block
  2. Set reasonable Limit (6-12 products)
  3. Use pagination instead of loading all products

Disable Auto-update: For static blocks, disable automatic content updates.

Optimize Banners

Use CSS Background Instead of <img>:

{* Instead of large banner image tag *}
<div class="hero-banner"
     style="background-image: url('{$banner_image}');">
  <!-- Content -->
</div>

Compress Banner Images:

  • Reduce file size as much as possible
  • Use WebP format
  • Consider using CSS gradients instead of image backgrounds

Database Query Optimization

Reduce Product Data Queries:

Edit: app/functions/fn.catalog.php

// Only fetch needed fields
$fields = [
    'products.product_id',
    'products.product',
    'products.price',
    'products.main_pair'
];

// Instead of SELECT *

Enable Query Caching:

In config.local.php:

$config['db_cache'] = true;

Advanced Optimizations

HTTP/2 or HTTP/3

Enable HTTP/2 on Apache:

# .htaccess or Apache config
Protocols h2 h2c http/1.1

Enable HTTP/2 on Nginx:

listen 443 ssl http2;

Brotli Compression

Apache:

<IfModule mod_brotli.c>
  AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css text/javascript application/javascript
</IfModule>

Nginx:

brotli on;
brotli_types text/plain text/css application/json application/javascript text/xml application/xml;

Server Upgrade

If server response time is slow:

  • Upgrade hosting plan (more RAM/CPU)
  • Use dedicated server instead of shared
  • Consider managed CS-Cart hosting

Monitoring LCP

Real User Monitoring (RUM)

Using Google Analytics 4:

The Web Vitals are automatically collected in GA4:

  1. Reports → Engagement → Pages and screens
  2. Add secondary dimension: Page path
  3. View LCP metrics per page

Using web-vitals Library:

<script type="module">
  import {getLCP} from 'https://unpkg.com/web-vitals@3/dist/web-vitals.js?module';

  getLCP(console.log);

  // Or send to analytics
  getLCP((metric) => {
    gtag('event', 'web_vitals', {
      event_category: 'Web Vitals',
      event_label: metric.id,
      value: Math.round(metric.value),
      metric_name: 'LCP'
    });
  });
</script>

Regular Testing

Schedule Weekly Tests:

  1. Use PageSpeed Insights
  2. Test key pages:
    • Homepage
    • Top category pages
    • Best-selling product pages
  3. Track improvements over time

Troubleshooting

LCP Still Slow After Optimizations

Check:

  1. Server location - Use CDN if far from users
  2. Hosting performance - Consider upgrade
  3. Third-party scripts - Defer or remove slow scripts
  4. Image optimization - Verify images are actually compressed
  5. Caching - Ensure cache is working

Use WebPageTest:

  1. Go to webpagetest.org
  2. Test with different locations
  3. View Waterfall to see what's blocking
  4. Check Filmstrip to see when LCP element appears

Different LCP Elements

If LCP element varies by page:

  • Optimize each page type separately
  • Focus on most-visited pages first
  • Use consistent hero image sizes

Best Practices Checklist

  • Optimize and compress all images
  • Use WebP format where possible
  • Preload LCP image
  • Enable CS-Cart caching (blocks, templates, database)
  • Use Redis or Memcached
  • Enable PHP OPcache
  • Defer non-critical JavaScript
  • Inline critical CSS
  • Use CDN for static assets
  • Lazy load off-screen images (but not LCP!)
  • Optimize web fonts with font-display: swap
  • Enable compression (Gzip/Brotli)
  • Upgrade to HTTP/2 or HTTP/3
  • Monitor LCP with RUM
  • Regular performance testing

Additional Resources