Cache Smarty vs OPcache vs Cache del Browser in PrestaShop

378 visualizzazioni

Comprendere i tre livelli di cache in PrestaShop

PrestaShop utilizza diversi meccanismi di caching per distribuire le pagine rapidamente. Ogni livello opera a un diverso livello dello stack e comprendere cosa fa ciascuno, quando interviene e quando e necessario svuotarlo e essenziale sia per l'ottimizzazione delle prestazioni che per la risoluzione dei problemi. I tre livelli di cache piu importanti sono la cache dei template Smarty, PHP OPcache e la cache del browser. Lavorano insieme, ma risolvono problemi diversi e richiedono approcci di gestione differenti.

Quando un cliente visita il tuo negozio, la richiesta passa attraverso tutti e tre i livelli in ordine inverso. Il browser controlla prima la sua cache locale. Se ha una copia aggiornata della risorsa, non contatta affatto il server. Se il browser invia una richiesta, PHP la elabora. OPcache garantisce che i file PHP vengano compilati una sola volta e riutilizzati dalla memoria invece di essere analizzati nuovamente a ogni richiesta. Infine, la cache Smarty garantisce che il rendering dei template, che include l'analisi della sintassi dei template e l'esecuzione della logica dei template, avvenga solo quando necessario e non a ogni caricamento di pagina.

I problemi sorgono quando questi livelli servono contenuti obsoleti. Modifichi un file template, ma la pagina appare uguale. Aggiorni un file PHP, ma il vecchio comportamento persiste. Modifichi il CSS, ma il browser mostra ancora i vecchi stili. Ciascuno di questi sintomi punta a un diverso livello di cache, e svuotare quello sbagliato fa perdere tempo senza risolvere il problema.

Cache dei template Smarty - come funziona

Smarty e il motore di template che PrestaShop utilizza per generare l'HTML. Ogni file .tpl nel tuo tema e nei moduli passa attraverso Smarty prima di diventare HTML inviato al browser. Il caching di Smarty opera in due fasi distinte: compilazione e caching dell'output.

Compilazione dei template

Quando Smarty incontra un file .tpl per la prima volta, lo compila in un file PHP. Questo file compilato viene memorizzato nella directory /var/cache/prod/smarty/compile/ (o /var/cache/dev/smarty/compile/ in modalita debug). Il file compilato contiene la logica del template tradotta in PHP puro, che si esegue molto piu velocemente dell'analisi della sintassi Smarty a ogni richiesta.

Smarty verifica se la versione compilata e aggiornata confrontando i timestamp. Se il file sorgente .tpl e piu recente della versione compilata, Smarty lo ricompila automaticamente. Questo e controllato dall'impostazione compile_check. In produzione, puoi disabilitare il controllo di compilazione per le massime prestazioni, il che significa che Smarty assume che i template compilati siano sempre aggiornati e non controlla mai i file sorgente.

Cache dell'output dei template

Oltre alla compilazione, Smarty puo anche memorizzare nella cache l'output renderizzato dei template. Quando la cache dell'output e abilitata, Smarty memorizza l'output HTML finale di un template e lo serve direttamente nelle richieste successive senza eseguire alcuna logica del template. Questo e piu aggressivo della cache di compilazione perche salta non solo la fase di analisi ma anche l'elaborazione dei dati e l'esecuzione della logica all'interno del template.

La cache dell'output in PrestaShop e gestita per hook del modulo. Ogni modulo puo dichiarare se il suo output dell'hook e cacheable, e PrestaShop assegna chiavi di cache basate su fattori come la lingua corrente, il negozio, la valuta e il gruppo clienti. Questo significa che un cliente francese e un cliente inglese ottengono versioni in cache separate.

Impostazioni della cache Smarty in PrestaShop

Configuri la cache Smarty nel back office in Parametri avanzati > Prestazioni. Le impostazioni rilevanti sono:

Compilazione dei template: Questo controlla come Smarty gestisce la compilazione dei template. Le opzioni sono tipicamente "Non ricompilare mai" (piu veloce, usa sempre la versione compilata), "Ricompila se modificato" (controlla i timestamp dei file, buon compromesso) e "Forza compilazione" (ricompila a ogni richiesta, solo per lo sviluppo). In produzione, usa "Ricompila se modificato" a meno che tu non sia sicuro che i tuoi template non cambino mai tra i deployment, nel qual caso "Non ricompilare mai" offre un piccolo guadagno di prestazioni aggiuntivo.

