PrestaShop LCP Optimization | Blue Frog Docs

PrestaShop LCP Optimization

Fix Largest Contentful Paint (LCP) issues on PrestaShop stores through image optimization, caching, server improvements, and PrestaShop-specific techniques.

PrestaShop LCP Optimization

Improve Largest Contentful Paint (LCP) for your PrestaShop store to boost Core Web Vitals scores, improve user experience, and enhance SEO rankings.

Understanding LCP in PrestaShop

What is LCP?

Largest Contentful Paint (LCP) measures how long it takes for the largest visible content element to render on the page. For PrestaShop stores, this is typically:

  • Homepage: Hero banner image, featured product image
  • Category Pages: First product image in grid
  • Product Pages: Main product image
  • Cart/Checkout: Logo or page heading

LCP Scoring Thresholds

Score Range User Experience
Good ≤ 2.5s Fast, excellent
Needs Improvement 2.5s - 4.0s Acceptable
Poor > 4.0s Slow, needs work

Common LCP Elements in PrestaShop

Identify Your LCP Element:

// Run in browser 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({entryTypes: ['largest-contentful-paint']});

Measuring LCP on PrestaShop

Testing Tools

1. Google PageSpeed Insights

  • URL: pagespeed.web.dev
  • Enter your PrestaShop URL
  • Check "Largest Contentful Paint" metric
  • Review "Diagnostics" for specific issues

2. Chrome DevTools

  • Open DevTools (F12)
  • Go to Lighthouse tab
  • Run Performance audit
  • Check LCP in "Metrics" section

3. Search Console Core Web Vitals

  • Real-world data from actual users
  • Shows issues by page group
  • More reliable than lab tests

4. WebPageTest

  • URL: webpagetest.org
  • Advanced waterfall analysis
  • Multiple test locations
  • Connection speed throttling

PrestaShop-Specific LCP Issues

1. Unoptimized Product Images

Problem: Large, uncompressed product images slow LCP dramatically.

PrestaShop Default Behavior:

  • Stores multiple image sizes
  • Original uploads often not optimized
  • No automatic WebP conversion
  • Missing lazy loading attributes

Solution: Optimize Product Images

A. Enable PrestaShop Image Optimization

Back Office > Design > Image Settings

✓ Image format: Use JPEG quality 90 or WebP
✓ Generate high-resolution images: Enable
✓ Maximum file size: 1MB recommended
✓ Regenerate thumbnails after changes

B. Use Image Optimization Module

Popular modules:

  • WebP Converter: Automatic WebP generation
  • Image Optimizer: Batch optimization
  • Lazy Load: Native lazy loading

C. Manual Optimization Before Upload

# Install ImageMagick
sudo apt-get install imagemagick

# Optimize JPG (reduce quality to 85%)
convert original.jpg -quality 85 -strip optimized.jpg

# Convert to WebP
convert original.jpg -quality 80 optimized.webp

# Batch optimize all images in directory
mogrify -strip -quality 85 -path ./optimized *.jpg

D. Serve Images in Modern Formats

Modify theme template to serve WebP with JPG fallback:

{* themes/your-theme/templates/catalog/_partials/miniatures/product.tpl *}
<picture>
  <source srcset="{$product.cover.bySize.home_default.url|replace:'.jpg':'.webp'}" type="image/webp">
  <source srcset="{$product.cover.bySize.home_default.url}" type="image/jpeg">
  <img
    src="{$product.cover.bySize.home_default.url}"
    alt="{$product.cover.legend}"
    loading="lazy"
    width="{$product.cover.bySize.home_default.width}"
    height="{$product.cover.bySize.home_default.height}"
  >
</picture>

2. Slow Server Response Time (TTFB)

Problem: PrestaShop page generation takes too long, delaying LCP.

Measure TTFB:

# Using curl
curl -w "TTFB: %{time_starttransfer}s\n" -o /dev/null -s https://yourstore.com

# Should be < 600ms

Solutions:

