Core Web Vitals javítása kép- és betűtípus optimalizálással.

Core Web Vitals javítása: Amikor a képek és a betűk lassítják le az oldalad

Üdv újra a frontend teljesítmény szürke övezetében! Ma nem a JavaScript bundle-okról vagy a komplex React re-renderekről fogok mesélni, hanem két olyan elemról, amelyek gyakran átnézve kerülnek a figyelmen kívül: a képekről és a betűtípusokról. Ezek a látszólag ártalmatlan asset-ek brutális módon ronthatják a Core Web Vitals pontszámaidat, különösen az LCP (Largest Contentful Paint) és a CLS (Cumulative Layout Shift) mutatókat. Nézzük meg, hogyan lehet ezeket a csendes sebességgyilkosokat szelíden kordában tartani.

Miért pont a képek és betűtípusok?

A Core Web Vitals egy olyan metrika-hármas, amely a felhasználói élmény valós minőségét próbálja megragadni. Az LCP azt méri, mennyi idő alad tölt be a legnagyobb tartalmi elem (ami gyakran egy kép vagy egy nagy betűstílusú címsor). A CLS pedig a váratlan layout-ugrások összegét számolja – amikor betöltődik egy később érkező betűtípus, és az egész oldal „megremeg”. Ha ezek a számok rosszak, a Google böngésző is lepontoz, és a felhasználók is elmennek.

A trükk az, hogy míg a JavaScriptet könnyű okolni, addig a több megabájtos, nem optimalizált képek és a helytelenül betöltött webfontok csendesen teszik tönkre a teljesítményt.

1. Képek optimalizálása: Több, mint csak egy width attribútum

A legnagyobb hiba, amit láthatok, amikor egy képfeltöltő scriptet írok PHP-ban, hogy a felhasználó feltölt egy 4000×3000 pixeles képet, és azt közvetlenül kiszolgálom a frontendre, csak CSS-ben lekicsinyítve. A böngésző akkor is letölti a teljes fájlméretet!

// Példa egy egyszerű képfeldolgozó PHP snippetre
// (Felületes ellenőrzéseket kihagytam a rövidség kedvéért)

function optimizeUploadedImage($uploadedPath, $maxWidth = 1200) {
    $info = getimagesize($uploadedPath);
    $mime = $info['mime'];

    switch ($mime) {
        case 'image/jpeg':
            $sourceImage = imagecreatefromjpeg($uploadedPath);
            break;
        case 'image/png':
            $sourceImage = imagecreatefrompng($uploadedPath);
            break;
        // ... más formátumok
        default:
            return false;
    }

    $origWidth = imagesx($sourceImage);
    $origHeight = imagesy($sourceImage);

    // Számold ki az új magasságot az arányok megtartásával
    $newWidth = min($origWidth, $maxWidth);
    $newHeight = intval(($origHeight / $origWidth) * $newWidth);

    $resizedImage = imagescale($sourceImage, $newWidth, $newHeight);

    // Mentés progresszív JPEG-ként, ami gyorsabban megjelenik
    imagejpeg($resizedImage, $uploadedPath, 75); // 75% minőség gyakran elég

    imagedestroy($sourceImage);
    imagedestroy($resizedImage);

    return true;
}

A frontenden viszont az a titok, hogy mindig adj meg width és height attribútumokat, még akkor is, ha CSS-ben átméretezed. Ez megakadályozza a layout shift-et (CLS).

<!-- Rossz -->
<img src="hero.jpg" alt="Hero" class="responsive-img">

<!-- Jó -->
<img src="hero.jpg" alt="Hero" width="1200" height="800" class="responsive-img" loading="lazy">
/* SCSS-ben könnyen kezelheted a kép arányait */
.responsive-img {
    max-width: 100%;
    height: auto; /* A height attribútummal együtt ez megtartja az arányt és megelőzi a CLS-t */
    display: block;
}

Ne felejtsd el a modern képformátumokat (WebP, AVIF) és a srcset attribútumot a reszponzív képekhez! Egy kis jQuery-vel még a lazy loading-t is felügyelheted komplexebb esetekben:

// Egyszerű lazy load megvalósítás képcserekkel (pl. WebP támogatás esetén)
$(document).ready(function() {
    $('img[data-src]').each(function() {
        var $img = $(this);
        // Csak akkor cseréljük, ha a kép a viewport közelében van
        if (elementInViewport($img)) {
            $img.attr('src', $img.data('src')).removeAttr('data-src');
        }
    });
});

2. Betűtípusok: A láthatatlan sebességfogyasztók

Egyetlen, gyakran használt font-weight változat letöltése akár több száz kilobájt is lehet. A gyakori buktató a teljes betűcsalad (pl. Light, Regular, Medium, Bold, Italic) betöltése, amikor csak két súlyt használsz valójában.

/* Rossz - 4 külön betűtípusfájl, mind más súllyal */
@font-face {
    font-family: 'MyFont';
    src: url('myfont-light.woff2') format('woff2');
    font-weight: 300;
}
@font-face {
    font-family: 'MyFont';
    src: url('myfont-regular.woff2') format('woff2');
    font-weight: 400;
}
/* ... és így tovább */

/* Jó - Csak azokat a súlyokat töltsd be, amelyekre tényleg szükséged van */
@font-face {
    font-family: 'MyFont';
    src: url('myfont-regular.woff2') format('woff2');
    font-weight: 400;
    font-display: swap; /* KULCS! */
}
@font-face {
    font-family: 'MyFont';
    src: url('myfont-bold.woff2') format('woff2');
    font-weight: 700;
    font-display: swap;
}

A font-display: swap; a legfontosabb fegyvered. Ez megmondja a böngészőnek, hogy azonnal jelenítsen meg egy system fontot (az ún. FOIT – Flash of Invisible Text elkerülésére), majd cserélje ki, amikor a webfont betöltődött. Hirtelen megszűnik a rejtélyes „ugrálás” a betűstílus váltáskor.

Egy Bootstrap projektben gyakran látom, hogy a fejlesztők a teljes Google Fonts CSS-t behúzzák. Sokkal jobb, ha helyileg hosztolod a kiválasztott .woff2 fájlokat, és a fenti @font-face szabályokkal vezéreled őket. Megspórolod a külső hálózati kérést.

Gyakori csapdák, amiket kerülj

1. Túl sok egyedi betűtípus-súly/stílus: Használd a system fontokat a testreszabottak helyett, ahol lehet. A font-display: optional; is egy erős lépés, ami csak akkor cserél, ha a betűtípus gyorsan elérhető. 2. Képek formátuma és mérete nincs kontrollálva a backend oldalon: Mindig dolgozd fel a felhasználói feltöltéseket, ne hagyd, hogy a frontend dolgozza meg a 10 megabájtos PNG-t. 3. Hiányzó width/height attribútumok: Ez a legegyszerűbb módja a CLS csökkentésének a képeknél. Egy Bootstrap img-fluid osztállyal kombinálva is működik. 4. A betűtípusok blokkolják a megjelenítést: Ha nem használod a swap-et, a szöveg láthatatlan marad addig, amíg a betűtípus betöltődik – katasztrofális LCP-re.

Összegzés

A Core Web Vitals javítása nem csak a legújabb JavaScript framework-ök trükkjeiről szól. Gyakran sokkal nagyobb nyereséget érhetsz el a webperf alapon való gondolkodással: a képek és betűtípusok tudatos kezelésével. A backend oldalon (PHP) gondoskodj a megfelelő méretű és formátumú képek kiszolgálásáról. A frontenden (CSS/SCSS, JavaScript, jQuery) pedig tartsd szem előtt a layout stabilitást (width/height, font-display: swap) és a lazy loading lehetőségeit.

Egy optimalizált kép és egy jól kezelt webfont nem csak a metrikákon javít, hanem érezhetően gyorsabbá és stabilabbá teszi az oldalad a felhasználó számára. És végül is, erről szól az egész: a felhasználói élményről, nem csak a számokról.