Cache: Questo attiva/disattiva la cache dell'output di Smarty. Quando abilitato, Smarty memorizza l'output HTML renderizzato e lo serve senza rieseguire la logica del template. Questo fornisce vantaggi significativi in termini di prestazioni per i negozi con template complessi o molti hook di moduli. Il tipo di cache puo essere impostato su filesystem (predefinito) o un gestore di cache personalizzato.

Ottimizzazioni multi-front: Questo abilita il caching su piu server front-end. Rilevante solo per configurazioni cluster.

Svuota cache: Le opzioni includono "Non svuotare mai i file di cache", "Svuota cache a ogni modifica" e strategie di svuotamento specifiche. Per la maggior parte dei negozi, lo svuotamento alla modifica e la scelta giusta perche garantisce che gli aggiornamenti siano visibili immediatamente beneficiando comunque della cache tra le modifiche.

Svuotare la cache Smarty

Per svuotare manualmente la cache Smarty, puoi usare il pulsante "Svuota cache" nella pagina Prestazioni del back office. Questo elimina i template compilati e l'output in cache dalla directory /var/cache/. Puoi anche svuotarla eliminando i file direttamente dal server:

Eliminare i template compilati: rimuovere il contenuto di var/cache/prod/smarty/compile/

Eliminare l'output in cache: rimuovere il contenuto di var/cache/prod/smarty/cache/

Devi svuotare la cache Smarty quando modifichi file di template .tpl (se il controllo di compilazione e disabilitato), quando installi o aggiorni un modulo che modifica i template, quando cambi tema o quando modifichi la configurazione relativa ai template. Se modifichi un file .tpl e la modifica non appare nel front-end, la cache di compilazione Smarty e quasi sempre la causa.

PHP OPcache - come funziona

PHP OPcache e una cache di bytecode integrata in PHP. Quando PHP esegue uno script, passa attraverso tre fasi: lexing (scomposizione del codice sorgente in token), parsing (costruzione di un albero sintattico astratto) e compilazione (generazione del bytecode che il motore PHP esegue). OPcache memorizza il bytecode compilato in memoria condivisa in modo che le richieste successive per lo stesso script saltino completamente le fasi di lexing, parsing e compilazione.

Questo e diverso dalla cache Smarty. Smarty memorizza nella cache l'output del rendering dei template (HTML). OPcache memorizza nella cache l'output della compilazione PHP (bytecode). Operano a livelli completamente diversi. Un template Smarty che e stato compilato in un file PHP da Smarty beneficia comunque di OPcache perche quel file PHP compilato stesso viene memorizzato nella cache come bytecode da OPcache.

Configurazione OPcache per PrestaShop

OPcache e configurato nel file php.ini. Le impostazioni piu importanti per PrestaShop sono:

opcache.enable=1 attiva OPcache. Dovrebbe essere sempre attivato in produzione. La differenza di prestazioni e significativa: l'esecuzione PHP diventa da 2 a 5 volte piu veloce con OPcache attivato.

opcache.memory_consumption=256 imposta la quantita di memoria condivisa (in megabyte) disponibile per memorizzare il bytecode compilato. PrestaShop con diversi moduli puo facilmente consumare 128 MB o piu. Se questo valore e troppo basso, OPcache rimuove le voci piu vecchie per fare spazio a quelle nuove, il che vanifica lo scopo. Impostalo a 256 MB o superiore per i negozi con molti moduli. Puoi verificare l'utilizzo con opcache_get_status() per vedere quanta memoria viene effettivamente consumata.

opcache.max_accelerated_files=20000 imposta il numero massimo di file PHP che possono essere memorizzati nella cache. Il core di PrestaShop piu i moduli possono facilmente avere 10.000 o piu file PHP. Il valore effettivo utilizzato da OPcache viene arrotondato per eccesso al numero primo successivo da un insieme predefinito, quindi impostare 20000 risulta in un limite effettivo di 20479. Verifica con opcache_get_status() che non stai raggiungendo questo limite.