A. Upgrade PHP Version

PrestaShop 8.x supports PHP 8.1+ with significant performance boost:

# Check current PHP version
php -v

# Upgrade to PHP 8.1 (Ubuntu/Debian)
sudo apt-get update
sudo apt-get install php8.1-fpm php8.1-mysql php8.1-xml php8.1-gd php8.1-curl php8.1-zip php8.1-intl php8.1-mbstring

# Update PrestaShop PHP-FPM pool
sudo nano /etc/php/8.1/fpm/pool.d/www.conf

# Restart PHP-FPM
sudo systemctl restart php8.1-fpm

B. Enable PrestaShop Caching

Back Office > Advanced Parameters > Performance

Smarty Cache: Yes
Cache: Yes
CCC (Combine, Compress, Cache):
  ✓ CSS Optimization: Enabled
  ✓ JavaScript Optimization: Enabled
  ✓ Move JavaScript to end: Yes

C. Optimize PrestaShop Configuration

// config/defines.inc.php

// Disable debug mode in production
if (!defined('_PS_MODE_DEV_')) {
    define('_PS_MODE_DEV_', false);
}

// Enable class index
if (!defined('_PS_CLASS_INDEX_')) {
    define('_PS_CLASS_INDEX_', true);
}

D. Database Optimization

-- Optimize all PrestaShop tables
OPTIMIZE TABLE ps_product;
OPTIMIZE TABLE ps_category;
OPTIMIZE TABLE ps_image;
OPTIMIZE TABLE ps_product_lang;
OPTIMIZE TABLE ps_category_lang;

-- Add missing indexes (if needed)
ALTER TABLE ps_product ADD INDEX idx_active (active);
ALTER TABLE ps_category ADD INDEX idx_active (active);

E. Implement Full Page Caching

Option 1: Varnish Cache

# Install Varnish
sudo apt-get install varnish

# Configure for PrestaShop
sudo nano /etc/varnish/default.vcl
# Varnish configuration for PrestaShop
vcl 4.0;

backend default {
    .host = "127.0.0.1";
    .port = "8080";
}

sub vcl_recv {
    # Don't cache admin, cart, checkout
    if (req.url ~ "^/admin" ||
        req.url ~ "^/cart" ||
        req.url ~ "^/order" ||
        req.url ~ "^/my-account") {
        return (pass);
    }

    # Don't cache if session cookie exists
    if (req.http.Cookie ~ "PrestaShop") {
        return (pass);
    }

    return (hash);
}

sub vcl_backend_response {
    # Cache for 1 hour
    set beresp.ttl = 1h;
}

Option 2: Redis Cache Module

# Install Redis
sudo apt-get install redis-server php8.1-redis

# Enable in PrestaShop
# Install "Redis" module from Addons

3. Render-Blocking Resources

Problem: CSS and JavaScript files block page rendering.

Identify Blocking Resources:

Google PageSpeed Insights > "Eliminate render-blocking resources"

Solutions:

A. Defer Non-Critical CSS

{* In theme header template: themes/your-theme/templates/_partials/head.tpl *}

