Responsiiviset kuvat 2026: srcset, sizes, AVIF ja fetchpriority käytännössä
Käytännön opas responsiivisiin kuviin vuonna 2026: srcset ja sizes oikein, AVIF/WebP-fallback picture-elementillä, lazy loading ja fetchpriority LCP:n parantamiseksi. Sisältää valmiit koodiesimerkit, kuvaputken ohjeet ja Lighthouse-tarkistuslistan.
Responsiiviset kuvat ovat vuonna 2026 selaimen valittavissa oleva joukko kuvavariantteja, joista se lataa laitteelle ja verkolle parhaiten sopivan version srcset-, sizes- ja <picture>-elementtien avulla. Tuloksena on pienempi tavumäärä, nopeampi LCP ja vähemmän datansiirtoa mobiiliverkoissa. Kun yhdistät modernit formaatit (AVIF, WebP) fallbackeineen, oikein mitoitetut width/height-attribuutit ja fetchpriority="high" LCP-kuvalle, saat käytännössä ilmaista suorituskykyä ilman rakennemuutoksia.
srcset + sizes antaa selaimen valita oikean resoluution: säästö 30–70 % tavuista Retina-näytöillä ja mobiililaitteilla.
<picture>-elementti hoitaa formaattineuvottelun (AVIF, WebP, JPEG) ja art directionin ilman JavaScriptiä.
AVIF tuo 2026 keskimäärin 20–30 % pienemmän tavumäärän WebP:hen verrattuna samalla laadulla, ja se tuetaan nyt kaikissa vihreissä selaimissa.
fetchpriority="high" LCP-kuvalle nostaa Largest Contentful Paintin priorisointia selainten resurssijonossa, usein 100–400 ms parannus.
loading="lazy" kuuluu vain fold-linjan alle jääville kuville. LCP-kuvalle se on antipattern.
width ja height -attribuutit varaavat tilan ja estävät CLS:n, vaikka CSS venyttäisi kuvan responsiiviseksi.
Miksi responsiiviset kuvat vaikuttavat suorituskykyyn
Yhden asiakasprojektin RUM-datassa vuonna 2025 näin, että kuvat vastasivat mediaanikäyttäjän tuotesivulla 68 % latauksen kokonaisbyteistä. Rehellisesti sanottuna luku yllätti myös meidät. Kun replikoin saman sivun responsiivisilla kuvilla ja AVIF-formaatilla, sama sivu latautui 4G-yhteydellä 2,1 sekuntia nopeammin ja LCP putosi 3,3 s → 1,7 s. Ei minkäänlaista koodimuutosta muualla, pelkästään <img>-tagien uudelleenkirjoitus.
Ongelma on yksinkertainen: kun palvelet 2560 px levyistä JPEG-kuvaa 375 px levyiseen puhelinnäyttöön, siirrät noin 6–8-kertaisen määrän pikseleitä käyttämättä niitä. Selain skaalaa ne CSS:llä pienemmäksi ilmaiseksi, mutta verkko on jo ehtinyt kärsiä. Responsiiviset kuvat siirtävät päätöksenteon selaimelle, joka tietää tarkalleen näytön leveyden, laitteen pikselitiheyden (DPR), verkkoyhteyden nopeuden (Save-Data-vihjeen kautta) ja viewportin todellisen koon.
Käytännössä tämä tarkoittaa kolmea rinnakkaista optimointia: oikeat mittasuhteet (srcset/sizes), oikea formaatti (AVIF/WebP/JPEG-neuvottelu picture-elementillä) ja oikea latausprioriteetti (fetchpriority + preload). Kaikki nämä ovat vakioselain-APIa vuonna 2026, etkä tarvitse yhtäkään JavaScript-kirjastoa. Google mittaa tuloksen Largest Contentful Paint -metriikalla, joka on suoraan sidoksissa hakukoneen ranking-signaaleihin.
srcset ja sizes: miten selain valitsee kuvan
srcset luettelee saatavilla olevat kuvavariantit ja niiden pikselileveydet. sizes taas kertoo selaimelle, kuinka leveänä kuva näkyy eri viewport-leveyksillä. Selain yhdistää nämä kaksi tietoa laitteen DPR:ään ja valitsee pienimmän kuvan, joka vielä näyttää terävältä. Näin se toimii käytännössä:
Huomaa neljä asiaa: (1) src-attribuutti on fallback vanhoille selaimille, eikä se laukea, jos srcset ymmärretään; (2) w-yksikkö srcset:issä on todellinen pikselileveys, ei viewport-leveys; (3) sizes-media-queryt luetaan järjestyksessä ylhäältä alas ja ensimmäinen sopiva voittaa; (4) width- ja height-attribuutit varaavat aspektisuhteen ja estävät layoutin hyppimisen, kuten CLS-optimoinnin oppaassa käsitellään tarkemmin.
Yleisin virhe on jättää sizes pois. Silloin selain olettaa sizes="100vw", ja lataa isolla näytöllä usein liian ison kuvan pieneen container-elementtiin. Törmäsin tähän itse viime kuussa, kun tuotelistaus latasi tuplat kuvatavuja pelkän puuttuvan atribuutin takia. Testaa aina Chrome DevToolsin Network-välilehden Resource Size -sarakkeella, että selain valitsee odotetun variantin eri laitteilla.
picture-elementti ja AVIF/WebP-fallback
<picture>-elementti on formaattineuvottelun kotipaikka. Selain käy <source>-elementit läpi järjestyksessä ja käyttää ensimmäistä, jonka MIME-tyyppi se ymmärtää. Sisällä oleva <img> on aina pakollinen. Se on sekä fallback että kaikki DOM-attribuutit (alt, width, height, fetchpriority) periytyvät siitä.
AVIF on vuonna 2026 tuettu kaikissa vihreissä selaimissa: Chrome 85+ (2020), Firefox 93+ (2021), Safari 16.4+ (2023) ja Edge 121+ (2024). Käytännössä yli 96 % globaalista liikenteestä osaa dekoodata sen. AVIF-tiedostot ovat keskimäärin 20–30 % pienempiä kuin WebP samalla PSNR-laadulla ja 50 % pienempiä kuin JPEG. WebP-fallback kannattaa silti pitää siihen asti, että vanhat Safarit (iOS 14, 15) tippuvat käytöstä, ja aina JPEG viimeisenä varmuuden vuoksi.
Art direction: eri rajaus mobiilissa ja desktopissa
<picture> mahdollistaa myös eri kuvasommittelun eri viewporteissa media-attribuutin kautta. Tämä on hyödyllistä esimerkiksi silloin, kun hero-kuvassa halutaan mobiilissa lähikuva ja desktopilla panoraama:
fetchpriority-attribuutti (Chromium 101+, Safari 17.2+, Firefox 132+) kertoo selaimelle, että tietty resurssi pitää siirtää muiden edelle selaimen sisäisessä latausjonossa. LCP-kuvalle asetettu fetchpriority="high" tuottaa Chromen omissa mittauksissa mediaanissa 200–400 ms parannuksen Largest Contentful Paintiin, koska selain ei odota CSS:n tai muiden kuvien lataamista ennen kuin aloittaa LCP-kuvan haun.
<!-- Yläreunan hero-kuva, joka on todennäköisesti LCP-elementti -->
<img src="/img/hero-1200.avif"
srcset="..."
sizes="100vw"
alt="..."
width="1200" height="600"
fetchpriority="high">
<!-- Kuva, jonka selain saa deprioritisoida (esim. skrollattava karuselli) -->
<img src="/img/gallery-2.avif"
alt="..."
width="600" height="400"
loading="lazy"
fetchpriority="low">
Vaihtoehto fetchpriority:lle on <link rel="preload" as="image"> dokumentin <head>ssä, mutta vuonna 2026 fetchpriority on parempi ratkaisu, koska se ei duplikoi kuvan URL:ia ja se toimii responsiivisten kuvien kanssa mutkattomasti. Jos silti käytät preloadia, muista imagesrcset- ja imagesizes-attribuutit:
Katso lisätaustaa LCP-optimoinnin käytännön oppaasta, jossa käsittelen kuvaresurssien priorisointia laajemmin osana kriittistä renderöintipolkua.
Lazy loading oikein: milloin ja miten
loading="lazy" on natiivi selain-attribuutti, joka lykkää kuvan latausta kunnes se on lähellä viewportia. Se toimii kaikissa vihreissä selaimissa ilman IntersectionObserver-koodia. Yleisin virhe on lisätä se kaikkiin sivun kuviin, mukaan lukien LCP-kuva. Silloin selain viivyttää LCP-latausta ja Lighthouse rankaisee sivua "Largest Contentful Paint image was lazily loaded" -varoituksella.
Sääntö on yksinkertainen: fold-linjan yläpuolella olevat kuvat eivät ole koskaan lazy. Fold-linjan alla olevat ovat aina lazy. Käytännössä tämä tarkoittaa yleensä:
Hero-kuva ja above-the-fold -tuotekuvat: fetchpriority="high", EI loading="lazy".
Karusellin ensimmäinen slide: fetchpriority="high", muut loading="lazy".
Tuotelistauksen ensimmäiset 4–6 riviä: eager (default). Loput: loading="lazy".
Footerin logot ja alaviitteen kuvat: aina loading="lazy".
Iframejen kohdalla sama pätee: <iframe loading="lazy"> on erinomainen YouTube-embedien ja Google Maps -upotusten kohdalla, jotka usein tuovat sivuun 500 kt+ ylimääräistä JavaScriptiä. Tämä liittyy laajempaan aiheeseen, jota käsittelin kolmannen osapuolen skriptien optimointi -artikkelissa.
Kuvaputken rakentaminen: sharp, squoosh ja CDN
Responsiiviset kuvat vaativat useita variantteja per kuva. Käsin generointi ei skaalaudu (kokeilin sitä kerran, kesti kaksi iltaa liian kauan). Vuonna 2026 näen kolme yleistä ratkaisua:
1. Build-aikainen prosessointi (sharp / squoosh)
Node-pohjaiset työkalut kuten sharp (libvips-käärö) generoivat variantit rakennusvaiheessa. Tämä sopii projekteihin, joissa kuvia ei lisätä usein ja jotka ovat versionhallinnassa. Esimerkki Node-skripti, joka luo AVIF- ja WebP-variantit 400/800/1200/1600 px leveyksinä:
import sharp from 'sharp';
import { readdir } from 'node:fs/promises';
import path from 'node:path';
const SRC = './src/images';
const OUT = './public/img';
const WIDTHS = [400, 800, 1200, 1600, 2400];
const FORMATS = [
{ ext: 'avif', options: { quality: 55, effort: 6 } },
{ ext: 'webp', options: { quality: 78 } },
{ ext: 'jpg', options: { quality: 82, mozjpeg: true } },
];
for (const file of await readdir(SRC)) {
const base = path.parse(file).name;
const input = sharp(path.join(SRC, file));
const meta = await input.metadata();
for (const w of WIDTHS) {
if (meta.width < w) continue;
for (const { ext, options } of FORMATS) {
await input
.clone()
.resize({ width: w, withoutEnlargement: true })
.toFormat(ext, options)
.toFile(`${OUT}/${base}-${w}.${ext}`);
}
}
}
AVIF-enkoodaus on hidasta (effort: 6 voi kestää useita sekunteja per kuva), joten aja se CI:ssä välimuistilla, älä paikallisesti jokaisella save-hetkellä. GitHub Actionsissa cache voi olla ./public/img-hakemiston hash.
Kuva-CDN palvelee variantteja query-parametrien perusteella: ?w=800&fm=avif&q=55. Sopii, kun kuvien määrä on suuri tai käyttäjät lataavat niitä (esim. UGC). Kalliimpi mutta joustava. Cloudflare Imagesin hinnoittelu vuonna 2026 alkaa noin 5 dollarista/kk 100 000 kuvasta ja skaalautuu lineaarisesti.
3. Framework-integraatiot
Next.js, Astro ja Nuxt tarjoavat sisäänrakennetut <Image>-komponentit, jotka hoitavat prosessoinnin, srcset-generoinnin ja formaattineuvottelun puolestasi. Käytä näitä, jos frameworkkisi tarjoaa ne. DIY-toteutus on harvoin sen arvoinen.
Next.js, Astro ja Nuxt: valmiit ratkaisut
Kolme yleisintä frameworkkia hoitavat responsiiviset kuvat lähes automaattisesti. Näin ne käytännössä toimivat vuonna 2026:
Ominaisuus
Next.js 15 next/image
Astro 5 <Image>
Nuxt 3 <NuxtImg>
Automaattinen srcset
Kyllä
Kyllä
Kyllä
AVIF-tuki oletuksena
Konfiguroitava
Kyllä
Kyllä
Runtime vs. build
Runtime (Vercel) tai build
Build
Molemmat
Lazy loading
Oletuksena päällä
Oletuksena päällä
Oletuksena päällä
fetchpriority
priority-prop
loading="eager"
preload-prop
Placeholder (blur)
Kyllä, LQIP tai base64
Kyllä
Kyllä
Next.js 15 -esimerkki
import Image from 'next/image';
import hero from '@/public/hero.jpg';
export default function Home() {
return (
<Image
src={hero}
alt="Tuotekuva keltaisesta juoksukengästä"
priority // asettaa fetchpriority="high" ja preloadin
sizes="(min-width: 1200px) 1140px, 100vw"
placeholder="blur"
/>
);
}
Next.jsin next.config.js:ssä muista määrittää images.formats: ['image/avif', 'image/webp'], jotta AVIF-neuvottelu on päällä. Katso Next.js Image-komponentin virallinen dokumentaatio täydellisen parametrilistan osalta.
Kun olet toteuttanut yllä olevat, aja Lighthouse tai PageSpeed Insights ja tarkista nämä auditit vihreiksi:
Properly size images: kuvat eivät ole enempää kuin 1 × näytöllä näkyvä koko.
Serve images in next-gen formats: AVIF/WebP käytössä JPEG:n sijaan.
Efficiently encode images: laatuparametrit tarpeeksi matalalla (AVIF 45–60, WebP 75–80).
Defer offscreen images: fold-linjan alla olevat käyttävät loading="lazy".
Preload Largest Contentful Paint image: LCP-kuvalla on fetchpriority="high" tai preload.
Image elements do not have explicit width and height: jokaisella kuvalla on width- ja height-attribuutit.
Käytännön RUM-mittausta varten seuraa Largest Contentful Paint -metriikkaa web-vitals-kirjaston avulla ja segmentoi laitetyypin sekä yhteyden nopeuden mukaan. Näet suoraan, kuinka paljon responsiivisten kuvien käyttöönotto on vaikuttanut oikeilla käyttäjillä, ei vain lab-mittauksissa.
Usein kysytyt kysymykset
Mitä eroa on srcset- ja sizes-attribuuteilla?
srcset luettelee saatavilla olevat kuvavariantit ja niiden todelliset pikselileveydet. sizes kertoo selaimelle, miten leveänä kuva näkyy eri viewport-leveyksillä. Selain käyttää molempia yhdessä valitakseen pienimmän kuvan, joka vielä näyttää terävältä laitteen DPR:llä.
Onko AVIF parempi kuin WebP vuonna 2026?
Kyllä useimmissa tapauksissa: AVIF-tiedostot ovat 20–30 % pienempiä kuin WebP samalla PSNR-laadulla. Enkoodaus on hitaampaa, joten se sopii parhaiten build-aikaiseen prosessointiin tai CDN-välimuistiin. Pidä WebP fallbackina vanhoille Safari-versioille (iOS 14, 15).
Milloin fetchpriority-attribuuttia kannattaa käyttää?
Aseta fetchpriority="high" vain LCP-kuvalle, yleensä yksi hero- tai above-the-fold -kuva per sivu. Käytä fetchpriority="low" lazy-ladatuille kuville, jotka voidaan viivyttää. Useampi high-prioriteettinen resurssi nollaa hyödyn.
Miksi Lighthouse varoittaa LCP-kuvan lazy loadingista?
Koska loading="lazy" viivyttää LCP-kuvan latausta, kunnes selain päättää sen olevan lähellä viewportia. Se lisää LCP-aikaa satoja millisekunteja. Jätä lazy loading pois kaikilta fold-linjan yläpuolelta löytyviltä kuvilta.
Tarvitseeko width- ja height-attribuutit vaikka CSS venyttää kuvaa?
Kyllä, ehdottomasti. Attribuutit määrittävät kuvan aspektisuhteen, jotta selain voi varata tilaa ennen kuvan latautumista. Ilman niitä sivu hyppii kuvan latautuessa ja Cumulative Layout Shift -pisteesi kärsivät. CSS voi silti asettaa width: 100%; height: auto.
Priya is a frontend performance engineer with 11 years of experience untangling slow React and Next.js apps. She spent four years at Shopify on the Storefront Performance team, where she drove a project that cut median LCP across the Online Store theme platform from 3.4s to 1.8s by rewriting the critical render path and killing third-party tag bloat. Before that she shipped checkout perf work at Klarna.
These days she runs an independent practice helping Series B/C ecommerce companies hit a 75th-percentile INP under 200ms before they bother with redesigns. She has a soft spot for Lighthouse CI in pull-request gates and writes most of her perf budgets in YAML. Outside work she's slowly restoring a 1998 Honda CB400 and arguing with her partner about whether RUM beats lab data (it does).
Miten hallita HTTP-välimuistia oikein 2026: Cache-Control-direktiivit, stale-while-revalidate ja CDN-invalidointi Cloudflaressa, Fastlyssa ja Vercelissä. Kaavat, koodit ja mittausohjeet.
Käytännön opas kolmannen osapuolen skriptien optimointiin 2026: mittaus LoAF-API:lla, facade-kuvio raskaille upotuksille, Partytown web workerissa ja bundle-budjetit CI:ssä. Sisältää valmiit koodinäytteet ja verkkokaupasta poimitut mittaustulokset.
Käytännön opas web-vitals-kirjaston käyttöön tuotannossa 2026: INP-, LCP-, CLS-, TTFB- ja FCP-mittaus, attribution-data, sendBeacon-lähetys ja oman p75-arvon vertailu CrUX-dataan.