⚡ Rendimiento en PrestaShop

Tecnicas avanzadas para optimizar el rendimiento de tu tienda y modulos: sistema de cache, CCC, optimizacion de queries y gestion de imagenes.

Sistema de cache de PrestaShop

php
<?php
// PrestaShop tiene un sistema de cache en memoria por request
// Cache::retrieve / Cache::store

$cacheKey = 'mymodule_products_' . (int)$id_lang;

// Intentar obtener de cache
$products = Cache::retrieve($cacheKey);

if ($products === false) {
    // No esta en cache — calcular y almacenar
    $products = Db::getInstance()->executeS(
        (new DbQuery())
            ->select('p.id_product, pl.name, p.price')
            ->from('product', 'p')
            ->leftJoin('product_lang', 'pl',
                'p.id_product = pl.id_product AND pl.id_lang = ' . (int)$id_lang
            )
            ->where('p.active = 1')
            ->orderBy('p.date_add DESC')
            ->limit(10)
    );

    Cache::store($cacheKey, $products);
}

// Invalidar cache cuando los datos cambien
Cache::clean('mymodule_products_*');

// ObjectModel usa cache automaticamente:
$product = new Product(1, false, $id_lang);
// La segunda llamada con el mismo ID usa el cache interno
$product2 = new Product(1, false, $id_lang); // Cache hit

CCC — Combinar, Comprimir y Cachear

El sistema CCC de PrestaShop combina y minifica automaticamente los archivos CSS y JS. Para asegurar compatibilidad:

php
<?php
// ✅ Registro correcto de assets compatible con CCC
public function hookActionFrontControllerSetMedia()
{
    $this->context->controller->registerStylesheet(
        'mymodule-main',                               // ID unico
        'modules/' . $this->name . '/views/css/front.css',
        [
            'media'    => 'all',
            'priority' => 150,
            'inline'   => false,   // false = en <link>, true = inline <style>
        ]
    );

    $this->context->controller->registerJavascript(
        'mymodule-main',
        'modules/' . $this->name . '/views/js/front.js',
        [
            'position' => 'bottom',  // 'head' o 'bottom'
            'priority' => 200,
            'attributes' => 'defer', // 'defer', 'async' o ''
        ]
    );
}

// Pasar variables PHP a JS (antes de que CCC combine el JS)
public function hookActionFrontControllerSetMedia()
{
    Media::addJsDef([
        'mymodule' => [
            'ajax_url' => $this->context->link->getModuleLink($this->name, 'ajax'),
            'token'    => Tools::getToken(false),
            'debug'    => (bool) _PS_MODE_DEV_,
        ]
    ]);
}

Optimizacion de queries

php
<?php
// ❌ EVITAR — N+1 queries (una query por cada producto)
foreach ($products as $product) {
    $category = new Category($product['id_category_default']); // N queries!
    echo $category->name[$id_lang];
}

// ✅ CORRECTO — Una sola query con JOIN
$result = Db::getInstance()->executeS(
    (new DbQuery())
        ->select('p.id_product, pl.name as product_name, cl.name as category_name')
        ->from('product', 'p')
        ->leftJoin('product_lang', 'pl',
            'p.id_product = pl.id_product AND pl.id_lang = ' . (int)$id_lang
        )
        ->leftJoin('category_lang', 'cl',
            'p.id_category_default = cl.id_category AND cl.id_lang = ' . (int)$id_lang
        )
        ->where('p.active = 1')
);

// Usar PrestaShopCollection para colecciones con filtros tipados
$collection = new PrestaShopCollection('Product', $id_lang);
$collection->where('active', '=', 1);
$collection->where('price', '>', 10);
$collection->setPageSize(20);
$collection->setPageNumber(1);
$products = $collection->getResults();