Web & performance
Hvis I søger efter billedoptimering hjemmeside, eller efter next/image, står I typisk ét sted: PageSpeed siger at LCP er et billede, og I er usikre på om I har et setup eller en mappe. Nogen kører et plugin én gang og kalder det færdigt. Nogen har lagt heroen ind som PNG i `/public` og sat `priority` på tre billeder. Nogen uploader fra CMS i originalstørrelse og lader browseren skære. Nogen har next/image uden `sizes`, så den mobile hero henter det samme som desktop.
Hastigheds-indlægget handler om hvorfor Core Web Vitals rangerer, og hvordan I måler. Den her handler om billedet som det element, der oftest *er* LCP på et marketing-site: format, bredde, CDN, og det sted i CMS'et, der nægter at slå en originalfil på flere megabyte igennem. En ærlig pipeline er ikke 'vi bruger WebP'. Det er en sætning om hvilket billede der må være hero, i hvilket format, ved hvilken bredde, og hvem der siger nej. Uden den sætning har I et plugin. I har ikke en pipeline.
TL;DR
De vigtigste pointer
- Heroen er typisk LCP på et marketing-site. Pipeline'en starter dér — ikke i et galleri, I kigger på til sidst.
- Format, bredde og `sizes` slår 'vi har trykket komprimér'. next/image uden `sizes` er stadig det forkerte download.
- Én priority-hero. Tre `priority`-billeder er tre LCP-kandidater, I har bedt om at kæmpe.
- CMS'et er en del af pipeline'en. Et upload uden loft er hvordan PNG'en vinder over jeres Next-config.
- CLS er et layout-job: width/height eller aspect-ratio, før billedet lander — ikke et fade, I kalder polish.
- WordPress, Next og Shopify har samme job. Forskellen er hvor I sætter nej'et, ikke om billeder tæller.
Hvorfor det her overhovedet er vigtigt
Et marketing-site sælger med billeder, og det er præcis derfor de ødelægger det. Heroen er det første, Google og brugeren venter på. Googles LCP-tærskel er kendt og offentlig — det er ikke et tal, vi har opfundet — og på et site som jeres er LCP-elementet oftest et billede, ikke en tekstblok. Hvis heroen er et originalt PNG, en autoplay-video I kalder baggrund, eller tre slider-frames der alle hentes, har I valgt at starte samtalen med et download. Pipeline'en er at nægte det download, før det er 'for sent at rette i PageSpeed'.
Teams arver ordet billedoptimering fra et plugin. I WordPress er det 'smid EWWW på'. I et design-handoff er det 'eksportér til 2x'. I Next.js er det 'vi har Image-komponenten'. Ingen af delene er pipeline'en. Pipeline'en er at et billede ikke kan nå browseren, uden at have et format, en bredde, en CDN-sti og et layout-slot. Plugin'et kører, når nogen husker det. Handoff'et lyver, når CMS'et tillader det næste upload. Komponenten lyver, når `sizes` er 100vw på en 200px-thumb.
Det er også et redaktionelt ejerskabs-spørgsmål. Hvis marketing kan uploade en hero uden loft, har I givet dem en knap, der slår LCP. Det er ikke deres fejl. Det er at I kaldte Next-configen for pipeline og lod CMS'et være et drev. Designsystem-indlægget er tokens og komponenter. Her er pligten enklere: ét sted, der siger nej til filen, før den er live. Uden nej'et er 'vi har WebP' en sætning om sidste uge.
Vi skriver det, fordi 'kan I ikke bare komprimere billederne' er blevet et køb, I tager før I har en sætning om hero, `sizes` og upload-loft. Et ærligt setup er kedeligt: ét prioriteret LCP-billede, moderne formater, rigtige widths, dimensioner i layoutet, og et CMS der ikke kan slå det over. Uden den sætning har I en mappe. I har ikke billedoptimering.
Hvad en billedpipeline faktisk er — og hvad next/image ikke er alene
En billedpipeline er vejen fra fil til skærm, med nej-punkter: upload-loft i CMS, et afledt sæt widths, et moderne format (AVIF/WebP med fornuftig fallback), en CDN der kan det, og markup der fortæller browseren hvilken fil den må hente (`srcset` + `sizes`) og hvor meget plads den fylder, før den er der. Den er et produktvalg, fordi den siger at heroen må vente på formatet, ikke at formatet må vente på heroen. De fleste marketing-sites skal have præcis det. De skal ikke have et nyt DAM, før de har et loft.
next/image er et værktøj i den vej, ikke vejen. Den kan aflede widths, sætte lazy, hoste på Vercel eller en loader I peger på. Den kan også hente det forkerte, hvis `sizes` er løgn, hvis I har slået optimering fra for at 'få det til at virke', eller hvis kilden allerede er et 4000px PNG, I har lagt i `/public` uden at gå gennem loaderen. Komponenten er ærlig, når I er ærlige i props. Den er ikke et amulet, I sætter rundt om en fil, I nægtede at eje.
Det er ikke 'eksportér til WebP én gang'. Et format uden widths er stadig for mange pixels. En 1600px-hero på en 390px-skærm er det forkerte download i et moderne wrap. Art-direction — et andet crop på mobil — er et andet job end format. Løs format og width først. Løs crop, når heroen skærer ansigtet af. Et slider-plugin med fem WebP'er er fem LCP-kandidater. Ét billede, ét crop, ét `priority`. Resten lazy.
Og det er ikke at slå billeder fra for at jage en Lighthouse-score. Et marketing-site uden hero er et andet produkt. Pipeline'en lader jer have billedet og LCP'en. Hvis I fjerner heroen for at 'vinde performance' og stadig uploader ukomprimeret i cases, har I flyttet scoren. I har ikke flyttet vanen. Hastigheds-indlægget er hvorfor scoren betyder noget. Her er vanen, der holder den.
Det der typisk går galt, når nogen siger vi har billedoptimering
Den første fejl er at komprimere galleriet og glemme heroen. I kører et batch-job på cases og lader forsiden ligge, fordi den 'er design'. Heroen er LCP. Galleriet er under folden og må lazy-loades. Et ærligt første skridt er at pege på LCP-elementet i PageSpeed Insights — værktøjet I selv kan køre — og rette dét billede, før I bygger en DAM-drøm. Hvis I ikke kan sige hvilken fil der er LCP, er I ikke klar til en pipeline. I er klar til at måle.
Den anden fejl er `sizes` som copy-paste. `100vw` på et kort i et tre-kolonne-grid er at bede mobil om desktop-filen, eller desktop om en fil, der er for lille og bliver skaleret grimt. `sizes` er layoutet, I allerede har: `(max-width: 768px) 100vw, 33vw` eller hvad grid'et faktisk er. Uden den sætning er `srcset` et buffet, browseren gætter forkert på. next/image hjælper jer med at udlede filerne. Den kan ikke gætte jeres CSS.
Den tredje fejl er layout-skift, I kalder animation. Billedet lander, teksten hopper, CLS går i rødt. Width og height, eller en aspect-ratio-boks, før requesten. Et skeleton er tilladt. Et fade, der skubber H1, er ikke polish. Det er at I ikke reserverede pladsen. Tilgængelighed-indlægget er EAA og fokus. Her er pligten at lade billedet have et slot, også for den, der taber linjen de læste.
Den fjerde fejl er at lade CMS'et slå pipeline'en. WordPress med 'full size' som default i Gutenberg. Et headless CMS uden transformation. Shopify-files, I linker som CDN uden widths. I har next/image på de sider, en udvikler rørte, og originale uploads på de sider, redaktøren rørte i morges. Pipeline'en er nej'et i uploadet: max-dimension, tilladte formater, et afledt sæt, ikke 'vi plejer at huske at eksportere'. Hvis nej'et kun lever i repoet, har I en udvikler-pipeline. I har ikke en site-pipeline.
Mappe af filer vs. ejet pipeline — to slags 'vi har styr på billeder'
Den ærlige mappe
Nogen eksporterede WebP sidste uge. CMS'et kan stadig lægge originalen live.
- Virker, indtil den næste hero kommer ind som PNG fra et designværktøj
- next/image på nogle routes, `<img>` på de sider redaktøren byggede
- Ingen `sizes` — browseren gætter, og mobil henter for meget
- Er et ærligt midlertidigt sted, og det forkerte at kalde færdigt
Den ærlige pipeline
Upload-loft, afledte widths, moderne format, ét LCP-billede, layout-slot.
- CMS nægter filen, der slår LCP — før den er på CDN'en
- Markup med `srcset` og rigtige `sizes`; `priority` kun på heroen
- Dimensioner i layoutet, så CLS ikke er et fade I kalder design
- Er spild, hvis I stadig ikke har peget på hvilket billede der er LCP
Sådan får I en billedpipeline, I faktisk kan holde
Uden den her rækkefølge får I et plugin, I kalder optimering, og en hero I ikke har rørt.
- 01
Peg på LCP-elementet — derefter kun det billede, først
Kør PageSpeed Insights på forsiden og den side, I faktisk annoncerer. Hvis LCP er et billede, er det pipeline'ens første fil. Ret format, width, `priority` og layout-slot på den. Rør ikke galleriet endnu. Et DAM-projekt, der starter med alle assets, er hvordan heroen overlever som PNG, mens I navngiver mapper. Hastigheds-indlægget er tærsklen. Her er filen.
- 02
Sæt nej'et ved upload — ikke ved et batch-job, nogen husker
Max-dimension. Tilladte formater. Et afledt sæt widths jeres markup faktisk bruger. WordPress, et headless CMS, Shopify files: samme pligt, forskelligt sted. Hvis redaktøren kan lægge originalen live, har I ikke et nej. I har en vejledning. Vejledninger taber til en deadline. Et loft i CMS'et taber ikke.
- 03
Skriv `sizes` som layoutet, I har — ikke som 100vw overalt
Hero fuld bredde er `100vw`. Et tre-kolonne-grid er det ikke. Kort i sidebar er det ikke. next/image kan udlede `srcset`. Den kan ikke udlede jeres CSS. Hvis I ikke vil vedligeholde `sizes`, så gør layoutet færre varianter, ikke løgnen global. En forkert `sizes` er et for stort download med et grønt 'vi bruger Image'.
- 04
Reserver pladsen, før filen lander
Width/height eller aspect-ratio i markup. Ét `priority` på LCP-heroen. Lazy på resten. Ingen slider, der henter fem frames før første maling. Hvis I skal have art-direction, så to billeder med `picture`, ikke ét for stort crop I skjuler med CSS. CLS er ikke et æstetik-punkt. Det er at linjen, nogen læste, blev skubbet.
- 05
Giv pipeline'en et sluk-kriterium for undtagelser
Et SVG-logo skal ikke gennem en raster-loader. Et og-billede I ikke kan transformere, skal have en navngiven undtagelse, ikke 'slå optimering fra globalt'. Hvis jobbet var 'hero LCP', og I nu har `unoptimized` på hele sitet fordi ét screenshot knækkede, har I solgt pipeline'en for en fil. Skriv undtagelsen. Ret loaderen. Slå ikke nej'et fra.
“I har billedoptimering, når heroen har et format, en bredde og et nej i CMS'et. En mappe af WebP er et håb.”
WordPress, Next.js og Shopify — samme job, tre steder at sige nej
Et Next.js-marketing-site er det, vi typisk anbefaler, når I vil eje markup: `next/image` eller en loader mod jeres CDN, `priority` på én hero, `sizes` der matcher grid'et, og et CMS (headless eller git) der ikke kan uploade uden loft. Preview på pull requesten viser den rigtige fil, ikke kun den rigtige copy. Hvis I har Image-komponenten og stadig linker PNG fra `/public` på forsiden, har I en komponent. I har ikke en pipeline. Wordpress-til-Next-indlægget er cutover. Den her er billed-jobbet, I tager med jer — eller glemmer, og så er LCP den samme på den nye stack.
Et WordPress-site har samme job og et andet nej-punkt. Medie-biblioteket er pipeline'en, hvis I tvinger sizes, webp/avif, og nægter 'full' som default i indholdet. Et plugin, I kører én gang, er et batch. Det næste upload vinder. Hvis I later som om et cache-plugin er billedoptimering, har I cachet det forkerte download. Relancering-indlægget er 301'erne. Her er at lade Gutenberg være et sted med loft, ikke et drev med pretty permalinks.
Shopify er det tredje sted, I kan lyve på samme måde. CDN'en kan widths, hvis I bruger dem i theme-liquid eller i jeres headless-frontend. En `img` med `file`-URL uden width-parameter er originalen. Et app-filter, I har glemt efter et theme-skift, er et batch der døde. I har stadig et LCP-billede. I har stadig brug for ét `priority`, rigtige sizes, og et sted i admin der ikke lader en 4000px-produktfil blive hero på en collection. Shopify-indlæggene er hvornår platformen rækker. Den her er billedet, platformen ikke retter for jer, hvis temaet lyver.
Et 'vi fjerner billeder for at vinde Lighthouse' er det sidste job, I ikke skal købe. Marketing-sitet skal have en hero. Pipeline'en er hvordan I har den uden at betale LCP-gælden hver gang nogen eksporterer fra Figma. Hvis scoren kun er grøn på en side uden media, har I målt et andet produkt. Sæt nej'et. Ret heroen. Lad galleriet være lazy. Det er kedeligt. Det er det, der holder, når redaktøren kommer mandag.
Hvad I typisk bør gøre i den situation, I står i
Venstre er det, I typisk siger. Højre er det næste skridt, vi typisk anbefaler.
Situation
PageSpeed siger LCP er et billede, og I har et komprimerings-plugin
Næste skridt
Peg på filen. Ret heroens format, width og `priority`. Plugin'et rører ikke det, I ikke har peget på
Situation
I har next/image, og mobil henter stadig en desktop-hero
Næste skridt
`sizes` er løgn, eller kilden går uden om loaderen. Ret markup. Slå ikke optimering fra
Situation
Marketing uploader en ny hero som PNG, og LCP dør om mandagen
Næste skridt
Nej i CMS'et — max-dimension og format — ikke en Slack-besked om at huske eksport
Situation
CLS hopper, når billedet lander, og I har sat et fade på
Næste skridt
Reserver aspect-ratio. Fadet er ikke pladsen. Layoutet er pladsen
Situation
Et screenshot knækkede loaderen, så I satte unoptimized på hele sitet
Næste skridt
Navngiv undtagelsen. Ret loaderen. Et globalt unoptimized er at sælge pipeline'en for én fil
Tjekliste før I kalder det billedoptimering
Hvis I mangler flere af punkterne, er sætningen next/image — setup'et er en mappe.
- I kan pege på LCP-billedet på forsiden og på den side, I annoncerer
- Heroen har moderne format, rigtige widths og præcis ét `priority`
- `sizes` matcher layoutet — ikke 100vw på hvert kort
- Layoutet reserverer plads, så CLS ikke er et fade
- CMS'et kan ikke lægge originalen live uden loft
- Undtagelser er navngivne. Optimering er ikke slået fra globalt
Spørgsmål vi får igen og igen
Hvad er billedoptimering på en hjemmeside — reelt?
At et billede ikke kan nå browseren uden format, bredde, CDN og et layout-slot — og at heroen, der oftest er LCP, er den første fil I retter. Et plugin, en hånd-eksport, en Image-komponent uden `sizes`, er stykker. Pipeline'en er nej'et: i CMS'et, i markupen, i det ene `priority`. Hvis I ikke kan pege på LCP-filen, har I ikke optimeret. I har en mappe, I er glade for.
Er next/image nok i sig selv?
Nej. Den afleder widths og kan hoste og lazy-loade. Den kan også hente det forkerte, hvis `sizes` er løgn, hvis kilden ligger i `/public` uden loader, eller hvis I har slået optimering fra. Komponenten er et værktøj. Pipeline'en er upload-loft plus ærlig markup plus ét LCP-billede. Vi ser oftere det første alene. Det er derfor mobil stadig henter desktop-heroen med et grønt 'vi bruger Next'.
Skal vi konvertere alt til AVIF eller WebP med det samme?
Start med LCP-heroen. Moderne formater dér, med en fornuftig fallback browseren kan. Derefter de billeder over folden. Galleriet under folden må lazy-loades og kan følge med, når nej'et i CMS'et er sat. Et batch der konverterer et helt case-arkiv, mens forsiden stadig er PNG, er den forkerte rækkefølge. Format uden widths er stadig for mange pixels. Gør begge på den fil, der venter brugeren.
Hvorfor hopper siden, når billedet loader?
Fordi I ikke reserverede pladsen. Width og height, eller en aspect-ratio-boks, før requesten. Et fade retter ikke CLS. Det skjuler at layoutet ikke havde et slot. Det er det samme job på WordPress, Next og Shopify. Tilgængelighed og læsning taber, når H1 skubbes. Sæt dimensionerne. Lad lazy være til det, der ikke er LCP. Kald ikke hoppet for polish.
Er det her det samme som at have et hurtigt site der rangerer?
Nej. Hastigheds-indlægget er hvorfor Core Web Vitals tæller, og hvordan I måler. Den her er billedet som det element, der oftest *er* LCP på et marketing-site, og vanen der holder det: loft, `sizes`, ét `priority`, nej i CMS'et. I kan have en grøn lab-score på en side uden media og stadig dø på forsiden om mandagen. Pipeline'en retter filen. Den erstatter ikke målingen, og den erstatter ikke de redirects, I skylder efter en relancering.
Hvis I har next/image og en hero, PageSpeed stadig peger på
Lad os skille pipeline, plugin og mappen ad.
Et nej i CMS'et og én ærlig hero slår en eksport, I huskede sidste uge.