opcache.validate_timestamps=1 dice a OPcache di verificare se i file sorgente sono cambiati. Quando abilitato, OPcache controlla l'ora di modifica del file a intervalli definiti da revalidate_freq. In produzione, puoi impostarlo a 0 (disabilitato) per le massime prestazioni, ma devi poi riavviare PHP-FPM o chiamare opcache_reset() ogni volta che distribuisci nuovo codice.

opcache.revalidate_freq=60 definisce con quale frequenza (in secondi) OPcache controlla le modifiche ai file quando validate_timestamps e abilitato. Un valore di 60 significa che OPcache controlla ogni file al massimo una volta al minuto. Valori piu alti significano prestazioni migliori ma ritardi piu lunghi prima che le modifiche al codice abbiano effetto. Per lo sviluppo attivo, impostalo a 0 o 2. Per la produzione, 60 e un buon compromesso.

opcache.interned_strings_buffer=16 alloca memoria per le stringhe internalizzate, che PHP usa per deduplicare stringhe identiche tra diversi script. PrestaShop ne beneficia perche molti moduli condividono gli stessi nomi di classi, nomi di funzioni e letterali di stringa. Impostalo a 16 MB o superiore.

opcache.save_comments=1 deve essere abilitato per PrestaShop. PrestaShop e alcune delle sue dipendenze utilizzano annotazioni PHP DocBlock che vengono lette a runtime. Se lo disabiliti, alcune funzionalita smettono di funzionare.

OPcache e la separazione CLI vs Web

Un dettaglio importante su OPcache e che gli ambienti CLI (riga di comando) e web (PHP-FPM o mod_php) mantengono pool OPcache separati. Svuotare OPcache dalla riga di comando (ad esempio, eseguendo uno script PHP che chiama opcache_reset() via CLI) non svuota l'OPcache web. Per svuotare l'OPcache web, devi riavviare il servizio PHP-FPM o eseguire opcache_reset() tramite una richiesta web.

Questa distinzione e importante nei workflow di deployment. Se distribuisci nuovo codice e svuoti OPcache tramite un comando CLI, il tuo sito web continua a servire il vecchio bytecode finche anche l'OPcache web non viene svuotato. Molti strumenti di deployment gestiscono questo chiamando un endpoint URL speciale che attiva opcache_reset(), o riavviando PHP-FPM come parte del processo di deployment.

Quando svuotare OPcache

Devi svuotare OPcache ogni volta che modifichi, carichi o sostituisci file PHP sul tuo server. Questo include il deployment di una nuova versione di PrestaShop, l'installazione o l'aggiornamento di moduli, la modifica di file PHP direttamente sul server e l'aggiornamento delle dipendenze Composer. Se modifichi un file PHP e il vecchio comportamento persiste nonostante il file sia chiaramente modificato sul disco, OPcache sta servendo il vecchio bytecode. Riavviare PHP-FPM e il modo piu affidabile per svuotarlo.

Cache del browser - come funziona

La cache del browser e l'ultimo livello e opera interamente sul lato client. Quando un browser scarica una risorsa (file CSS, file JavaScript, immagine, font o anche una pagina HTML), puo memorizzare una copia locale e riutilizzarla per le richieste successive. Questo elimina completamente i roundtrip di rete per le risorse in cache, che e il miglioramento delle prestazioni piu grande possibile perche nessuna ottimizzazione lato server puo battere una latenza di rete pari a zero.

La cache del browser e controllata dagli header di risposta HTTP che il tuo server invia insieme a ogni risorsa. Gli header piu importanti sono Cache-Control, Expires, ETag e Last-Modified.

Header Cache-Control

L'header Cache-Control e il meccanismo principale per controllare la cache del browser. Supporta diverse direttive:

max-age=31536000 dice al browser di memorizzare nella cache la risorsa per un massimo di 31.536.000 secondi (un anno). Durante questo periodo, il browser usa la sua copia locale senza contattare il server. Questo e ideale per risorse statiche come CSS, JavaScript e immagini che includono un identificatore di versione nel loro URL (come un hash o una query string).