{* Critical CSS inline *}
<style>
  {* Inline critical CSS here - above-the-fold styles *}
  body { margin: 0; font-family: Arial, sans-serif; }
  .header { background: #fff; padding: 20px; }
  .product-grid { display: grid; grid-template-columns: repeat(4, 1fr); }
</style>

{* Defer non-critical CSS *}
<link rel="preload" href="{$urls.css_url}" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="{$urls.css_url}"></noscript>

B. Defer JavaScript

Back Office > Advanced Parameters > Performance

Move JavaScript to the end: Yes
Defer JavaScript: Yes (if available in your PrestaShop version)

Manual Implementation:

{* Add defer attribute to scripts *}
<script src="{$urls.js_url}" defer></script>

C. Remove Unused Modules

Disable modules that add unnecessary CSS/JS:

Back Office > Modules > Module Manager

Disable:
- Unused payment modules
- Social media widgets not in use
- Unused marketing modules
- Demo/example modules

4. Large Banner/Hero Images

Problem: Homepage hero banners are often 2-3MB, slowing LCP.

Solutions:

A. Compress Banner Images

Target sizes:

  • Desktop banners: 200-300KB max
  • Mobile banners: 100-150KB max
  • Format: WebP preferred, JPG fallback
# Compress banner image
convert hero-banner.jpg -quality 75 -resize 1920x600 -strip hero-banner-optimized.jpg

# Convert to WebP
cwebp -q 75 hero-banner.jpg -o hero-banner.webp

B. Responsive Images with srcset

{* themes/your-theme/modules/ps_imageslider/views/templates/hook/slider.tpl *}
<picture>
  <source
    media="(max-width: 576px)"
    srcset="{$slide.image_url|replace:'.jpg':'-mobile.webp'}"
    type="image/webp"
  >
  <source
    media="(max-width: 576px)"
    srcset="{$slide.image_url|replace:'.jpg':'-mobile.jpg'}"
    type="image/jpeg"
  >
  <source
    srcset="{$slide.image_url|replace:'.jpg':'.webp'}"
    type="image/webp"
  >
  <img
    src="{$slide.image_url}"
    alt="{$slide.legend}"
    width="1920"
    height="600"
    fetchpriority="high"
  >
</picture>

C. Preload LCP Image

{* In <head> section *}
<link rel="preload" as="image" href="{$hero_image_url}" fetchpriority="high">

5. Third-Party Scripts

Problem: External scripts (analytics, ads, chat) delay LCP.

Solutions:

A. Defer Third-Party Scripts

// Load GTM/analytics after page load
window.addEventListener('load', function() {
  // Load GTM
  (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
  new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
  j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
  'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
  })(window,document,'script','dataLayer','GTM-XXXXXX');
});

B. Self-Host Third-Party Resources

# Download and host Google Fonts locally
# Use google-webfonts-helper: https://gwfh.mranftl.com/fonts

# Download font files to: themes/your-theme/assets/fonts/

# Add to CSS:
@font-face {
  font-family: 'Roboto';
  src: url('../fonts/roboto-v30-latin-regular.woff2') format('woff2');
  font-display: swap;
}

C. Use Facade for Heavy Embeds

Replace YouTube embeds with lite-youtube-embed:

<!-- Instead of iframe -->
<lite-youtube videoid="VIDEO_ID"></lite-youtube>

<script src="https://cdn.jsdelivr.net/npm/lite-youtube-embed@0.2.0/src/lite-yt-embed.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/lite-youtube-embed@0.2.0/src/lite-yt-embed.css">

PrestaShop Caching Strategies

1. Enable All PrestaShop Caches

Back Office > Advanced Parameters > Performance

Cache:
✓ Use cache: Yes
✓ Caching system: File System (or Redis if configured)

Smarty:
✓ Template compilation: Recompile if files have changed
✓ Cache: Yes
✓ Multi-front optimizations: Yes (for multi-server setups)

CCC (Combine, Compress, Cache):
✓ Smart cache for CSS: Yes
✓ Smart cache for JavaScript: Yes

2. Configure PHP OpCache

; /etc/php/8.1/fpm/php.ini

opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.revalidate_freq=2
opcache.fast_shutdown=1
opcache.enable_cli=0

3. Browser Caching via .htaccess

# .htaccess in PrestaShop root

# Enable compression
<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/x-javascript application/json
</IfModule>

# Leverage browser caching
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType image/jpg "access plus 1 year"
    ExpiresByType image/jpeg "access plus 1 year"
    ExpiresByType image/gif "access plus 1 year"
    ExpiresByType image/png "access plus 1 year"
    ExpiresByType image/webp "access plus 1 year"
    ExpiresByType text/css "access plus 1 month"
    ExpiresByType application/javascript "access plus 1 month"
    ExpiresByType application/pdf "access plus 1 month"
    ExpiresByType image/x-icon "access plus 1 year"
