WooCommerce da 2.400 prodotti: misurato, stabilizzato, migrato

Negozio di abbigliamento su WordPress e WooCommerce, circa 2.400 prodotti e 22.000 varianti, catalogo caricato ogni giorno dal gestionale aziendale. Hosting condiviso senza SSH né WP-CLI, stack non aggiornato da mesi, prodotti che sparivano dal negozio dopo ogni import, pagine dinamiche servite in 1,8-2,3 secondi. La copia del sito che mi è stata consegnata puntava ancora al database di produzione, con il gateway di pagamento attivo.
Misurare prima di toccare
Replica completa in un ambiente locale isolato, ogni controllo in produzione fatto direttamente sull’origine scavalcando la cache della CDN, suite Playwright automatica (36 test all’inizio, 58 alla fine) eseguita prima e dopo ogni modifica, misure notturne con sitespeed.io su un host dedicato con dati in Grafana. Quando il titolare ha segnalato un crollo del traffico in GA4, la misura ha mostrato ordini stabili: il banner dei consensi tagliava il denominatore, non il sito. Nessun lavoro è stato fatto su un problema che non c’era.
Diagnosticare sulle prove
Metà delle chiamate dell’import (101 su 207) finiva in errore 500. Quattro log incrociati hanno mostrato processi PHP uccisi dall’hosting condiviso, non un difetto del codice, e il fornitore ha confermato che i limiti non si potevano cambiare. Quella prova ha deciso il trasloco. Al checkout, una sonda senza dati personali ha mostrato che l’errore più frequente (35%, caselle di consenso non spuntate) non costava niente perché i clienti si correggevano: le perdite erano altrove, e le priorità sono cambiate prima di spendere.
Correggere alla fonte
Import riscritto in modo che i prodotti ritirati dal gestionale vengano nascosti e conservati, mai cancellati: primo import corretto 414 su 414, zero errori, 3.417 righe orfane rimosse. Ricerca interna estesa con un dizionario italiano e un indice FULLTEXT, senza motori a pagamento: le ricerche senza risultato erano il 22,9% e per le 45 più frequenti ora c’è sempre una risposta. Codici GTIN copiati nel campo nativo di WooCommerce per 8.411 varianti, zero duplicati. Creazione dell’ordine da 97,3 a 34,2 ms togliendo un plugin di numerazione doppio. Il plugin da 1.719 righe del fornitore precedente svuotato in otto passi senza modificarlo, ogni passo confrontato su tutti i 2.490 prodotti e verificato con un ordine reale. Sette plugin rimossi, quattro sostituiti da piccolo codice dedicato, 186 KB di JavaScript in meno sulla home. Errori di contrasto sulla home da 91 a 1, misurati con axe-core invece di installare un overlay di accessibilità.
Migrare con le prove
Sedici script idempotenti, ciascuno provato in un container prima di toccare il server. Il nuovo server isolato fino al passaggio. 1.815.094 record verificati uno per uno su 139 tabelle e 413.586 file. Rollback del DNS provato. Passaggio a negozio chiuso con il vecchio hosting lasciato intatto come rete di sicurezza, prova finale con un ordine reale di basso importo.
Risultato all’origine, media di 10 pagine: TTFB da 954 a 636 ms su desktop (-33%) e da 1.027 a 647 ms su mobile (-37%), LCP da 1.557 a 1.147 ms su desktop (-26%) e da 1.488 a 1.055 ms su mobile (-29%), Lighthouse mobile sulla home da 61 a 75. Import sul nuovo server: 188 record in 2 minuti e 20 secondi, nessun processo interrotto.
Limiti
In questa fase nessun test di carico sull’hosting condiviso: il contratto chiedeva un’autorizzazione scritta che l’incarico non prevedeva. I dati di campo CrUX non facevano parte di questa fase. I numeri sopra sono misure di laboratorio sull’origine, non dati di campo. Pubblicato con il consenso del cliente.
Caso anonimizzato su richiesta del cliente.