no-cache non significa "non memorizzare nella cache". Significa che il browser puo memorizzare la risorsa nella cache ma deve validarla con il server prima di usare la copia in cache. Il server risponde con uno stato 304 (Not Modified), che indica che la versione in cache e ancora valida, o con un 200 con il nuovo contenuto.

no-store impedisce effettivamente il caching. Il browser deve scaricare la risorsa nuova ogni volta. Usa questo per contenuti sensibili che non dovrebbero mai essere memorizzati localmente.

public indica che la risposta puo essere memorizzata nella cache da qualsiasi cache, inclusi CDN e server proxy. Usa questo per risorse statiche.

private indica che la risposta e specifica per un singolo utente e non dovrebbe essere memorizzata da cache condivise come i CDN. Usa questo per pagine che contengono contenuti specifici dell'utente, come la pagina dell'account cliente o il carrello.

Header ETag

Un ETag (Entity Tag) e un identificatore univoco per una versione specifica di una risorsa. Il server lo genera (tipicamente un hash del contenuto del file) e lo invia con la risposta. Quando il browser deve validare la sua copia in cache, invia l'ETag al server in un header If-None-Match. Il server confronta gli ETag e restituisce 304 (usa la tua versione in cache) o 200 (ecco la nuova versione).

Gli ETag sono utili quando vuoi il caching del browser con validazione. Il browser fa comunque una richiesta al server, ma se il contenuto non e cambiato, il server restituisce una piccola risposta 304 invece della risorsa completa. Questo risparmia banda garantendo al contempo l'aggiornamento.

Last-Modified e If-Modified-Since

Questi header funzionano in modo simile agli ETag ma usano timestamp invece di hash del contenuto. Il server invia il timestamp Last-Modified con la risorsa, e il browser lo reinvia come If-Modified-Since durante la validazione. Il server controlla se il file e stato modificato da quel momento e restituisce 304 o 200 di conseguenza.

Gli ETag sono generalmente preferiti rispetto a Last-Modified perche sono basati sul contenuto piuttosto che sul tempo, il che evita problemi di sincronizzazione dell'orologio ed e piu preciso. Tuttavia, la maggior parte dei server invia entrambi, e i browser usano quello disponibile.

Configurazione della cache del browser per PrestaShop

Le risorse statiche di PrestaShop (CSS, JavaScript, immagini) dovrebbero essere memorizzate aggressivamente nella cache dai browser. L'approccio standard e configurare il tuo server web per aggiungere gli header Cache-Control appropriati alle risposte dei file statici.

Per Apache, usi i moduli mod_expires e mod_headers nel tuo file .htaccess. Il file .htaccess predefinito di PrestaShop include alcune regole di caching, ma potresti volerle estendere. Una configurazione tipica imposta max-age=31536000 per immagini, font, CSS e file JavaScript, mentre le risposte HTML ricevono no-cache per garantire contenuti aggiornati.

Per Nginx, aggiungi direttive expires nei tuoi blocchi location per i file statici. Ad esempio: location ~* \\.(css|js|jpg|png|gif|ico|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; } memorizza nella cache le risorse statiche per un anno e le contrassegna come immutabili (dicendo al browser di non validarle nemmeno).

Cache busting in PrestaShop

Se imposti tempi di cache lunghi per i file CSS e JavaScript, come fanno i browser a ottenere le versioni aggiornate quando distribuisci modifiche? Qui entra in gioco il cache busting. PrestaShop gestisce questo in modo diverso a seconda che CCC (Combine, Compress, Cache) sia abilitato.

Con CCC abilitato, PrestaShop combina i file CSS e JavaScript in bundle e genera nomi di file che includono un hash del contenuto. Quando il contenuto cambia, il nome del file cambia, e i browser scaricano il nuovo file perche non hanno mai visto quell'URL prima. Questo e l'approccio di cache busting piu affidabile.

Senza CCC, PrestaShop serve i file CSS e JavaScript individuali ai loro URL originali. Alcuni temi e moduli aggiungono una query string di versione (come ?v=1.2.3) a questi URL, che cambia quando il modulo viene aggiornato. I browser trattano l'URL con una query string diversa come una risorsa diversa e la scaricano nuova.

