Hvordan fjerne render-Blocking CSS og js? (Async, defer, critical CSS)

Hvordan fjerne render-Blocking CSS og js? (Async, defer, critical CSS)

Sist verifisert: 22. september 2026
8 min lesetid
Guide
Core Web Vitals

Når nettleseren laster siden din, leser den HTML-koden linje for linje. Når den møter <script src="stor-fil.js"> eller <link rel="stylesheet">, stopper den alt annet, laster ned filen og kjører den.

Først da rendrer den resten av siden. Dette er “Render-Blocking”.

I 2026, når Core Web Vitals teller (spesielt LCP - Largest Contentful Paint), må du fikse dette.

#1. Javascript: Async og defer

Gammel skole så: “legg skript i bunnen (wp_footer)”. Ny skole sier: “bruk attributter”.

  • <script async>: Laster i bakgrunnen, kjører umiddelbart etter nedlasting (risikabelt for avhengigheter, f.eks. jQuery).
  • <script defer>: Laster i bakgrunnen, kjører først etter HTML er lastet (trygt, bevarer rekkefølge).

Hvordan legge til defer i WordPress? Cache-plugins (WP Rocket, Autoptimize, LiteSpeed Cache) har en “Defer JS” alternativ. Aktiver det.

Dette løser vanligvis 90% av JS-problemene.

#2. CSS: Critical CSS

CSS er vanskeligere. Du kan ikke “forsinke” det fordi siden vil se ut som “rå tekst” et øyeblikk (ustylet - FOUC-effekt).

Løsningen er Critical CSS.

  1. Ta bare CSS som trengs for “over folden” innhold (synlig uten scrolling).
  2. Lim det inn inline i <style> i headeren.
  3. Last resten av CSS (bunntekst, nedre seksjoner) asynkront i bakgrunnen.

De fleste moderne optimaliseringsplugins genererer Critical CSS automatisk.

#Strategioppsummering

  1. JS: Alt med defer (bortsett fra absolutt kritiske analyse/cookie-skript).
  2. CSS: Critical CSS inline + resten asynkront.
  3. Fonter: Bruk font-display: swap.

På denne måten ser brukeren innhold umiddelbart mens tunge galleri- eller kartskript lastes i bakgrunnen.

#Slik finner du ut hva som faktisk blokkerer

Lighthouse gir deg en liste over blokkerende filer, men listen sier ingenting om hvor mye av hver fil som faktisk brukes. Åpne DevTools, kjør “Show Coverage” fra kommandopaletten, last siden på nytt og se på kolonnen “Unused Bytes”. Et vanlig WordPress-tema med sidebygger viser gjerne 70 til 90 prosent ubrukt CSS på forsiden. Det tallet er viktigere enn filstørrelsen alene, fordi det skiller mellom to helt ulike problemer: for mye CSS, eller CSS lastet på feil tidspunkt.

Nettverksfanen forteller resten. Sorter etter waterfall og let etter små filer som starter nedlastingen sent. De er nesten alltid ressurser nettleseren først oppdaget etter å ha parset en annen fil, og nettopp de er kandidater for preload.

#Async eller defer, en kort beslutningstabell

AttributtNedlastingKjøringRekkefølge bevartBruk når
ingenblokkerer parsingumiddelbartjahelst aldri i <head>
asyncparalleltså snart filen er nedeneifrittstående skript uten avhengigheter
deferparalleltetter at HTML er parsetjaalt som bruker jQuery eller andre skript
type="module"paralleltetter parsingjaES-moduler, defer er innebygd

Regelen i praksis: defer er standardvalget og async er unntaket. Grunnen er at async kjører i den rekkefølgen filene tilfeldigvis blir ferdige. En galleri-plugin som kaller jQuery(...) før jQuery er lastet gir en TypeError i konsollen og et tomt galleri på siden. Feilen viser seg sjelden på utviklermaskinen, der alt ligger i cache og kommer ned i riktig rekkefølge uansett.

#Defer i WordPress uten plugin

WordPress 6.3 innførte et strategy-argument i wp_enqueue_script(), og det er den riktige måten i dag, fordi WordPress selv holder styr på avhengighetskjeden:

wp_enqueue_script(
    'tema-galleri',
    get_template_directory_uri() . '/js/galleri.js',
    array( 'jquery' ),
    '1.2.0',
    array(
        'in_footer' => true,
        'strategy'  => 'defer',
    )
);

Poenget med å oppgi array( 'jquery' ) er at WordPress da nekter å utsette skriptet hvis jQuery selv ikke er utsatt. Du får rett og slett ikke lov til å lage den klassiske feilen.

For eldre installasjoner, eller for en plugin du ikke kan endre, går veien om filteret:

add_filter( 'script_loader_tag', 'nb_defer_valgte_skript', 10, 2 );

function nb_defer_valgte_skript( string $tag, string $handle ): string {
    $utsatt = array( 'slider', 'lightbox', 'kart' );

    return in_array( $handle, $utsatt, true )
        ? str_replace( ' src', ' defer src', $tag )
        : $tag;
}

Legg merke til at listen er en ja-liste, ikke en nei-liste. En nei-liste (“alt utenom disse”) ser mer effektiv ut, men den utsetter også skript som legges til av neste plugin du installerer. Da har du en feil du ikke har skrevet.

