Optimizare LCP: Preîncărcare imagini, CSS critic și SSR
Il Cea mai mare vopsea plină de conținut (LCP) măsoară timpul care trece de la încărcarea paginii până în momentul în care cel mai mare element este vizibil în fereastra este redată. Google consideră un LCP sub 2,5 secunde „bun”, intre 2,5 si 4 secunde "de imbunatatit", peste 4 secunde "slab". Este unul din trei Principalele elemente vitale web care influențează direct clasamentele în căutare.
Optimizarea LCP necesită înțelegerea cale critică: secvența de operațiuni pe care browserul trebuie să le finalizeze înainte de a putea reda elementul LCP. Orice resurse inutile pe calea critică întârzie LCP. Cele patru strategii impact mai mare — preîncărcare a imaginii, CSS critic inline, optimizare de fonturi și randare pe server — reduceți LCP cu 500 ms-2 secunde în majoritatea cazurilor parte a cazurilor reale.
Ce vei învăța
- Cum descoperă și încarcă browserul elementul LCP: calea critică
- fetchpriority="high": spuneți browserului care imagine este prioritară
- rel="preload": Preîncărcați resursele înainte ca analizatorul să le descopere
- Critical CSS inline: eliminați blocarea randării foilor de stil
- font-display: schimb și opțional pentru a evita FOIT care întârzie LCP
- Redare pe server: Eliminați JS cascadă pentru LCP
- Măsurați impactul real cu WebPageTest și PerformanceObserver
Calea critică pentru LCP
Înainte de optimizare, trebuie să înțelegeți ce blochează LCP-ul în cazul dvs. specific. Browserul urmează acești pași pentru a reda elementul LCP:
// PerformanceObserver: misura il tuo LCP reale
const observer = new PerformanceObserver((list) => {
// L'ultimo entry e il piu aggiornato
const entries = list.getEntries();
const lastEntry = entries[entries.length - 1];
console.log('LCP Element:', lastEntry.element?.tagName);
console.log('LCP Time:', lastEntry.startTime.toFixed(0), 'ms');
console.log('LCP URL:', lastEntry.url); // se e un'immagine
// Breakdown del tempo LCP
if (lastEntry.element) {
const el = lastEntry.element;
const rect = el.getBoundingClientRect();
console.log('Element size:', rect.width * rect.height, 'px^2');
}
});
observer.observe({ type: 'largest-contentful-paint', buffered: true });
// Quali elementi vengono considerati per l'LCP?
// - img elements
// - image elements dentro svg
// - video elements (usa il poster)
// - background-image (solo via CSS)
// - block-level elements con testo (h1, p, div con testo visibile)
// L'elemento piu grande nel viewport al momento del paint
// Come trovare l'elemento LCP in DevTools:
// 1. Apri Chrome DevTools > Performance
// 2. Registra un caricamento
// 3. Cerca "LCP" nella timeline
// 4. Clicca sull'entry: mostra quale elemento
fetchpriority="high": Prioritate explicită a browserului
Browserul folosește un sistem de prioritate intern pentru a decide ce resurse să încarce
înainte. În mod implicit, imaginile au prioritate scăzută sau medie. Atributul
fetchpriority="high" spune browserului că această imagine este LCP
element și trebuie încărcat mai întâi.
Critical CSS Inline: Eliminați blocarea randării
Foile de stil externe blochează redarea până când sunt descărcate și analizate. O rețea lentă sau un server lent poate întârzia LCP doar cu 500 ms-2 secunde pentru un fișier CSS. Solutia: inline CSS-ul critic direct în HTML (CSS-ul necesar pentru a reda conținutul deasupra paginii) e încărcați restul asincron.
// Tool per estrarre automaticamente il Critical CSS
// criticalcss (npm) oppure Vite Critical CSS plugin
// Configurazione Vite con vite-plugin-critical
// vite.config.ts
import { defineConfig } from 'vite';
import critical from 'vite-plugin-critical';
export default defineConfig({
plugins: [
critical({
criticalUrl: 'http://localhost:4173',
criticalBase: 'dist/',
criticalPages: [
{ uri: '/', template: 'index' },
{ uri: '/blog', template: 'blog' },
],
criticalConfig: {
inline: true,
dimensions: [
{ width: 375, height: 812 }, // iPhone
{ width: 1440, height: 900 }, // Desktop
],
},
}),
],
});
Optimizarea fonturilor: Eliminați FOIT pe calea critică
Fonturile web blochează adesea redarea textului elementului LCP. Dacă fontul nu este
încă încărcat, browserul așteaptă (FOIT - Flash of Invisible Text) înainte
redați textul. font-display: swap arătați mai întâi soluția de rezervă
apoi înlocuiește, dar creează un CLS. font-display: optional si alegere
mai bine pentru LCP: utilizați alternativ dacă fontul nu este deja în cache.
/* Font loading ottimizzato per LCP */
/* 1. Preconnect al CDN del font (risparmia ~100ms di DNS lookup) */
/* Nel :
*/
/* 2. Preload del font critico (quello usato dall'LCP element) */
/* Nel :
*/
/* 3. font-display strategy */
@font-face {
font-family: 'Inter';
src: url('/fonts/inter-latin-400.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: optional;
/* optional: usa il font solo se gia in cache.
Al primo caricamento usa system font (zero FOIT, zero CLS).
Dal secondo caricamento usa il web font. */
unicode-range: U+0000-00FF; /* Solo Latin: riduce dimensione */
}
/* Per testi LCP critici: usa fallback con metriche simili */
/* Riduci CLS da font swap usando size-adjust */
@font-face {
font-family: 'Inter-Fallback';
src: local('Arial'); /* Font di sistema come fallback */
ascent-override: 90%;
descent-override: 22%;
line-gap-override: 0%;
size-adjust: 107%;
/* Metriche calibrate per ridurre il layout shift */
}
.lcp-heading {
font-family: 'Inter', 'Inter-Fallback', system-ui;
}
Redare pe server: Eliminați cascada JavaScript
Aplicațiile cu o singură pagină (SPA) cu randare pe partea clientului au o problemă structural pentru LCP: browserul trebuie să descarce HTML, să execute JavaScript, faceți solicitări la date, apoi redați conținutul. Această „cascada” poate adăugați 1-3 secunde la LCP. Server-Side Rendering (SSR) rezolvă acest lucru trimiterea HTML deja redat către client.
// Impatto SSR sull'LCP: misurazioni reali
// SPA senza SSR: waterfall tipico
// 0ms - Browser riceve HTML (vuoto, solo )
// 200ms - Scarica bundle JavaScript (150KB gzipped)
// 400ms - Esegue JavaScript, monta il framework
// 600ms - Prima render: scheletro UI (loading spinner)
// 800ms - API request per i dati
// 1200ms - Risposta API
// 1300ms - Render con dati: LCP event
// LCP = ~1300ms (buono ma potrebbe essere meglio)
// Con SSR: nessun waterfall
// 0ms - Browser invia request
// 150ms - Server renderizza HTML completo con dati
// 350ms - Browser riceve HTML gia renderizzato con l'LCP element visibile
// 350ms - LCP event: l'elemento e gia nella pagina!
// LCP = ~350ms (eccellente)
// Angular Universal (SSR) - esempio di configurazione
// angular.json: abilita SSR
// "server": { "builder": "@angular-devkit/build-angular:application" }
// app.config.server.ts:
import { ApplicationConfig } from '@angular/core';
import { provideServerRendering } from '@angular/platform-server';
export const serverConfig: ApplicationConfig = {
providers: [
provideServerRendering(),
],
};
// Next.js: LCP ottimale con SSR e Image component
// Ogni pagina e server-rendered by default in App Router
// Il componente Image gestisce automaticamente:
// - fetchpriority="high" per above-fold images
// - preload link nel head
// - srcset per responsive images
// - dimensioni esplicite per evitare CLS
Măsurarea impactului: înainte și după
// Misura il tuo LCP prima di ottimizzare
// e dopo per verificare il miglioramento
// web-vitals.js: libreria Google per misurare CWV
import { onLCP, onFID, onCLS } from 'web-vitals';
function sendToAnalytics(metric) {
// Invia a Google Analytics o sistema custom
gtag('event', metric.name, {
value: Math.round(metric.value),
metric_id: metric.id,
metric_value: metric.value,
metric_delta: metric.delta,
metric_rating: metric.rating, // 'good' | 'needs-improvement' | 'poor'
});
}
onLCP(sendToAnalytics);
// WebPageTest: test sintetico con waterfall dettagliato
// https://www.webpagetest.org
// Parametri raccomandati:
// - Location: EC2 Frankfurt (per utenti EU)
// - Connection: 4G (LTE) - 9 Mbps down, 9 Mbps up, 170ms RTT
// - Repeat Views: si (testa cache)
// - Video capture: si (vedi frame-by-frame quando appare l'LCP)
// Risultati da cercare nel waterfall:
// - Quante risorse bloccano il rendering? (Resources in Critical Chain)
// - Quando viene scoperta l'immagine LCP? (piu presto = meglio)
// - Quanto dura il "Render-Blocking" bar? (dovrebb essere < 200ms)
Lista de verificare pentru optimizarea LCP
- Identificați elementul LCP cu DevTools Performance sau WebPageTest
- Adăugați fetchpriority="high" și eliminați loading="lazy" din elementul LCP
- Pentru imagini: utilizați AVIF/WebP, responsive srcset, dimensiuni explicite
- Aliniați CSS-ul critic deasupra paginii, încărcați restul asincron
- Preîncărcați fontul folosit de elementul LCP
- Dacă utilizați SSR: asigurați-vă că elementul LCP este în HTML inițial
- Măsurați LCP P75 cu CrUX sau web-vitals.js în producție
Concluzii
Optimizarea LCP este practic un exercițiu de reducere a timpului pe calea critică: fiecare resursă pe care browserul trebuie să o descarce înainte de a o redare elementul LCP este o oportunitate de îmbunătățire. Cu fetchpriority, CSS critic inline și SSR puteți obține LCP-uri sub 1 secundă pe conexiunile mobile tipice.







