Bildestørrelsesfeil og Cumulative Layout Shift (CLS) er blant de vanligste advarslene nettstedseiere ser i Google Search Console og PageSpeed Insights. Denne guiden viser hvordan du finner årsakene i WordPress, retter maler og bildeflyten og måler CLS på en måte som kan gjentas, i stedet for å pynte én enkelt URL til «grønn».
CLS måler visuell stabilitet: hopper noe i visningsområdet mens siden lastes, stiger scoren. Manglende width/height på <img>, sene hero-bilder, cookie-bannere og annonseplasser uten reservert høyde er de vanlige mistenkte. Offisiell fordypning: web.dev om CLS, web.dev om CLS-optimalisering, MDN aspect-ratio og wp_get_attachment_image().
I nettbutikker og magasintemaer går den samme feilen igjen: et skreddersydd tema skriver bilder med hardkodet markup, redaksjonen laster opp originaler på 5000 piksler, og en optimaliseringsutvidelse komprimerer filene uten noen gang å skrive mål inn i HTML-treet. PageSpeed blir da «grønn» på en demo-URL og forblir rød i CrUX, fordi kategori- og produktmaler bruker andre bildeveier.
Hva bildestørrelsesfeil i PageSpeed Insights betyr
I mange år varslet Lighthouse at bildeelementer manglet eksplisitt bredde og høyde når HTML-en ikke oppga mål. Nettleseren kjenner da sideforholdet først etter nedlastingen og skyver tekst og knapper nedover. På produktsider med mange miniatyrbilder summerer det seg til en rød CLS.
Fra og med Lighthouse 13 heter disse kontrollene noe annet. Ifølge Chrome for Developers er revisjonene unsized-images og layout-shifts slått sammen i innsikten cls-culprits-insight, og prioritize-lcp-image og lcp-lazy-loaded i lcp-discovery-insight. Søker du etter det gamle revisjonsnavnet fra eldre saker eller byrårapporter, finner du det ikke lenger i den nye rapporten. Årsaken er den samme.
I WordPress oppstår feilene ofte slik:
- Egne maler bruker hardkodet
<img src="...">uten attributter - Sidebyggere lagrer bilde-HTML uten mål i post meta
- SVG-ikoner uten viewBox og uten CSS-størrelse
- Bakgrunnsbilder i CSS kan ikke få
width/heighti markup (plassen må reserveres via beholderen) - Galleri-kortkoder fra eldre utvidelser gjengir
<img>uten vedleggs-API-et - CDN-URL-er som bare speiler filen og mister metadata fra mediebiblioteket
Et annet spesialtilfelle er eksterne bilder (hotlinking til produsent-PDF-er eller sosiale CDN-er). WordPress kjenner ikke målene deres. Enten hoster du dem lokalt og behandler dem som vedlegg, eller så sikrer du den omsluttende beholderen med fast sideforhold og min-height.
Hvordan Google beregner CLS
Hver enkelt forskyvning får en score av to faktorer: layoutskift-score = impact fraction × distance fraction. Impact fraction er andelen av visningsområdet som det ustabile elementet dekker i begge bilderammene til sammen. Distance fraction er den største strekningen elementet flytter seg, i forhold til den største dimensjonen av visningsområdet. Et element som sammen med sin nye posisjon dekker halve visningsområdet og flytter seg 15 % av høyden, gir 0,5 × 0,15 = 0,075.
CLS summerer ikke lenger disse verdiene over hele sidens levetid. web.dev definerer CLS som den største serien av forskyvninger: skift med mindre enn ett sekund imellom danner et sesjonsvindu, og et vindu varer høyst fem sekunder. Det vinduet med høyest sum teller. En lang side med mange små forskyvninger spredt i tid blir derfor ikke automatisk rød.
To unntak er viktige for temautviklere. Forskyvninger innen 500 ms etter en diskret inndata (trykk, klikk, tastetrykk) får flagget hadRecentInput og regnes ikke med i CLS. Rulling, dra og knipezoom teller ikke som slik inndata. Og animasjoner via transform skyver ikke andre elementer, så de teller ifølge web.dev ikke i CLS.
Google vurderer feltdata (CrUX) strengere enn én enkelt Lighthouse-kjøring i laben. Det som teller er 75. persentil av sidevisningene, adskilt for mobil og desktop. Mål derfor ekte sidetyper etter rettingene (forside, innlegg, kategori, produkt, handlekurv), ikke bare URL-en som tilfeldigvis ble grønn.
| CLS (god / trenger forbedring / dårlig) | Typisk bildeårsak |
|---|---|
| ≤ 0,1 | Mål og sideforhold er satt |
| 0,1-0,25 | Blandede maler, sene bannere |
| > 0,25 | Hero uten mål, annonser uten plass, fonter og bilder i kombinasjon |
Lab-CLS og felt-CLS kan sprike. I laben mangler ofte samtykkebannere, A/B-tester og trege tredjepartsskript. Når Search Console melder «dårlig» og Lighthouse «god», stoler du på feltdataene og åpner Layout Shift Regions på en ekte mobil eller en realistisk emulering.
Hvordan nettleseren utleder sideforhold fra width og height
Attributtene width og height er ifølge MDN heltall uten enhet og angir den iboende størrelsen i piksler. De bestemmer ikke hvor stort bildet til slutt vises. Nytten er at nettleseren regner ut sideforholdet før bildet er lastet. Moderne nettlesere setter internt en verdi som aspect-ratio: auto 640 / 360 (web.dev).
auto i denne verdien har en presis betydning. MDN beskriver det slik: for et erstattet element som <img> gjelder det oppgitte forholdet til innholdet er lastet, deretter filens naturlige forhold. Stemmer ikke attributtene og filen overens, hopper bildet likevel etter lasting. Det er nøyaktig det som skjer når en mal skriver originalens mål i attributtene, men leverer en størrelse med annen beskjæring.
Det gir tre regler:
- Alle kandidater i et
srcsettrenger samme sideforhold, ellers stemmer attributtene bare for én av dem. - Ved art direction med
<picture>og ulike beskjæringer får hvert<source>egnewidth/height. Ifølge web.dev støtter Chrome, Firefox og Safari dette nå. - Bilder med lat lasting trenger attributtene ekstra mye. MDN påpeker at et bilde som ennå ikke er lastet og mangler mål, er 0 × 0 piksler og dermed kanskje aldri havner i det synlige området som ville utløst lastingen.
En utbredt, men virkningsløs regel er aspect-ratio: attr(width) / attr(height). Uten typeangivelse returnerer attr() ifølge MDN en CSS-streng, og en streng er ikke et gyldig forhold. Linjen forkastes. Nettleseren gjør utledningen selv uansett, så regelen kan fjernes.
Hvordan rette bilde-CLS i HTML-markup
1. Sett width og height
<img src="bilde.jpg" width="800" height="600" alt="Beskrivelse">I WordPress bør du helst bruke kjernefunksjonen som henter målene fra vedleggsmetadataene:
echo wp_get_attachment_image( $attachment_id, 'large' );wp_get_attachment_image() skriver width, height og, når underformater finnes, srcset/sizes. Klassen attachment-large size-large og loading setter WordPress selv; en egen 'loading' => 'lazy' trengs ikke, fordi kjernen siden 6.3 avgjør hvilke bilder som kan lastes lat. Hardkodede <img>-tagger i eldre temaer er den vanligste grunnen til at bare nye innlegg er «rene» mens det eldre innholdet gir CLS.
Bruker du ACF-bildefelt, lagrer du vedleggs-ID-en, ikke bare URL-en. Fra ID-en bygger du wp_get_attachment_image(). Med en naken URL har du bare gjetting eller en ekstra spørring mot vedleggstabellen igjen.
2. CSS aspect-ratio for beholdere og beskjæringer
For innholdsbilder med riktige attributter holder en responsiv grunnregel. Et fast forhold på alle innholdsbilder ville tvunget stående bilder og panoramaer inn i 4:3 og forvrengt dem:
.entry-content img {
max-width: 100%;
height: auto;
}
.hero-media img {
aspect-ratio: 16 / 9;
width: 100%;
height: auto;
object-fit: cover;
}Et fast aspect-ratio hører hjemme på komponenter med bevisst beskjæring: hero, kortrutenett, produktfliser, innebygde videoer og beholdere med bakgrunnsbilde. Kombiner det med fornuftige sizes, ellers laster nettleseren for store varianter, og LCP lider parallelt med CLS.
Før aspect-ratio reserverte temaer plass med padding-bottom-trikset: en wrapper med height: 0 og padding-bottom: 56.25% (9 delt på 16), med et absolutt posisjonert bilde inni. Det virker fortsatt, men krever ekstra markup. Overtar du gamle temaer, lønner det seg å bytte til aspect-ratio ved neste malrefaktorering, ikke som et eget prosjekt.
3. Bruk lat lasting riktig
Lat lasting hører hjemme under bretten. LCP-elementet (ofte hero-bildet) skal ikke ha loading="lazy". Ellers utsetter nettleseren nedlastingen til layouten er klar. Mer om LCP finner du i guiden til Core Web Vitals og INP.
I malen er den mest direkte veien å merke hero-bildet eksplisitt som viktig:
echo wp_get_attachment_image(
$hero_id,
'full',
false,
array(
'class' => 'hero-media__img',
'fetchpriority' => 'high',
)
);Med fetchpriority="high" behandler wp_get_loading_optimization_attributes() bildet som synlig og utelater loading="lazy". Den tidligere utbredte veien via filteret wp_get_attachment_image_attributes, som i ettertid setter loading til eager, har en hake siden WordPress 6.7: på det tidspunktet har kjernen allerede satt auto først i sizes for late bilder. Ifølge utviklernotatet for 6.7 forkaster nettlesere sizes="auto, ..." på et bilde som ikke lastes lat, og faller tilbake til 100vw. Hero-bildet lastes da i den største varianten. Må du beholde filteret, fjerner du prefikset slik:
add_filter( 'wp_get_attachment_image_attributes', function ( $attr ) {
if ( ! empty( $attr['class'] ) && false !== strpos( $attr['class'], 'skip-lazy' ) ) {
$attr['loading'] = 'eager';
$attr['fetchpriority'] = 'high';
if ( isset( $attr['sizes'] ) ) {
$attr['sizes'] = preg_replace( '/^\s*auto\s*,\s*/i', '', $attr['sizes'] );
}
}
return $attr;
} );fetchpriority er ifølge MDN bare et hint til nettleseren, med verdiene high, low og auto. Sett high på nøyaktig ett bilde per side, ellers konkurrerer flere nedlastinger om samme prioritet.
I butikktemaer ser du ofte at det første produktbildet lastes lat, fordi et generelt filter merker alle img. Et unntak for innhold over bretten sparer CLS og LCP. Sjekk også slidere: er slide 2 og 3 lat lastet med en gang, men slide 1 mangler mål, hopper hele karusellrammen likevel.
Hva WordPress gjør automatisk siden 5.5, 6.3 og 6.7
Mange veiledninger anbefaler kode for ting kjernen har tatt over for lengst. Status etter de offisielle utviklernotatene:
| Versjon | Endring | Kilde |
|---|---|---|
| 4.4 | srcset og sizes for vedleggsbilder | wp_get_attachment_image |
| 5.5 | loading="lazy" for bilder med width og height; manglende mål legges til på bilder med klassen wp-image-{ID} | Utviklernotat 5.5 |
| 6.1 | decoding-attributt i wp_get_attachment_image() | Funksjonens endringslogg |
| 6.3 | fetchpriority="high" for det sannsynlige LCP-bildet, terskel for bilder som ikke lastes lat økt fra 1 til 3 | Utviklernotat 6.3 |
| 6.7 | sizes="auto, ..." for bilder som lastes lat | Utviklernotat 6.7 |
Tillegget av mål skjer i wp_filter_content_tags(), som i default-filters.php henger på the_content med prioritet 12, altså etter kortkodene. Lat lasting hopper over de tre første innholdsbildene; verdien styres av filteret wp_omit_loading_attr_threshold. For å få fetchpriority="high" må et bilde ifølge utviklernotatet for 6.3 ha minst 50 000 piksler i flate, justerbart via wp_min_priority_img_pixels. En liten logo får derfor ikke prioriteten.
Den praktiske følgen: bilder som er satt inn via blokkredigereren med kobling til mediebiblioteket, er sjelden problemet i nyere versjoner. Feilene sitter i temamaler, byggerutdata, hardkodet HTML og bilder uten klassen wp-image-{ID}.
Hvilke bildestørrelser WordPress lager ved opplasting
Ifølge WordPress-kildekoden lager en fersk installasjon disse størrelsene: thumbnail 150 px, medium 300 px, medium_large 768 px og large 1024 px (bredde, kan endres i innstillingene). Siden 5.3 kommer 1536x1536 og 2048x2048 i tillegg. Også siden 5.3 skalerer WordPress originaler der lengste side overstiger 2560 px ned til denne grensen og lagrer dem med suffikset -scaled; filteret big_image_size_threshold endrer eller deaktiverer verdien.
For srcset tar wp_calculate_image_srcset() bare med varianter med samme sideforhold og kutter som standard ved 2048 px bredde (filteret max_srcset_image_width). Temaets egne størrelser via add_image_size() med hard beskjæring (crop = true) har et annet forhold enn originalen og havner derfor ikke i originalens srcset. Et kortrutenett med 4:3-beskjæring trenger altså flere egne størrelser i samme 4:3-forhold, ellers finnes det bare én fil for alle skjermer.
Hvordan bruke responsive bilder og srcset i WordPress
Kjernen leverer srcset når du bruker vedleggs-API-ene. Sidebyggere og ACF-bildefelt med manuell URL går utenom dette. Da mangler både mål og passende varianter.
Slik velger nettleseren: med w-deskriptorer i srcset ignorerer den src og bruker sizes til å bestemme forventet visningsbredde. Mangler sizes, gjelder ifølge MDN 100vw. WordPress setter derfor siden 4.4 en standardverdi etter mønsteret (max-width: {bredde}px) 100vw, {bredde}px; temaer bør tilpasse den til den faktiske layouten via filteret wp_calculate_image_sizes. Siden 6.7 setter kjernen auto foran på bilder som lastes lat, slik at nettleseren bruker den faktisk gjengitte bredden.
Sjekkliste for redaksjon og utviklere:
- Mediebibliotek: ikke last opp originaler som er 6000 px brede uten grunn
- Temaet registrerer fornuftige
add_image_size-varianter i samme sideforhold - Maler kaller aldri bare
wp_get_attachment_url()for synlige innholdsbilder - Etter temabytte lager du underformatene på nytt (f.eks.
wp media regenerate), ellers mangler srcset-kandidater - Tilpass
sizes-attributtet til den faktiske layoutbredden (sidefelt eller full bredde)
Et typisk magasintilfelle: innholdet er 720 px bredt på desktop og 100 vw på mobil. Står sizes på 100vw, laster desktopnettleseren ofte varianten på 2048 piksler til en spalte på 720 piksler. Det er ingen CLS-feil, men det forlenger LCP og oppleves som en «tung side». Tenk CLS og LCP sammen, ikke etter hverandre.
Bilde mindre enn anbefalt: krav for Discover og artikkelmarkup
Meldingen i Search Console om at bildet er mindre enn anbefalt, har ingenting med CLS å gjøre. Den gjelder bildet Google bruker til forhåndsvisninger, altså det fremhevede bildet, og:image og image-feltet i strukturert artikkelmarkup. Meldingen stammer opprinnelig fra AMP-æraen; dagens krav står i to Google-dokumenter.
For Google Discover bør store bilder være minst 1200 px brede, ha mer enn 300 000 piksler i flate og ha forholdet 16:9. Store forhåndsvisninger vises bare når siden tillater max-image-preview:large eller bruker AMP. Nettstedets logo skal ikke gis til Google som forhåndsvisningsbilde via og:image eller schema-markup.
Dokumentasjonen for artikkelmarkup anbefaler flere høyoppløselige bilder med minst 50 000 piksler (bredde ganger høyde) i forholdene 16:9, 4:3 og 1:1. Bilde-URL-ene må kunne gjennomsøkes og indekseres.
Et kontrollskript for redaksjonen som logger for smale fremhevede bilder ved publisering:
add_action( 'publish_post', function ( int $post_id ) {
$thumbnail_id = get_post_thumbnail_id( $post_id );
if ( ! $thumbnail_id ) {
return;
}
$meta = wp_get_attachment_metadata( $thumbnail_id );
$width = (int) ( $meta['width'] ?? 0 );
if ( $width < 1200 ) {
error_log( sprintf( 'Innlegg %d: fremhevet bilde er bare %d px bredt.', $post_id, $width ) );
}
} );wp_get_attachment_metadata() returnerer for skalerte opplastinger målene til -scaled-filen, altså høyst 2560 px. Det holder for Discover.
Hvordan unngå CLS i WooCommerce og rutenettlayouter
Produktrutenett er CLS-brennpunkter. Hver flis trenger samme bilderamme. Har et produkt ikke noe fremhevet bilde og reserven er en smalere plassholder-PNG, hopper kortet. Sett en felles wrapper med sideforhold og object-fit: cover for produktbilder i temaet.
Varianter og gallerier: WooCommerce bytter miniatyrbilder med JS. Reserver galleriets høyde før variantskriptene kjører. Ellers klikker noen på «Størrelse M», det store bildet lastes inn, og legg-i-handlekurv-knappen flytter seg. Forskyvninger innen 500 ms etter klikket teller riktignok ikke i CLS, men en innlasting etter det gjør det, og knappen glir unna fingeren uansett.
Hvordan webfonter, bannere og tredjepartsskript gir CLS
Ikke all CLS er et bildeproblem. Cookie-bannere som hopper fra 0 til 120 px etter samtykke, fonter uten passende font-display-strategi og sene affiliate-widgets gir de samme skiftområdene i DevTools. Reserver minimumshøyder for samtykkelinjer og annonseplasser før skriptene lastes. web.dev anbefaler også å ikke la reservert plass kollapse når ingen annonse leveres, men å vise en plassholder.
Chrome: DevTools, så Rendering, så Layout Shift Regions. Last inn på nytt, og blå flater markerer synderne. Følg med på mobilemulering; desktop-CLS kan være «grønn» mens mobil-CrUX forblir rød.
Andre kilder enn bilder:
- Webfonter som hopper fra reservefont til egen font (
font-display: optionalbruker ifølge web.dev bare fonten hvis den allerede er der ved første layout) - Innebygde videoer og iframes uten boks med sideforhold
- «Sticky» toppfelt som vokser etter rullehøyde
- Live chat-bobler som dukker opp først etter inaktivitet
- Animasjoner via
top,leftellerheighti stedet fortransform
Hvordan reparere gamle innlegg programmatisk
For bilder med klassen wp-image-{ID} trengs ingen egen kode: siden 5.5 legger wp_filter_content_tags() selv til manglende width/height, med målene til den størrelsen som faktisk er satt inn. Et filter som i stedet bruker målene fra full, skriver feil attributter på et innsatt miniatyrbilde på 300 px.
Egen kode lønner seg bare for tagger uten denne klassen, for eksempel fra importert innhold eller gammel bygger-HTML. Filteret under kjører etter kjernen, finner vedleggs-ID-en via URL-en og bruker målene til den riktige størrelsen:
add_filter( 'the_content', function ( $content ) {
if ( false === strpos( $content, '<img' ) ) {
return $content;
}
return preg_replace_callback(
'/<img\b[^>]*>/i',
function ( $matches ) {
$img = $matches[0];
if ( preg_match( '/\swidth=/i', $img ) || ! preg_match( '/\ssrc="([^"]+)"/i', $img, $src ) ) {
return $img;
}
// attachment_url_to_postid() kjenner bare original-URL-en, så størrelsessuffikset fjernes.
$original = preg_replace( '/-\d+x\d+(?=\.\w+$)/', '', strtok( $src[1], '?' ) );
$id = attachment_url_to_postid( $original );
if ( ! $id ) {
return $img;
}
$size = wp_image_src_get_dimensions( $src[1], wp_get_attachment_metadata( $id ), $id );
if ( ! $size ) {
return $img;
}
return str_replace( '<img', sprintf( '<img width="%d" height="%d"', $size[0], $size[1] ), $img );
},
$content
);
}, 13 );Dette er et sikkerhetsnett, ikke en erstatning for ryddige maler. attachment_url_to_postid() gjør én databasespørring per bilde; i store arkiver lønner det seg med en engangskjøring i WP-CLI som skriver attributtene inn i post_content, i stedet for å filtrere ved hver visning. Bilder fra andre domener blir ikke rørt: å hente dem ved kjøretid med getimagesize() laster filen fra den fremmede serveren ved hver cache-miss.
Hvordan måle og kontrollere CLS etter rettingene
Ikke bare kjør Lighthouse på nytt etter hver retting. En arbeidsflyt som holder i byråprosjekter:
- Åpne Core Web Vitals i Search Console og noter berørte URL-grupper
- Sjekk én URL per maltype med Layout Shift Regions
- Emuler en Android-enhet i mellomklassen (ikke bare en Pixel-desktop)
- Vent 28 dager med feltdata etter utrulling før du melder «ferdig», fordi CrUX bruker et rullerende 28-dagersvindu
- Regresjon: en ny hero-blokk eller en ny samtykkeplattform trenger samme kontroll
Til egne feltdata passer Googles bibliotek web-vitals. Det rapporterer CLS etter samme logikk med sesjonsvinduer som CrUX:
import { onCLS } from 'web-vitals';
onCLS( ( metric ) => {
navigator.sendBeacon( '/vitals', JSON.stringify( {
name: metric.name,
value: metric.value,
id: metric.id,
} ) );
} );Dokumenter hvilke sidetyper du har målt. Er bare forsiden grønn mens enkeltinnlegget på bloggen forblir rødt, er oppdraget ikke ferdig. Redaksjon og utviklere trenger en felles definisjon av «ferdig».
Sjekkliste for bildestørrelsesfeil og CLS i WordPress
- Alle synlige innholdsbilder kommer via vedleggs-API-ene
- Hero uten
loading="lazy", medfetchpriority="high"på nøyaktig ett bilde - Ingen
sizes="auto, ..."på bilder som ikke lastes lat - Temaets
add_image_sizedekker rutenett, enkeltvisning og OG, hver i samme forhold - Fremhevede bilder minst 1200 px brede,
max-image-preview:largesatt - Samtykkebannere og annonseplasser har reservert høyde
- CrUX og Search Console sjekket på nytt etter utrulling
- Ingen bakgrunns-heroer uten beholder med sideforhold
- Reservebilder i produktrutenettet har samme flishøyde
Typiske bilde-CLS-feil i WordPress-prosjekter
- Optimaliseringsutvidelsen er på, men temaet gjengir fortsatt hardkodede
<img>-tagger - AMP eller en egen «mobiltema»-gren med annen markup enn desktop
- WebP-konvertering erstatter filer, men sletter ikke gamle srcset-kandidater
- Redaksjonen setter inn skjermbilder av hele nettleservinduer (3000×2000) uten beskjæring
- Sidebyggeren lagrer absolutte pikselbredder som brekker på mobil og så rettes opp med JS
Vanlige spørsmål om bildestørrelser og CLS i WordPress
Hva gir CLS fra bilder i WordPress
Som regel mangler faste bildemål, responsive varianter eller reservert plass i malen. Dermed hopper layouten når bildene lastes inn.
Hvordan rette bildestørrelsesfeil skikkelig
Sjekk maler, bildestørrelser, srcset-utdata og CSS-regler samlet. Mål deretter CLS på nytt på ekte sidetyper, ikke bare på én enkelt URL.
Hvor ofte bør man sjekke CLS
Etter temaendringer, nye komponenter, større medieopplastinger og Core Web Vitals-advarsler i Search Console.
Ødelegger width og height den responsive layouten
Nei. HTML-attributtene gir sideforholdet. Med CSS max-width: 100% og height: auto skalerer bildet, og den reserverte plassen blir værende.
Oppsummering
Bildestørrelsesfeil er sjelden et problem med én enkelt utvidelse. De oppstår der maler går utenom vedleggs-API-et, der hero og lat lasting kolliderer og der feltdata blir oversett. Strammer du inn mål, sideforhold og målinger som kan gjentas, får du stabilere layouter og mindre støy i Search Console, uten PageSpeed-pynt på en demo-URL.
Mer om ytelsesarbeid: WordPress-optimalisering for hastighet og hvordan gjøre en WordPress-side raskere.







