{"id":16,"date":"2026-02-22T09:16:54","date_gmt":"2026-02-22T08:16:54","guid":{"rendered":"https:\/\/seocodice.online\/seoblog\/?p=16"},"modified":"2026-02-22T10:31:05","modified_gmt":"2026-02-22T09:31:05","slug":"wordpress-100-100-pagespeed-il-case-study","status":"publish","type":"post","link":"https:\/\/seocodice.online\/seoblog\/wordpress-100-100-pagespeed-il-case-study\/","title":{"rendered":"WordPress 100\/100 PageSpeed: il Case Study"},"content":{"rendered":"<p>Il 22 febbraio 2026 abbiamo pubblicato il primo articolo su SEOCodice e \u2014 prima ancora di promuoverlo \u2014 abbiamo aperto PageSpeed Insights. Il punteggio era <strong>91\/100 su mobile<\/strong>. Per un blog appena nato, gi\u00e0 un risultato straordinario. Ma non era abbastanza: l&#8217;obiettivo era dimostrare che un WordPress costruito con la metodologia <a title=\"Cos'\u00e8 l'Infrastructure-First SEO\" href=\"https:\/\/seocodice.online\/seoblog\/cos-e-infrastructure-first-seo-e-come-funziona\/\">Infrastructure-First SEO<\/a> pu\u00f2 competere con qualsiasi framework statico. Questo \u00e8 il diario tecnico di come siamo arrivati a <strong>100\/100<\/strong> in meno di 24 ore, senza plugin di cache, senza CDN, senza magie.<\/p>\r\n<p><\/p>\r\n<hr class=\"wp-block-separator\" \/>\r\n<h2>Qual era il punto di partenza e cosa mostrava il report?<\/h2>\r\n<p>Il primo report PageSpeed Insights registrava questi valori su dispositivi mobili:<\/p>\r\n<table>\r\n<thead>\r\n<tr>\r\n<th>Metrica<\/th>\r\n<th>Valore iniziale<\/th>\r\n<th>Soglia Google &#8220;Buono&#8221;<\/th>\r\n<th>Stato<\/th>\r\n<\/tr>\r\n<\/thead>\r\n<tbody>\r\n<tr>\r\n<td>First Contentful Paint<\/td>\r\n<td>0,8 s<\/td>\r\n<td>&lt; 1,8 s<\/td>\r\n<td>\u2705<\/td>\r\n<\/tr>\r\n<tr>\r\n<td>Largest Contentful Paint<\/td>\r\n<td>3,0 s<\/td>\r\n<td>&lt; 2,5 s<\/td>\r\n<td>\ud83d\udd34<\/td>\r\n<\/tr>\r\n<tr>\r\n<td>Total Blocking Time<\/td>\r\n<td>0 ms<\/td>\r\n<td>&lt; 200 ms<\/td>\r\n<td>\u2705<\/td>\r\n<\/tr>\r\n<tr>\r\n<td>Cumulative Layout Shift<\/td>\r\n<td>0,183<\/td>\r\n<td>&lt; 0,1<\/td>\r\n<td>\ud83d\udd34<\/td>\r\n<\/tr>\r\n<tr>\r\n<td>Speed Index<\/td>\r\n<td>0,8 s<\/td>\r\n<td>&lt; 3,4 s<\/td>\r\n<td>\u2705<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><strong>Punteggio Performance<\/strong><\/td>\r\n<td><strong>91<\/strong><\/td>\r\n<td><strong>90\u2013100<\/strong><\/td>\r\n<td>\ud83d\udfe1<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p>Tre problemi principali emergevano dalla sezione Approfondimenti:<\/p>\r\n<ol>\r\n<li><strong>LCP 3,0s<\/strong>: l&#8217;immagine in evidenza non era precaricata<\/li>\r\n<li><strong>Cache browser assente<\/strong>: nessun header di scadenza sulle risorse statiche (349 KiB sprecati ad ogni visita)<\/li>\r\n<li><strong>CSS render-blocking<\/strong>: il foglio di stile bloccava il rendering per ~130ms<\/li>\r\n<\/ol>\r\n<h2>Come funziona la diagnosi Infrastructure-First SEO sulla performance?<\/h2>\r\n<p>Prima di toccare il codice, abbiamo applicato il protocollo diagnostico dell&#8217;<a title=\"Infrastructure-First SEO metodologia\" href=\"https:\/\/seocodice.online\/seoblog\/cos-e-infrastructure-first-seo-e-come-funziona\/\">Infrastructure-First SEO<\/a>: analisi layer per layer, dal pi\u00f9 esterno al pi\u00f9 interno.<\/p>\r\n<ol>\r\n<li><strong>Layer rete<\/strong>: DNS, TTFB, cache<\/li>\r\n<li><strong>Layer rendering<\/strong>: risorse bloccanti, ordine di caricamento<\/li>\r\n<li><strong>Layer visuale<\/strong>: LCP element, CLS sources<\/li>\r\n<li><strong>Layer codice<\/strong>: asset inutili, richieste esterne<\/li>\r\n<\/ol>\r\n<p>Questo approccio \u2014 infrastruttura prima, contenuto dopo \u2014 \u00e8 esattamente ci\u00f2 che separa un&#8217;ottimizzazione sistematica da una serie di tentativi casuali.<\/p>\r\n<h2>Fix 1: Come abbiamo eliminato il problema della cache in 10 righe di Apache?<\/h2>\r\n<p>Il sito non aveva un file <code>.htaccess<\/code> ottimizzato. Ogni visita scaricava le stesse immagini, gli stessi font, lo stesso CSS da zero. La soluzione: un <code>.htaccess<\/code> con tre blocchi precisi. <strong>GZIP\/Deflate<\/strong> per comprimere HTML, CSS, JS, JSON, SVG in transito (~70% di risparmio sui file di testo). <strong>Cache-Control headers<\/strong> via <code>mod_headers<\/code>:<\/p>\r\n<ul>\r\n<li>Immagini e font: <code>max-age=31536000<\/code> (1 anno)<\/li>\r\n<li>CSS e JavaScript: <code>max-age=2592000<\/code> (1 mese)<\/li>\r\n<li>HTML: <code>max-age=3600<\/code> (1 ora, per aggiornamenti rapidi)<\/li>\r\n<\/ul>\r\n<p><strong>WebP automatico<\/strong>: se il browser supporta WebP e il file <code>.webp<\/code> esiste nella cartella uploads, Apache lo serve al posto del JPEG\/PNG originale \u2014 senza PHP, senza JavaScript, direttamente a livello server. Risultato immediato: le 349 KiB segnalate da Google come &#8220;risparmio stimato&#8221; azzerata alla seconda visita.<\/p>\r\n<h2>Fix 2: Cos&#8217;\u00e8 il preload LCP e perch\u00e9 riduce il tempo di 1,9 secondi?<\/h2>\r\n<p>L&#8217;immagine in evidenza \u00e8 quasi sempre l&#8217;elemento LCP (Largest Contentful Paint) di un articolo. Il problema: il browser la scopre solo dopo aver scaricato e analizzato l&#8217;HTML completo. La soluzione \u00e8 il <code>&lt;link rel=\"preload\"&gt;<\/code> con <code>fetchpriority=\"high\"<\/code> inserito nel <code>&lt;head&gt;<\/code> \u2014 prima di qualsiasi altro tag. In questo modo il browser avvia il download dell&#8217;immagine <strong>in parallelo<\/strong> con il parsing dell&#8217;HTML, invece di aspettare. Abbiamo implementato una funzione PHP che:<\/p>\r\n<ol>\r\n<li>Rileva automaticamente se la pagina \u00e8 un articolo singolo<\/li>\r\n<li>Recupera l&#8217;ID dell&#8217;immagine in evidenza<\/li>\r\n<li>Genera il tag preload con <code>imagesrcset<\/code> e <code>imagesizes=\"100vw\"<\/code> per il corretto responsive<\/li>\r\n<\/ol>\r\n<p>Effetto: LCP da 3,0s \u2192 1,1s. Una riduzione del <strong>63%<\/strong>.<\/p>\r\n<h2>Fix 3: Perch\u00e9 il CSS esterno blocca il rendering e come evitarlo?<\/h2>\r\n<p>Per impostazione predefinita, WordPress carica il foglio di stile del tema con un tag <code>&lt;link rel=\"stylesheet\"&gt;<\/code>. Il browser, quando incontra questo tag, si ferma: non pu\u00f2 renderizzare nulla finch\u00e9 il CSS non \u00e8 completamente scaricato e analizzato. Esistono tre approcci per risolverlo:<\/p>\r\n<ol>\r\n<li><strong>Non-blocking con preload + onload<\/strong>: tecnica consolidata, ma il CSS arriva comunque in ritardo<\/li>\r\n<li><strong>Critical CSS inline + async per il resto<\/strong>: ottima performance, alta complessit\u00e0 di manutenzione<\/li>\r\n<li><strong>CSS completamente inline nel <code>&lt;head&gt;<\/code><\/strong>: massima semplicit\u00e0, effetto pagina statica<\/li>\r\n<\/ol>\r\n<p>Abbiamo scelto la terza via.<\/p>\r\n<h2>Cos&#8217;\u00e8 il CSS inline e perch\u00e9 funziona come una pagina statica?<\/h2>\r\n<p>L&#8217;idea \u2014 apparentemente controintuitiva \u2014 \u00e8 stata del founder di SEOCodice: <em>&#8220;non \u00e8 un modo per garantire che il CSS venga iniettato direttamente in ogni articolo come se fosse una pagina statica?&#8221;<\/em> Risposta: s\u00ec, esattamente. Ed \u00e8 quello che fanno Astro, Hugo, Next.js e tutti i generatori statici moderni che vedete con punteggi 98-100. La funzione PHP legge <code>style.css<\/code>, rimuove il commento-header del tema, minifica collassando spazi e newline, e lo inietta come <code>&lt;style id=\"uu-seo-critical\"&gt;<\/code> nel <code>&lt;head&gt;<\/code> con priorit\u00e0 2 \u2014 prima di qualsiasi altra risorsa. Risultato:<\/p>\r\n<ul>\r\n<li>Nessuna richiesta HTTP extra per il CSS<\/li>\r\n<li>Nessun flash di pagina non stilizzata (FOUC)<\/li>\r\n<li>Tutti gli stili applicati dal <strong>frame 1 assoluto<\/strong><\/li>\r\n<\/ul>\r\n<p>Il GZIP del server comprime il CSS inline (~20KB) di circa l&#8217;80%, riducendo l&#8217;impatto a ~4KB extra per risposta HTML \u2014 un compromesso largamente accettabile.<\/p>\r\n<h2>Cos&#8217;\u00e8 il CLS e perch\u00e9 era causato dalla scrollbar di Windows?<\/h2>\r\n<p>Il <a title=\"Cumulative Layout Shift \u2014 web.dev\" href=\"https:\/\/web.dev\/articles\/cls\" target=\"_blank\" rel=\"nofollow noopener\">Cumulative Layout Shift<\/a> misura quanto il contenuto si sposta visivamente durante il caricamento senza interazione dell&#8217;utente. Google considera &#8220;buono&#8221; un CLS inferiore a 0,1. Il nostro 0,183 era attribuito all&#8217;elemento <code>body.wp-singular<\/code> \u2014 l&#8217;intera pagina si spostava. Un&#8217;analisi pi\u00f9 attenta ha rivelato la causa: la scrollbar verticale di Windows. La sequenza del problema:<\/p>\r\n<ol>\r\n<li>La pagina inizia a caricarsi \u2192 nessun contenuto scrollabile \u2192 nessuna scrollbar \u2192 viewport = 1366px<\/li>\r\n<li>Il contenuto carica completamente \u2192 la pagina diventa scrollabile \u2192 la scrollbar appare \u2192 viewport = 1349px (-17px)<\/li>\r\n<li>Tutto il corpo della pagina si sposta di 17px a sinistra \u2192 Google registra CLS = 0,183<\/li>\r\n<\/ol>\r\n<p>La soluzione \u00e8 una singola riga CSS aggiunta all&#8217;elemento <code>html<\/code>:<\/p>\r\n<pre><code>overflow-y: scroll;<\/code><\/pre>\r\n<p>Questo forza la scrollbar a occupare sempre il suo spazio, anche quando non \u00e8 necessaria. Il viewport non cambia mai larghezza \u2192 CLS = 0. Ma con il CSS inline, il beneficio \u00e8 doppio: <code>overflow-y: scroll<\/code> \u00e8 attivo <strong>al primo frame<\/strong>, prima ancora che il contenuto venga dipinto sullo schermo. Non c&#8217;\u00e8 nemmeno una finestra temporale in cui il comportamento pu\u00f2 essere sbagliato.<\/p>\r\n<h2>Quali sono i risultati finali dopo ogni ottimizzazione?<\/h2>\r\n<table>\r\n<thead>\r\n<tr>\r\n<th>Metrica<\/th>\r\n<th>Inizio<\/th>\r\n<th>Dopo .htaccess<\/th>\r\n<th>Dopo LCP preload<\/th>\r\n<th>Dopo CSS inline<\/th>\r\n<\/tr>\r\n<\/thead>\r\n<tbody>\r\n<tr>\r\n<td>Prestazioni<\/td>\r\n<td>91<\/td>\r\n<td>92<\/td>\r\n<td>92<\/td>\r\n<td><strong>100<\/strong><\/td>\r\n<\/tr>\r\n<tr>\r\n<td>LCP<\/td>\r\n<td>3,0 s<\/td>\r\n<td>3,0 s<\/td>\r\n<td>1,4 s<\/td>\r\n<td><strong>1,1 s<\/strong><\/td>\r\n<\/tr>\r\n<tr>\r\n<td>CLS<\/td>\r\n<td>0,183<\/td>\r\n<td>0,183<\/td>\r\n<td>0,183<\/td>\r\n<td><strong>0<\/strong><\/td>\r\n<\/tr>\r\n<tr>\r\n<td>FCP<\/td>\r\n<td>0,8 s<\/td>\r\n<td>0,8 s<\/td>\r\n<td>0,8 s<\/td>\r\n<td><strong>0,8 s<\/strong><\/td>\r\n<\/tr>\r\n<tr>\r\n<td>TBT<\/td>\r\n<td>0 ms<\/td>\r\n<td>0 ms<\/td>\r\n<td>0 ms<\/td>\r\n<td><strong>0 ms<\/strong><\/td>\r\n<\/tr>\r\n<tr>\r\n<td>SEO<\/td>\r\n<td>100<\/td>\r\n<td>100<\/td>\r\n<td>100<\/td>\r\n<td><strong>100<\/strong><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p>Il punteggio finale: <strong>100 \/ 96 \/ 100 \/ 100<\/strong> su dispositivi mobili, con una connessione 4G lenta emulata da Lighthouse 13.0.1 su Moto G Power.<\/p>\r\n<h2>Cosa dimostra questo case study sulla metodologia Infrastructure-First SEO?<\/h2>\r\n<p>Tre cose concrete. <strong>Prima<\/strong>: la performance non \u00e8 un problema di hosting o di CDN. \u00c8 un problema di architettura del codice. Lo stesso hosting, lo stesso server, lo stesso dominio: da 91 a 100 cambiando solo il tema e la sua logica PHP. <strong>Seconda<\/strong>: WordPress pu\u00f2 competere con i framework statici. Non \u00e8 una questione di piattaforma, \u00e8 una questione di come si costruisce su quella piattaforma. CSS inline, LCP preload, zero richieste esterne: sono scelte di progettazione, non di infrastruttura. <strong>Terza<\/strong>: la diagnostica sistematica batte l&#8217;ottimizzazione a tentativi. Ogni fix ha affrontato un problema specifico identificato dal report. Nessun plugin installato &#8220;per sicurezza&#8221;, nessuna ottimizzazione generica. Questo \u00e8 l&#8217;Infrastructure-First SEO applicato alla performance: infrastruttura analizzata, problemi prioritizzati, soluzioni mirate.<\/p>\r\n<h2>FAQ \u2014 Domande frequenti su PageSpeed e WordPress<\/h2>\r\n<h3>\u00c8 possibile raggiungere 100\/100 su PageSpeed con WordPress?<\/h3>\r\n<p>S\u00ec, come dimostra questo case study. \u00c8 necessario eliminare le richieste esterne non necessarie, gestire il CSS in modo non bloccante (o inline), e ottimizzare il percorso critico di rendering. Non servono plugin di cache o CDN se il tema \u00e8 costruito correttamente.<\/p>\r\n<h3>Il CSS inline penalizza il caching del browser?<\/h3>\r\n<p>Il CSS inline non viene cachato separatamente, ma con la compressione GZIP il suo impatto sull&#8217;HTML \u00e8 di circa 4KB per risposta. Per un blog editoriale con pagine che si aggiornano spesso, il compromesso \u00e8 favorevole: nessun FOUC, nessun render-blocking, CLS zero garantito dal frame 1.<\/p>\r\n<h3>Perch\u00e9 il CLS era 0,183 anche con le immagini dimensionate correttamente?<\/h3>\r\n<p>Perch\u00e9 il CLS era causato dalla scrollbar di Windows, non dalle immagini. Anche con attributi <code>width<\/code> e <code>height<\/code> corretti sull&#8217;<code>&lt;img&gt;<\/code>, il viewport si restringeva di 17px quando la scrollbar appariva. La soluzione \u00e8 <code>overflow-y: scroll<\/code> sull&#8217;elemento <code>html<\/code>.<\/p>\r\n<h3>Questi fix funzionano su qualsiasi tema WordPress?<\/h3>\r\n<p>I principi s\u00ec, il codice esatto dipende dall&#8217;architettura del tema. Il file <code>.htaccess<\/code> funziona su qualsiasi installazione Apache. Il preload LCP e il CSS inline richiedono di intervenire su <code>functions.php<\/code> o nei file del tema. Non sono compatibili con builder come Elementor o Divi, che aggiungono decine di richieste CSS e JS indipendenti.<\/p>","protected":false},"excerpt":{"rendered":"<p>Da 91 a 100\/100 su PageSpeed Insights in meno di 24 ore, su un WordPress reale. Ogni fix documentato: CSS inline, LCP preload, CLS zero. Codice incluso<\/p>\n","protected":false},"author":1,"featured_media":18,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[13,8,14,3,12,11,15],"class_list":["post-16","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-case-study","tag-cls","tag-core-web-vitals","tag-css-inline","tag-infrastructure-first-seo","tag-lcp","tag-pagespeed","tag-wordpress-performance"],"_links":{"self":[{"href":"https:\/\/seocodice.online\/seoblog\/wp-json\/wp\/v2\/posts\/16","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/seocodice.online\/seoblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/seocodice.online\/seoblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/seocodice.online\/seoblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/seocodice.online\/seoblog\/wp-json\/wp\/v2\/comments?post=16"}],"version-history":[{"count":5,"href":"https:\/\/seocodice.online\/seoblog\/wp-json\/wp\/v2\/posts\/16\/revisions"}],"predecessor-version":[{"id":22,"href":"https:\/\/seocodice.online\/seoblog\/wp-json\/wp\/v2\/posts\/16\/revisions\/22"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/seocodice.online\/seoblog\/wp-json\/wp\/v2\/media\/18"}],"wp:attachment":[{"href":"https:\/\/seocodice.online\/seoblog\/wp-json\/wp\/v2\/media?parent=16"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/seocodice.online\/seoblog\/wp-json\/wp\/v2\/categories?post=16"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/seocodice.online\/seoblog\/wp-json\/wp\/v2\/tags?post=16"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}