Le immagini sono piu complicate perche i loro URL tipicamente non cambiano a meno che l'immagine stessa non venga sostituita. Se sostituisci un'immagine con una nuova allo stesso URL, i browser che hanno la vecchia versione in cache continueranno a mostrarla fino alla scadenza della cache. In questo caso, devi cambiare il nome del file dell'immagine o svuotare le cache dei browser (cosa che non puoi fare per i tuoi visitatori). La soluzione pratica e usare URL di immagini con versione o attendere che la cache scada naturalmente.

Come i tre livelli interagiscono

Comprendere come questi tre livelli di cache interagiscono e fondamentale per una risoluzione efficace dei problemi. Ecco il ciclo di vita di una richiesta tipica:

Un cliente visita una pagina prodotto. Il browser controlla la sua cache per l'HTML di quella pagina. Poiche l'HTML e tipicamente servito con no-cache, il browser invia una richiesta al server (possibilmente con un header If-Modified-Since o If-None-Match per la validazione).

Il server web riceve la richiesta e la passa a PHP. L'OPcache di PHP-FPM ha il bytecode per index.php di PrestaShop, il dispatcher, i controller e tutti i file dei moduli memorizzati nella cache in memoria condivisa. PHP esegue il bytecode senza ricompilare alcun file sorgente.

Il controller di PrestaShop chiama Smarty per renderizzare il template. Smarty controlla la sua cache per una versione compilata del template. Se la cache dell'output e abilitata e un output in cache valido esiste per questa combinazione di lingua, gruppo clienti e altre chiavi di cache, Smarty restituisce l'HTML in cache direttamente. In caso contrario, Smarty esegue il template compilato (che OPcache ha anche memorizzato nella cache come bytecode poiche i template Smarty compilati sono file PHP), genera l'HTML, lo memorizza nella cache dell'output e lo restituisce.

PHP invia la risposta HTML al browser, insieme agli header HTTP che controllano la cache del browser. Il browser renderizza l'HTML e richiede tutti i file CSS, JavaScript e le immagini referenziati in esso. Per ciascuna di queste risorse, il browser controlla la sua cache locale. Se ha una copia aggiornata (basata sul max-age di Cache-Control), usa la copia locale senza contattare il server. Se la copia in cache necessita di validazione, invia una richiesta condizionale con header ETag o If-Modified-Since.

Risoluzione dei problemi con contenuti obsoleti

Quando le modifiche apportate non appaiono nel front-end, devi identificare quale livello di cache e responsabile. Ecco un approccio sistematico:

Passo 1: Controllare il browser

Apri la pagina in una finestra di navigazione privata o in incognito, o esegui un aggiornamento forzato (Ctrl+Shift+R nella maggior parte dei browser). Se la modifica appare in incognito ma non in una finestra normale, la cache del browser e la causa. Svuota la cache del browser o attendi la sua scadenza.

Per le modifiche CSS e JavaScript in particolare, controlla la scheda rete nei DevTools del browser. Guarda gli header di risposta per il file che hai modificato. Se la risposta mostra un 304 (Not Modified) e il contenuto e vecchio, il file lato server potrebbe non essere effettivamente cambiato (controlla OPcache). Se il browser non sta nemmeno facendo una richiesta per il file (mostra "from disk cache" o "from memory cache"), il max-age di Cache-Control non e scaduto.

Passo 2: Controllare la cache Smarty

Se la modifica non appare nemmeno in incognito, il problema e lato server. Per le modifiche ai template, svuota la cache Smarty dal back office (Parametri avanzati > Prestazioni > Svuota cache) o elimina il contenuto di var/cache/prod/smarty/. Ricarica la pagina e verifica se la modifica appare.

Passo 3: Controllare OPcache

Se svuotare la cache Smarty non aiuta e la modifica riguarda un file PHP (non un template), OPcache sta probabilmente servendo il vecchio bytecode. Riavvia PHP-FPM o chiama opcache_reset() tramite una richiesta web. Su hosting condiviso dove non puoi riavviare PHP-FPM, il pannello di controllo dell'hosting potrebbe avere un'opzione per svuotare OPcache, oppure puoi creare un piccolo file PHP che chiama opcache_reset() e accedervi tramite il browser.

