WordPress
Sito WordPress lento: un'analisi tecnica oltre i soliti consigli
Perché un sito WordPress è lento davvero: TTFB, autoload, query, hook, page builder e terze parti. Una diagnosi da sviluppatore, e quando la cache non basta più.
Fabio Folgori8 min di lettura

Su «sito WordPress lento» circolano da anni gli stessi consigli: comprimi le immagini, installa una cache, togli qualche plugin. Sono consigli corretti, ma restano in superficie. Quando un sito WordPress è lento in modo strutturale, il motivo sta quasi sempre in come genera le pagine e in quanto lavoro scarica sul browser. Questa è la diagnosi che faccio io, nell'ordine in cui la faccio.
Due problemi diversi: server e browser
La lentezza ha due origini che vanno separate subito.
- Lato server: il tempo che PHP e database impiegano a produrre l'HTML. Si legge nel TTFB delle pagine non in cache e incide sull'LCP.
- Lato browser: quanto JavaScript e CSS la pagina deve scaricare, analizzare ed eseguire. Incide su LCP e soprattutto su INP.
Confonderli porta a soluzioni sbagliate: un hosting più potente non sistema un INP rovinato da un builder, e un ottimizzatore di asset non sistema 800 millisecondi di query.
Lato server: cosa fa WordPress a ogni richiesta
A ogni richiesta non servita dalla cache, WordPress carica il core, il tema e tutti i plugin attivi, anche quelli che su quella pagina non fanno nulla. Poi esegue la catena di hook, legge le opzioni e lancia le query del template. I punti in cui il tempo si accumula sono quasi sempre gli stessi.
Le opzioni in autoload
Le opzioni autoload vengono caricate insieme e possono essere servite da una object cache persistente. Nelle versioni moderne non basta filtrare autoload = yes: occorre considerare i valori riconosciuti dalla versione del core, normalmente anche on, auto-on e auto. Plugin disinstallati male, transient mai scaduti e configurazioni serializzate da centinaia di kilobyte finiscono lì. Ho visto siti con diversi megabyte di autoload: è memoria e tempo pagati su ogni singola pagina. Si misura con una query sulla somma di LENGTH(option_value) e si ripulisce con criterio, non con un plugin «pulisci database» lanciato alla cieca.
Query e meta
WP_Query con meta_query su più chiavi, ordinamenti per campi personalizzati, ricerche con LIKE su post_content: su tabelle wp_postmeta con milioni di righe diventano lente perché quei campi non sono indicizzati in modo utile. Le soluzioni vere sono un modello dati migliore (tassonomie dove servono, tabelle dedicate per dati strutturati) e una object cache persistente come Redis per non ripetere le stesse query.
Hook pesanti e chiamate esterne
Un plugin che su init chiama un'API remota, verifica una licenza o rigenera qualcosa blocca la generazione della pagina finché la risposta non arriva. Query Monitor mostra le richieste HTTP eseguite durante la generazione: quelle evitabili vanno spostate fuori dal percorso critico o servite da cache. Le chiamate necessarie richiedono timeout e gestione dei guasti.
WP-Cron
Per impostazione predefinita WP-Cron viene attivato in relazione alle visite e avvia normalmente una richiesta loopback non bloccante. I job possono comunque consumare risorse condivise e la puntualità dipende da traffico e configurazione. Per lavori che richiedono regolarità valuto un pianificatore di sistema, verificando prima che funzioni e poi disabilitando l’attivazione automatica tramite visite.
Lato browser: dove si perde l'INP
Un possibile responsabile è il page builder, da verificare con una traccia delle prestazioni. Genera DOM profondi e ridondanti, carica librerie per animazioni, slider e widget su ogni pagina, e aggiunge JavaScript che si esegue all'avvio. Il risultato sono long task sul thread principale e interazioni che rispondono in ritardo.
Gli altri responsabili ricorrenti:
- script di terze parti: tag manager con dieci tag, chat, mappe, pixel, banner cookie pesanti. Ognuno compete per il thread principale;
- CSS globale non usato: centinaia di kilobyte di regole per componenti che non esistono nella pagina;
- font: troppe varianti, caricate senza
font-displayadeguato o da server esterni.
«Ottimizzare» qui spesso significa aggiungere un altro plugin che rimanda, unisce o ritarda gli script. Funziona fino a un certo punto, e intanto aggiunge un livello in più che può rompersi a ogni aggiornamento.
Il metodo di diagnosi
- Dati reali prima di tutto: i Core Web Vitals di Search Console (dati CrUX) dicono quali gruppi di pagine hanno problemi e quale metrica. Un singolo test di laboratorio non basta.
- TTFB senza cache, misurato su home, archivio e pagina singola.
- Query Monitor su quelle pagine: numero e durata delle query, componenti più lenti, richieste HTTP, peso dell'autoload.
- Pannello Performance del browser con CPU rallentata: long task, script più costosi, elemento LCP e sua sorgente.
- Inventario dei componenti: per ogni plugin, cosa carica e dove. Spesso metà dei plugin si può togliere o sostituire con poche righe di codice.
Solo dopo questa fase ha senso intervenire.
Quando la cache diventa una toppa
La cache di pagina è indispensabile su WordPress, ma va vista per quello che è: un modo per non eseguire WordPress. Se il sito è veloce solo quando la cache è calda, il problema è ancora lì: lo pagano gli utenti loggati, il carrello, la ricerca, i bot che chiedono pagine non in cache e ogni svuotamento dopo un aggiornamento.
Quando mi accorgo che l'ottimizzazione consiste nell'impilare livelli (cache di pagina, cache degli oggetti, ottimizzatore di asset, CDN, plugin che ritarda gli script) per compensare un tema e un set di plugin che non si possono toccare, è il segnale che il problema è architetturale.
Come risolvo un sito lento
Seguo l'ordine della diagnosi qui sopra, e ogni intervento ha un criterio: se il collo di bottiglia è una query, un autoload gonfio o un plugin che chiama un'API a ogni richiesta, lo correggo nel codice e il sito resta WordPress. Se è un page builder che carica tutto su ogni pagina, spesso conviene riscrivere il tema con blocchi e componenti caricati solo dove servono. Ottimizzare è giusto quando il sito ha davvero bisogno del suo pannello.
Quando la risposta è migrare
Capita spesso, però, che la diagnosi dica un'altra cosa: il sito è un insieme di pagine che cambiano di rado, e tutto il peso di WordPress (PHP, database, plugin, cache impilate su cache) serve a gestire un pannello che nessuno usa. Tutti vogliono il pannello, pochi clienti lo usano davvero. In quel caso non ha senso spendere per rendere veloce una macchina che non dovrebbe girare a ogni visita: genero le pagine una volta sola e le servo da una CDN. Con Nuxt.js (o strumenti simili, come Astro o Next.js in modalità statica) il TTFB può ridursi e il JavaScript può essere alleggerito; LCP e INP vanno comunque misurati e restano cache HTTP e CDN da configurare: la generazione dell’HTML è anticipata, ma invalidazione, freschezza dei contenuti e JavaScript lato client restano da gestire. Come si fa la migrazione senza perdere posizionamento lo racconto in Da WordPress a Nuxt.js, GitHub e Netlify.
Misurare l’autoload senza modificare il database
In una diagnosi su WordPress recente considero i valori autoload riconosciuti dal core, non soltanto yes. Questa query di sola lettura mostra numero di opzioni e dimensione dei valori memorizzati; il prefisso della tabella va adattato all’installazione:
SELECT COUNT(*) AS opzioni,
SUM(OCTET_LENGTH(option_value)) AS byte_valori
FROM wp_options
WHERE autoload IN ('yes', 'on', 'auto-on', 'auto');
La dimensione serializzata non equivale alla memoria occupata in PHP. Il filtro del core può inoltre modificare l’insieme effettivo dei valori autoload, e una object cache persistente può evitare la lettura SQL su ogni richiesta. Individuo quindi le opzioni più grandi e il loro proprietario prima di cambiarle. Non elimino opzioni o transient solo perché grandi.
Riferimento: valori autoload nel core WordPress.
Come la vedo io
Sviluppo con WordPress da molti anni e so renderlo veloce: su progetti scritti a mano, con tema su misura e pochi plugin, i risultati sono ottimi. Ma per un sito nuovo, o per uno lento da rifare, faccio prima un'altra domanda: serve davvero un pannello dinamico? Se sì, ottimizzo WordPress. Se no, la soluzione più veloce è non eseguire niente a ogni richiesta. Preferisco dirlo con onestà: spesso si spende meno a ripensare il sito che a inseguire i punteggi.
Perché affidarlo a me
Dal 1999 ho consegnato più di 300 progetti, con più di 30 agenzie, da Roma e da remoto. Faccio la diagnosi con gli strumenti di uno sviluppatore, non con un punteggio, e ti dico se conviene ottimizzare o cambiare strada.
Se il tuo sito WordPress è lento, scrivimi: in una chiacchierata di circa 20 minuti guardiamo i dati reali e capiamo dove si perde il tempo. Il servizio è in Velocità e SEO.
Domande frequenti
La cache di pagina nasconde il tempo di generazione per i visitatori anonimi, ma non lo elimina: utenti loggati, carrello, ricerca e pagine non in cache restano lenti. E non tocca il lavoro del browser, che è dove si perde l'INP.
Solo se il collo di bottiglia è il server. Si verifica misurando il TTFB su pagine non in cache e profilando le richieste: se il PHP impiega 1,5 secondi per colpa di query e hook, un server più potente porta un miglioramento parziale.
Query Monitor per query, hook e richieste HTTP lato server; i dati CrUX di Search Console per l'esperienza reale; il pannello Performance del browser per i long task. Su progetti importanti, un profiler come Xdebug o un APM.
Quando ogni miglioramento richiede un plugin in più, quando il tema o il builder sono il collo di bottiglia e non si possono togliere, o quando il sito non ha bisogno di contenuti dinamici. Allora una generazione statica è spesso più economica di un'ottimizzazione infinita.
- #wordpress
- #velocità del sito
- #performance
- #core web vitals
- #database