</IfModule>

# Add Cache-Control headers
<IfModule mod_headers.c>
    <FilesMatch "\.(jpg|jpeg|png|gif|webp|svg)$">
        Header set Cache-Control "max-age=31536000, public"
    </FilesMatch>
    <FilesMatch "\.(css|js)$">
        Header set Cache-Control "max-age=2592000, public"
    </FilesMatch>
</IfModule>

Content Delivery Network (CDN)

Set Up CDN for PrestaShop

Popular CDN Options:

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

Configure in PrestaShop:

Back Office > Advanced Parameters > Performance > Media Servers

Media server #1: https://cdn1.yourstore.com
Media server #2: https://cdn2.yourstore.com

This will serve static assets from CDN instead of your server.

Cloudflare Setup:

  1. Add your domain to Cloudflare
  2. Update DNS nameservers
  3. Enable:
  4. Set caching rules for /img/ and /themes/ directories

Server-Level Optimizations

1. Upgrade Server Resources

Minimum Recommended:

  • CPU: 4 cores
  • RAM: 8GB
  • Storage: SSD (NVMe preferred)
  • PHP: Version 8.1+
  • MySQL: 8.0+ or MariaDB 10.6+

2. Configure Nginx (Alternative to Apache)

Nginx typically performs better than Apache for PrestaShop:

# /etc/nginx/sites-available/prestashop

server {
    listen 80;
    server_name yourstore.com;
    root /var/www/prestashop;
    index index.php;

    # Gzip compression
    gzip on;
    gzip_types text/css application/javascript image/svg+xml;
    gzip_comp_level 6;

    # Browser caching
    location ~* \.(jpg|jpeg|png|gif|webp|svg|css|js|ico)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    # PHP-FPM
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    # Deny access to sensitive files
    location ~ /\. {
        deny all;
    }
}

3. Database on Separate Server

For high-traffic stores:

  • Host MySQL on dedicated server
  • Use SSD storage for database
  • Configure MySQL query cache
  • Implement master-slave replication

Monitoring and Testing

Continuous Monitoring

Set Up Monitoring:

// Real User Monitoring (RUM) with Web Vitals
<script type="module">
  import {getCLS, getFID, getFCP, getLCP, getTTFB} from 'https://unpkg.com/web-vitals?module';

  function sendToAnalytics({name, delta, id}) {
    // Send to your analytics endpoint
    gtag('event', name, {
      event_category: 'Web Vitals',
      value: Math.round(name === 'CLS' ? delta * 1000 : delta),
      event_label: id,
      non_interaction: true,
    });
  }

  getCLS(sendToAnalytics);
  getFID(sendToAnalytics);
  getFCP(sendToAnalytics);
  getLCP(sendToAnalytics);
  getTTFB(sendToAnalytics);
</script>

Monitor via Tools:

  • Google Search Console (Real user data)
  • Cloudflare Web Analytics
  • New Relic / Datadog (APM)
  • Custom logging to track server response times

Before/After Testing

Document Baseline:

  1. Test with PageSpeed Insights
  2. Record initial LCP score
  3. Implement optimizations
  4. Re-test and compare
  5. Document improvements

Track Progress:

Date LCP (Desktop) LCP (Mobile) Changes Made
2024-01-01 4.2s 5.8s Baseline
2024-01-15 3.1s 4.3s Image optimization
2024-02-01 2.4s 3.2s Varnish cache
2024-02-15 1.9s 2.6s CDN implementation

Quick Wins Checklist

Implement these for immediate LCP improvement:

  • Enable all PrestaShop caching options
  • Compress and convert images to WebP
  • Add width/height attributes to images
  • Preload LCP image with <link rel="preload">
  • Defer non-critical JavaScript
  • Upgrade to PHP 8.1+
  • Enable Gzip/Brotli compression
  • Optimize database tables
  • Remove unused modules
  • Implement browser caching headers

Next Steps

// SYS.FOOTER