Passo 4: Controllare altre cache

PrestaShop ha meccanismi di cache aggiuntivi oltre a questi tre livelli. La cache di Symfony (in PrestaShop 1.7 e 8.x) memorizza i container dei servizi Symfony compilati, le definizioni delle rotte e altri dati del framework. Svuotala eliminando le directory var/cache/prod/ e var/cache/dev/. Se usi un reverse proxy come Varnish o un CDN come Cloudflare, questi aggiungono un ulteriore livello di cache che deve essere svuotato separatamente.

Configurazione ottimale per la produzione

Per un negozio PrestaShop in produzione, la configurazione ottimale della cache bilancia prestazioni e manutenibilita:

Smarty: Imposta la compilazione dei template su "Ricompila se modificato". Abilita la cache dell'output. Imposta lo svuotamento della cache su "Svuota alla modifica". Questo offre solide prestazioni di cache garantendo al contempo che le modifiche dal back office (come la modifica di pagine CMS o la modifica della configurazione dei moduli) abbiano effetto immediato.

OPcache: Abilita con almeno 256 MB di memoria, 20000 max accelerated files, validate_timestamps abilitato con revalidate_freq di 60 secondi. Questa configurazione significa che le modifiche al codice impiegano fino a 60 secondi per avere effetto, il che e accettabile in produzione. Se distribuisci raramente modifiche al codice e vuoi le massime prestazioni, disabilita validate_timestamps e riavvia PHP-FPM dopo ogni deployment.

Cache del browser: Imposta Cache-Control con valori max-age lunghi (almeno un mese, idealmente un anno) per le risorse statiche (CSS, JavaScript, immagini, font). Usa no-cache per le risposte HTML in modo che le pagine siano sempre validate. Abilita CCC in PrestaShop per ottenere nomi di file con hash del contenuto per i file CSS e JavaScript combinati, il che fornisce cache busting automatico quando le risorse cambiano.

Con questa configurazione, il tuo negozio beneficia di tutti e tre i livelli di cache che lavorano insieme. Le risorse statiche vengono servite dalla cache del browser senza alcun contatto con il server. I file PHP vengono eseguiti dal bytecode in cache senza ricompilazione. E il rendering dei template viene memorizzato nella cache in modo che la logica Smarty venga eseguita solo quando il contenuto cambia. Il risultato e un negozio che si carica rapidamente per i visitatori di ritorno e gestisce il traffico elevato in modo efficiente lato server.

Quando svuotare ogni livello di cache

Per evitare sia contenuti obsoleti che svuotamenti di cache non necessari, segui queste linee guida:

Svuota la cache Smarty quando modifichi file .tpl, cambi posizioni o hook dei moduli, installi o aggiorni moduli che modificano template, o cambi impostazioni relative al tema. Non devi svuotare la cache Smarty quando modifichi file PHP o aggiorni file CSS o JavaScript.

Svuota OPcache quando modifichi file PHP, installi o aggiorni moduli, aggiorni il core di PrestaShop, o esegui Composer per aggiornare le dipendenze. Non devi svuotare OPcache per modifiche ai template o al CSS.

Svuota la cache del browser quando devi vedere le modifiche CSS, JavaScript o delle immagini immediatamente durante lo sviluppo. Per la produzione, affidati al cache busting (URL con versione, nomi di file con hash CCC) invece di chiedere agli utenti di svuotare le loro cache. Non puoi controllare le cache dei browser dei tuoi visitatori, quindi il tuo processo di deployment deve tenerne conto utilizzando tecniche di cache busting appropriate.

Una sequenza completa di svuotamento della cache dopo un deployment importante sarebbe: svuotare le directory di compilazione e cache Smarty, riavviare PHP-FPM per svuotare OPcache, purgare la cache del CDN o reverse proxy se applicabile, e verificare in una finestra di navigazione privata. Per modifiche minori (come la modifica di un singolo template), svuotare solo il livello rilevante e sufficiente e piu veloce.

Questa risposta ti è stata utile?

Hai ancora domande?

Can't find what you're looking for? Send us your question and we'll get back to you quickly.

Loading...
Back to top