Optimizacija slika nije jedan checkbox. Dobar sustav mora znati koja je slika kritična za prvi prikaz, koje slike smiju čekati, koje dimenzije su stvarno potrebne, kako izbjeći layout shift i kako održavati kvalitetu bez nepotrebnog bandwidtha.
preload i učitana s većim prioritetom. Slike niže na stranici najčešće
trebaju loading="lazy". Najgora kombinacija je lazy-loadati LCP sliku i
preloadati slike koje korisnik možda nikad neće vidjeti.
1. Prvo odredite ulogu slike
Ne optimiziraju se sve slike jednako. Hero slika, blog card thumbnail, galerija, logo, dekorativna pozadina i inline ilustracija imaju različite zahtjeve. Najvažnija odluka je nalazi li se slika u prvom prikazu i utječe li na LCP, odnosno Largest Contentful Paint.
Ako je slika glavni vizual hero sekcije, browser je treba dobiti rano. Ako je slika treća kartica u blog listi ili dio galerije duboko niže na stranici, nema smisla gurati je u prvi network val. Ovdje se najčešće događaju performance greške: sve slike dobiju isti tretman.
fetchpriority="high".2. WebP nije magija, ali je dobar default
WebP je odličan format za većinu fotografija i web vizuala jer često daje puno manju datoteku od JPEG-a uz dobru vizualnu kvalitetu. Ali format sam po sebi ne rješava sve. WebP od 4000 piksela širine i dalje je prevelik ako ga prikazujete u kartici od 360 piksela.
Pravi redoslijed je: prvo odrediti potrebne dimenzije, zatim kompresiju, zatim loading strategiju. Ako radite custom CMS, dobro je već u upload procesu generirati nekoliko izvedenica slike umjesto da se original šalje korisniku.
cwebp -q 82 -resize 1024 1024 source.png -o hero.webp
cwebp -q 78 -resize 640 640 source.png -o card.webp
cwebp -q 74 -resize 320 320 source.png -o thumb.webp
3. Dimenzije su važnije nego što izgledaju
Ako CSS prikazuje sliku na 400 piksela širine, nema smisla slati sliku od 2400 piksela osim ako postoji specifičan razlog. Retina ekrani mogu opravdati veću gustoću, ali i dalje treba razmišljati u realnim prikaznim veličinama.
Za blog hero slike često je praktično imati kvadratni asset 1024x1024 jer radi dobro u hero prikazu, Open Graph/Twitter previewu i blog karticama. Ali za male thumbnail prikaze idealno je imati manju izvedenicu. Ako nemate izvedenice, barem pazite da glavna slika bude dovoljno komprimirana.
<img
src="/assets/images/blog-example.webp"
width="1024"
height="1024"
alt="Opis slike"
>
Atributi width i height pomažu browseru rezervirati prostor prije
nego se slika učita. Time se smanjuje rizik od CLS-a, odnosno layout shifta.
4. Responsive images: srcset i sizes
Ako imate više izvedenica slike, srcset i sizes omogućuju browseru
da sam odabere najbolju datoteku za konkretan viewport. To je posebno korisno za card gridove,
galerije i velike hero slike koje na mobitelu ne trebaju istu širinu kao na desktopu.
<img
src="/assets/images/project-1024.webp"
srcset="
/assets/images/project-480.webp 480w,
/assets/images/project-768.webp 768w,
/assets/images/project-1024.webp 1024w
"
sizes="(max-width: 700px) 92vw, 520px"
width="1024"
height="1024"
alt="Web projekt prikazan na uređajima"
>
Najčešća greška je dodati srcset, ali krivo napisati sizes. Browser
tada može izabrati veću sliku nego što treba. sizes treba opisivati stvarnu
prikaznu širinu slike u layoutu, ne fizičku širinu originala.
5. Lazy loading: odličan alat koji se lako krivo koristi
loading="lazy" govori browseru da sliku može učitati kasnije, kada se približi
viewportu. To je idealno za slike niže na stranici. Ali ako lazy-loadate hero sliku, browser
može odgoditi najvažniji vizual i time pogoršati LCP.
<img
src="/assets/images/blog-card.webp"
width="1024"
height="1024"
loading="lazy"
decoding="async"
alt="Kartica blog članka"
>
Kada koristiti lazy loading
- Za slike niže u blog listi, galeriji ili case study sekciji.
- Za slike koje nisu dio prvog viewporta na većini uređaja.
- Za dekorativne i sekundarne vizuale koji nisu kritični za razumijevanje stranice.
- Ne za glavnu hero sliku ako je ona LCP kandidat.
6. Preload i fetchpriority za LCP sliku
Ako znate da je hero slika najveći element u prvom prikazu, možete je najaviti browseru
kroz preload. Time browser ranije sazna za resurs, čak i ako se slika u HTML-u
nalazi nešto kasnije ili je CSS/JS struktura složenija.
<link
rel="preload"
as="image"
href="/assets/images/hero.webp?v=1.0.68"
type="image/webp"
fetchpriority="high"
>
<img
src="/assets/images/hero.webp?v=1.0.68"
width="1024"
height="1024"
fetchpriority="high"
decoding="async"
alt="Glavni vizual stranice"
>
Preload treba koristiti ciljano. Ako preloadate previše slika, više ne pomažete browseru nego ga zbunjujete. Jedna kritična hero slika je dobar kandidat. Deset blog thumbnaila nije.
7. PHP helper za dosljedan image markup
Na custom webu je praktično imati helper koji generira dosljedan markup za slike. Tako lakše kontrolirate alt tekst, width/height, lazy loading i cache-busting verziju. To smanjuje šansu da svaka stranica ručno implementira slike malo drugačije.
<?php
function image_tag(
string $src,
string $alt,
int $width,
int $height,
bool $lazy = true,
): string {
$loading = $lazy ? ' loading="lazy"' : ' fetchpriority="high"';
return sprintf(
'<img src="%s?v=%s" width="%d" height="%d" alt="%s"%s decoding="async">',
htmlspecialchars($src, ENT_QUOTES),
ASSEMBLY,
$width,
$height,
htmlspecialchars($alt, ENT_QUOTES),
$loading
);
}
Helper ne mora biti kompliciran. Njegova vrijednost je u disciplini: svaka slika dobiva dimenzije, alt tekst i ispravan loading mode.
8. Alt tekst nije mjesto za keyword stuffing
Alt tekst ima primarnu accessibility svrhu: opisati sliku korisnicima koji je ne vide ili alatima koji je interpretiraju. SEO vrijednost postoji, ali prirodan opis je bolji od nasilnog ponavljanja ključnih riječi.
9. Cache busting bez razbijanja cachea
Slike treba cacheirati, ali kada se asset stvarno promijeni, browser treba dobiti novu verziju. Jednostavan query parametar s assembly verzijom može biti sasvim dovoljan za custom web. Bitno je da se verzija mijenja pri deployu, a ne nasumično pri svakom requestu.
<?php
const ASSEMBLY = '1.0.68';
const BASE_URL = 'https://example.com';
function asset(string $path): string
{
return rtrim(BASE_URL, '/') . '/' . ltrim($path, '/') . '?v=' . ASSEMBLY;
}
// asset('/assets/images/hero.webp')
Ovo je jednostavno, ali učinkovito. Ako se CSS, JavaScript ili slika promijene, nova assembly verzija prisili browser da preuzme svježi asset. Ako se ništa ne promijeni, cache ostaje koristan.
10. Checklist za produkciju
Prije deploya provjerite
- Je li hero slika optimizirana i nije lazy-loaded ako je LCP kandidat?
- Imaju li slike eksplicitne
widthiheightatribute? - Jesu li slike u WebP formatu ili drugom prikladnom modernom formatu?
- Koristi li se
loading="lazy"samo za nekritične slike? - Postoji li smislen alt tekst bez keyword stuffinga?
- Je li cache-busting verzija ažurirana nakon deploya?
- Je li Lighthouse/LCP provjera napravljena na mobilnom prikazu?
Zaključak: slike su performance feature
Slike nisu samo vizualni materijal. One su performance feature, SEO signal, accessibility element i često najveći razlog za spor prvi prikaz. Dobra optimizacija znači da svaka slika ima jasnu ulogu, pravu dimenziju, pravi format i pravi loading prioritet.
Kod custom webova prednost je što se pravila mogu ugraditi u sam sustav: helperi za slike, automatske WebP izvedenice, kontroliran preload i dosljedan markup. Za povezane teme pogledajte i članke Core Web Vitals i brzina web stranice, tehnički SEO te struktura URL-ova za SEO.