
⚡ Slik legger du til defer og async for WordPress-skript i function.php
Sider laster sakte, Google PageSpeed Insights viser oransje advarsler, og kunden spør: «hvorfor er nettstedet tregt?» Ni av ti ganger er rotårsaken at JavaScript blokkerer renderingen. Nettleseren treffer en <script>, stopper byggingen av DOM-en, laster og kjører skriptet, og først deretter fortsetter den. På et moderne nettsted med et dusin utvidelser blir denne forsinkelsen til sekunder.
WordPress hadde lenge ingen standard måte å kontrollere skriptinnlasting på. Utviklere danset rundt med workarounds: filtrering av script_loader_tag, patching av output via clean_url, eller til og med å skrive egne walkers for WP_Scripts. Men med lanseringen av WordPress 6.3 endret situasjonen seg radikalt, og nå har vi en ryddig, støttet måte å legge til defer eller async på ethvert skript uten et eneste hack.
Nedenfor finner du to fungerende metoder: den moderne, native tilnærmingen (WP 6.3+) og det velprøvde script_loader_tag-filteret (WP 4.1+). Begge er testet på reelle prosjekter, og begge bevarer integriteten til avhengighetskøen.
💡 Rask oversikt:
- Forstå forskjellen mellom
deferogasyncog når du skal bruke hvilken, dette avgjør om funksjonalitet ryker etter optimalisering - Bruk den native WordPress 6.3+-metoden via
wp_enqueue_script()medstrategy-parameteren, den reneste tilnærmingen som bevarer rekkefølgen på kjøring - Hvis nettstedet kjører en versjon under 6.3, bruk
script_loader_tag-filteret med en array av handles, dette fungerer fra og med WordPress 4.1 - For flere skripter, samle handles i en array og loop gjennom den, ett filter for alle skript i stedet for kopier og lim
Hva defer og async er og når du skal bruke dem
Når en nettleser møter en vanlig <script>-tagg, gjør den tre ting i rekkefølge: stopper parsing av HTML, laster skriptet, kjører det. Først deretter går den tilbake til HTML. På en side med fem skripter i <head> betyr dette at brukeren ser en hvit skjerm mens den siste kommentarutvidelsen laster, selv om selve innlegget kunne ha blitt rendret for lenge siden.
Attributtene defer og async løser dette problemet, men fungerer forskjellig:
Attributt | Når det lastes | Når det kjøres | Kjøringsrekkefølge |
|---|---|---|---|
(ingen) | Blokkerer parsing umiddelbart | Umiddelbart etter lasting | I DOM-rekkefølge |
| Parallelt med parsing | Etter at DOM er fullstendig lastet | I DOM-rekkefølge |
| Parallelt med parsing | Umiddelbart etter lasting | Den som laster først |
Defer er arbeidshesten for de fleste scenarioer. Skriptet laster parallelt med HTML og kjøres først når DOM-en er fullstendig bygget. Rekkefølgen bevares: skript A vil kjøre før skript B, selv om B lastet raskere. Dette er kritisk for jQuery og alt som avhenger av det.
Async er et verktøy for uavhengige skripter. Analyse, annonser, sosiale medier-widgets: de trenger ikke DOM-en, de bryr seg ikke om rekkefølge, de trenger bare å kjøre så raskt som mulig. Men hvis du setter async på et skript som avhenger av jQuery, vil du sannsynligvis få $ is not defined.
Enkel regel: skript avhenger av andre skript eller av DOM-en → defer. Skript er fullstendig autonomt → async. Når du er i tvil, start alltid med defer.
Metode 1: Native WordPress 6.3+-tilnærming
Siden juli 2023 har en ny mekanisme fungert i WordPress-kjernen. Funksjonene wp_register_script() og wp_enqueue_script() fikk en overbelastet femte parameter $args, en array der du kan spesifisere lastestrategien. Ingen filtre, ingen strengmagi, ingen risiko for å ødelegge avhengighetsrekkefølgen.
Grunnleggende syntaks for defer:
1 wp_enqueue_script( 2 'my-js-handle', 3 get_template_directory_uri() . '/js/my-script.js', 4 array('jquery'), 5 '1.0.0', 6 array( 7 'strategy' => 'defer', 8 'in_footer' => true, 9 ) 10 );
For async, samme mekanikk:
1 wp_enqueue_script( 2 'google-analytics', 3 'https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX', 4 array(), 5 '1.0.0', 6 array( 7 'strategy' => 'async', 8 'in_footer' => false, 9 ) 10 );
Nøkkelen in_footer inne i arrayen fungerer på samme måte som den gamle boolske parameteren: true plasserer skriptet i footeren, false i <head>. For defer setter du typisk true (skriptet venter uansett på DOM, ingen vits i å laste det tidlig), for async det som fungerer.
Hovedfordelen med den native metoden er at kjernen selv sjekker avhengighetstreet. Hvis skript A med defer avhenger av skript B, og B er registrert uten strategi (blokkerende), vil ikke WordPress ødelegge nettstedet ditt: det vil automatisk nedgradere skript A sin strategi til blokkerende. Når du bruker script_loader_tag mangler du denne beskyttelsen, filteret setter bare inn attributtet uten å se på avhengigheter.
Viktig: $args-arrayen dukket opp i WordPress 6.3. Hvis et tema eller en utvidelse må fungere på lavere versjoner, bruk metode 2 eller legg til en sjekk:
1 if ( version_compare( $GLOBALS['wp_version'], '6.3', '>=' ) ) { 2 // native method 3 } else { 4 // script_loader_tag filter 5 }
Metode 2: script_loader_tag-filter (WordPress 4.1+)
Hvis nettstedet kjører en versjon under 6.3 eller du trenger å opprettholde bakoverkompatibilitet, bruk det velprøvde script_loader_tag-filteret. Det har eksistert siden WordPress 4.1 og fungerer fortsatt feilfritt.
Filteret utløses rett før <script>-taggen sendes ut til HTML, du mottar den ferdige tagg-strengen, skript-handlen og filbanen, og kan erstatte src med defer="defer" src eller async="async" src.
Enkelt skript med defer:
1 function add_defer_to_my_script($tag, $handle) { 2 if ( 'my-js-handle' !== $handle ) { 3 return $tag; 4 } 5 return str_replace( ' src', ' defer="defer" src', $tag ); 6 } 7 add_filter('script_loader_tag', 'add_defer_to_my_script', 10, 2);
Koden plasseres i det aktive temaets functions.php eller, mer korrekt, i en separat snippet-utvidelse som Code Snippets eller WPCode. Hvis du legger den i et child-temas functions.php, vil skriptene bli blokkerende igjen når du bytter tema, og du vil ikke merke det umiddelbart.
Skript-handlen er den første parameteren du sendte til wp_register_script() eller wp_enqueue_script(). Dette er det som vises i if-betingelsen. Ikke gjett handlen, åpne kildekoden til utvidelsen eller temaet og finn kallet til wp_enqueue_script.
Defer og async for flere skript
Å legge til ett filter per skript er en vei til oppblåst functions.php og kopier-og-lim-feil. Den riktige løsningen: en array med handles og ett filter med en loop.
1 function add_defer_to_scripts($tag, $handle) { 2 $scripts_to_defer = array( 3 'my-js-handle', 4 'another-handle', 5 'third-party-lib', 6 ); 7 8 foreach ( $scripts_to_defer as $defer_script ) { 9 if ( $defer_script === $handle ) { 10 return str_replace( ' src', ' defer="defer" src', $tag ); 11 } 12 } 13 return $tag; 14 } 15 add_filter('script_loader_tag', 'add_defer_to_scripts', 10, 2);
For async er det bare attributtet og array-navnet som endres:
1 function add_async_to_scripts($tag, $handle) { 2 $scripts_to_async = array( 3 'google-tag-manager', 4 'facebook-pixel', 5 'hotjar', 6 ); 7 8 foreach ( $scripts_to_async as $async_script ) { 9 if ( $async_script === $handle ) { 10 return str_replace( ' src', ' async="async" src', $tag ); 11 } 12 } 13 return $tag; 14 } 15 add_filter('script_loader_tag', 'add_async_to_scripts', 10, 2);
Begge filtrene kan hektes på samtidig, defer på dine skript, async på tredjeparts trackere. De fungerer uavhengig og kommer ikke i konflikt.
Praktisk eksempel: Google Maps API
Google Maps er en klassisk kandidat for defer. Kartet er typisk i footeren på kontaktsiden, skriptet henter 100+ KB, og brukeren trenger ikke kartet med en gang. Dessuten avhenger ikke selve API-et av andre sideskripter, et ideelt tilfelle.
Koble til og defer:
1 // theme's functions.php 2 function enqueue_google_maps() { 3 if ( ! is_page('contacts') ) { 4 return; 5 } 6 7 wp_enqueue_script( 8 'google-maps-api', 9 'https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY', 10 array(), 11 null, 12 array( 13 'strategy' => 'defer', 14 'in_footer' => true, 15 ) 16 ); 17 } 18 add_action('wp_enqueue_scripts', 'enqueue_google_maps');
Samme resultat via script_loader_tag:
1 function add_defer_to_google_maps($tag, $handle) { 2 if ( 'google-maps-api' !== $handle ) { 3 return $tag; 4 } 5 return str_replace( ' src', ' defer="defer" src', $tag ); 6 } 7 add_filter('script_loader_tag', 'add_defer_to_google_maps', 10, 2);
Etter at du har installert en av variantene, sjekk definitivt kartet på kontaktsiden. Åpne nettleserkonsollen (F12), forsikre deg om at det ikke er noen JavaScript-feil, og at kartet ble rendret korrekt. Hvis du får en feil som initMap is not a function, betyr det at initialiseringsskriptet ditt også må merkes som defer og plasseres strengt etter API-tilkoblingen.
Hvordan verifisere at defer og async fungerer
Etter implementering kommer verifisering. Uten den vet du ikke om optimaliseringen fungerte eller bare ligger som død kode.
Åpne sidekilden (Ctrl+U) og finn skriptene dine. <script>-taggen skal ha attributtene:
1 <script defer="defer" src="/wp-content/themes/my-theme/js/my-script.js"></script>
Hvis det ikke er noen attributter, sjekk om handlen i filteret samsvarer med den faktiske skript-handlen. Vanlig feil: i wp_enqueue_script er handlen my-plugin-frontend, men i filteret er den my_plugin_frontend. Bindestrek versus understrek, og filteret hopper stille over skriptet.
Siste finpuss, Google PageSpeed Insights eller Lighthouse i Audits-fanen i utviklerverktøyene. Seksjonen «Eliminate render-blocking resources» skal vise forbedring. Den spesifikke gevinsten avhenger av antall og størrelse på skript, men for et typisk WordPress-nettsted med 5-7 utvidelser er en 40-60% reduksjon i blokkerende JavaScript et oppnåelig resultat.
⁉️🤔 Ofte stilte spørsmål
Kan jeg bruke både defer og async på ett skript?
Nei. Hvis du spesifiserer begge attributtene samtidig, vil nettleseren ignorere
deferog kjøre skriptet somasync. Denne oppførselen er bakt inn i HTML-spesifikasjonen,asynchar alltid prioritet. Velg én basert på om kjøringsrekkefølge er viktig.
Hva gjør jeg hvis skriptet sluttet å fungere etter at jeg la til defer?
Mest sannsynlig forventer skriptet at DOM-en ikke er bygget ennå og prøver å manipulere elementer som ikke eksisterer på kjøretidspunktet. Erstatt
defermed standard blokkerende lasting for det spesifikke skriptet. Eller pakk skriptkoden inn iDOMContentLoaded, da kan det fungere meddeferuten feil. Det andre alternativet er å foretrekke: du beholder optimaliseringen og fikser kompatibiliteten.
Hva er forskjellen mellom defer og å flytte skriptet til footeren via wp_enqueue_script med $in_footer = true?
$in_footer = trueflytter bare<script>-taggen fra<head>til slutten av<body>. Skriptet blokkerer fortsatt rendering, bare senere.deferlaster parallelt med HTML-parsing og kjøres strengt etter at DOM-en er bygget. Kombinert bruk (in_footer => true+strategy => 'defer') gir maksimal effekt: skriptet i footeren forsinker ikke første render, og defer garanterer at det heller ikke vil blokkere endelig rendering.
Bør jeg oppdatere WordPress til 6.3 bare for den native metoden?
Hvis nettstedet er på versjon 6.2 eller eldre, er det verdt å oppdatere ikke bare for
strategy. WordPress 6.3 lukket dusinvis av sårbarheter og ga ytelsesforbedringer i kjernen. Men hvis en oppdatering er umulig av en eller annen grunn, fungererscript_loader_tag-filteret helt pålitelig fra versjon 4.1, utgitt i 2014. Du taper ingenting på å bruke det.
Hva med jQuery, defer eller la det være som det er?
jQuery bør lastes med
deferhvis alle avhengige skripter også er merketdefer. Problemet er at WordPress-utvidelser ekstremt sjelden håndterer attributter for skriptene sine. Hvis du setterdeferpå jQuery mens en kontaktskjema-utvidelse kobler til sitt skript uten attributter, vil nettleseren kjøre utvidelsen før jQuery og skjemaet vil ryke. Praktisk råd: start meddeferfor dine egne temaskripter. Ikke rør jQuery før du har testet hver eneste utvidelse på nettstedet.
Hva du bør bruke på et produksjonsnettsted i 2026
Hvis serveren kjører WordPress 6.3 eller nyere, kun den native metoden. Ren kode, beskyttelse mot avhengighetskonflikter, kjernestøtte. Start med defer for alle temaskripter og kritisk viktige utvidelser; reserver async for analyse og tredjeparts widgets.
Hvis versjonen er under 6.3, bruk script_loader_tag-filteret med en array av handles. Det har fungert i et tiår, ingenting å ødelegge. Det eneste det ikke kan gjøre er å automatisk sjekke avhengighetstreet, så legg til skripter i arrayen ett om gangen og sjekk nettstedet etter hvert.
Og viktigst av alt: ingen metode erstatter revisjon av selve skriptene. Hvis en galleriutvidelse kobler til 15 filer bare for å vise tre bilder, vil verken defer eller async hjelpe radikalt. Lastoptimalisering starter med spørsmålet «er dette skriptet i det hele tatt nødvendig», og først deretter, «hvordan skal det lastes».
🔗 Offisiell WordPress 6.3-dokumentasjon, Script Loading Strategies