#Critical CSS uten at siden blinker

Mønsteret er alltid det samme: kritisk CSS inline i <head>, resten hentet uten å blokkere.

<style>/* bare regler for det som er synlig uten scrolling */</style>
<link rel="preload" href="/style.css" as="style"
      onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="/style.css"></noscript>

noscript-linjen er ikke pynt. Uten den mister besøkende med JavaScript avslått hele stilarket, og det gjelder også en del bedriftsnettverk med streng innholdsfiltrering.

Tre ting avgjør om dette går bra:

  1. Størrelsen. Hold inline-blokken under omtrent 15 KB. Blir den større, betaler du med lengre HTML-svar på hver eneste sidevisning, og da har du flyttet problemet i stedet for å fjerne det.
  2. Viewport. Critical CSS generert på 1300 piksler bredde mangler reglene som bare gjelder mobil. Generer for begge bredder og slå sammen resultatet.
  3. Test på treg linje. Sett DevTools til “Slow 3G” og last på nytt. Ser du ustylet tekst i et halvt sekund før layouten smekker på plass, har du tatt med for lite i den kritiske blokken.

#Fonter, blokkeringen folk glemmer

En egen skrifttype uten font-display gir FOIT: nettleseren skjuler teksten til fontfilen er nede. På en dårlig mobilforbindelse betyr det flere sekunder med tomme tekstflater der innholdet skulle stått.

@font-face {
    font-family: 'Inter';
    src: url('/fonts/inter.woff2') format('woff2');
    font-display: swap;
}

swap viser systemfonten umiddelbart og bytter når filen kommer. Kombiner med preload, og husk crossorigin, som kreves for fonter selv når filen ligger på ditt eget domene:

<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>

Hoster du fonten selv, sparer du i tillegg et DNS-oppslag og et TLS-håndtrykk mot et fremmed domene før nedlastingen i det hele tatt begynner.

#Tredjeparts skript setter ofte grensen

Du kan optimalisere temaet ditt perfekt og likevel bli stående på samme LCP, fordi en chat-widget og en kartinnbygging drar inn noen hundre kilobyte hver. To grep hjelper mer enn all minifisering til sammen.

Last chat-widgeten først når brukeren viser tegn til å være til stede:

addEventListener('scroll', function last() {
    const s = document.createElement('script');
    s.src = 'https://widget.example.com/chat.js';
    s.defer = true;
    document.body.appendChild(s);
}, { once: true });

Ingen besøkende åpner en chat i løpet av de første 300 millisekundene, så det er ingenting å tape på å vente.

Videoinnbygginger bytter du ut med en fasade: et stillbilde som ser ut som spilleren, og selve iframen først ved klikk. Pakken lite-youtube-embed gjør nettopp dette og tar en YouTube-innbygging fra flere hundre kilobyte ned til noen få.

#Mål før og etter, ellers gjetter du

Lighthouse er labdata og gir rask tilbakemelding på hver enkelt endring. Feltdataene i Chrome User Experience Report er de som avgjør hva Search Console viser. De to er ikke uenige, de måler forskjellige ting: labdata er én måling på én maskin, feltdata er et rullerende vindu på 28 dager fra ekte enheter og ekte forbindelser.

Konsekvensen er praktisk. Ikke konkluder med at endringen var uten effekt fordi Search Console står stille dagen etter. Vinduet må rulle gjennom først. Noter datoen for utrullingen, så du vet hvilken del av kurven som hører til hvilken endring.

#Fem feil som koster mest

  • async på noe som bruker jQuery. Gir tomme gallerier og skjemaer som ikke sender, og bare på trege forbindelser.
  • For mye CSS inline. Under omtrent 15 KB, ellers betaler hver sidevisning for det.
  • Glemt mobilviewport i Critical CSS. Mobilen er der målingen som teller blir gjort.
  • Nei-liste i stedet for ja-liste når du utsetter skript. Neste plugin blir ditt problem.
  • Ingen ny sjekk etter plugin-oppdateringer. Plugins endrer hva de køer opp, og et oppsett som virket i fjor kan være stille brutt i dag.

#Rekkefølgen som gir minst risiko

Gjør det i denne rekkefølgen, så vet du alltid hvilken endring som forårsaket hva. Fjern først skript og stilark som ikke skal lastes på den aktuelle siden i det hele tatt, for en fil som ikke sendes kan heller ikke blokkere noe. Utsett deretter resten med defer, og sjekk konsollen for feil før du går videre. Legg Critical CSS til sist, fordi det er steget som lettest gir synlige feil og dermed det du vil kunne rulle tilbake alene. Mellom hvert steg tar du en Lighthouse-kjøring på samme URL og samme innstillinger, ellers sammenligner du to ulike målinger og ikke to versjoner av siden.

Se vår WordPress-hastighetsoptimalisering.

Neste steg

Gjør artikkelen om til faktisk implementering

Denne blokken styrker intern lenking og sender leseren videre til de mest relevante tjenestene og innholdet.

Vil du få dette implementert på nettstedet ditt?

Hvis problemet er Core Web Vitals, treg rendering eller tung WordPress-kjoring, kan jeg definere og gjennomfore optimaliseringen.

Relaterte artikler