
⚡ Hur du lägger till defer och async för WordPress-skript i function.php
Sidor laddar långsamt, Google PageSpeed Insights visar orange varningar och kunden frågar: "varför är sajten seg?" Nio gånger av tio är grundorsaken att JavaScript blockerar renderingen. Webbläsaren når en <script>, slutar bygga DOM:en, laddar och kör skriptet, och fortsätter först därefter. På en modern sajt med ett dussin tillägg blir denna fördröjning sekunder.
WordPress erbjöd länge inget standardiserat sätt att styra skriptinläsning. Utvecklare tog till workarounds: filtrera script_loader_tag, patcha utdata via clean_url eller till och med skriva egna walkers för WP_Scripts. Men i och med lanseringen av WordPress 6.3 förändrades situationen radikalt, och nu har vi ett rent och understött sätt att lägga till defer eller async på vilket skript som helst utan ett enda hack.
Nedan finns två fungerande metoder: den moderna, inbyggda metoden (WP 6.3+) och det beprövade script_loader_tag-filtret (WP 4.1+). Båda har testats i skarpa projekt, och båda bevarar beroendeköns integritet.
💡 Snabb översikt:
- Förstå skillnaden mellan
deferochasyncoch när du ska använda respektive, detta avgör om funktionaliteten går sönder efter optimering - Använd den inbyggda WordPress 6.3+-metoden via
wp_enqueue_script()med parameternstrategy, den renaste metoden som bevarar exekveringsordningen - Om sajten kör en version under 6.3, använd
script_loader_tag-filtret med en array av handtag, detta fungerar från och med WordPress 4.1 - För flera skript, samla handtagen i en array och loopa igenom den, ett filter för alla skript istället för copy-paste
Vad defer och async är och när du ska använda dem
När en webbläsare stöter på en vanlig <script>-tagg gör den tre saker i sekvens: slutar tolka HTML, laddar skriptet, kör det. Först därefter återgår den till HTML:en. På en sida med fem skript i <head> innebär detta att användaren ser en vit skärm medan det sista kommentarspluginet laddar, trots att själva inlägget hade kunnat renderas för länge sedan.
Attributen defer och async löser detta problem, men fungerar olika:
Attribut | När det laddas | När det körs | Exekveringsordning |
|---|---|---|---|
(inget) | Blockerar tolkning omedelbart | Omedelbart efter laddning | I DOM-ordning |
| Parallellt med tolkning | Efter att DOM laddats helt | I DOM-ordning |
| Parallellt med tolkning | Omedelbart efter laddning | Den som laddar först |
Defer är arbetshästen för de flesta scenarier. Skriptet laddas parallellt med HTML och körs först när DOM:en är helt uppbyggd. Ordningen bevaras: skript A körs före skript B, även om B laddade snabbare. Detta är kritiskt för jQuery och allt som är beroende av det.
Async är ett verktyg för oberoende skript. Analys, annonser, sociala medier-widgets: de behöver inte DOM:en, de bryr sig inte om ordning, de behöver bara köras så snart som möjligt. Men om du sätter async på ett skript som är beroende av jQuery får du troligen $ is not defined.
Enkel regel: skriptet är beroende av andra skript eller av DOM:en → defer. Skriptet är helt fristående → async. Vid tveksamhet, börja alltid med defer.
Metod 1: Inbyggd WordPress 6.3+-metod
Sedan juli 2023 finns en ny mekanism i WordPress core. Funktionerna wp_register_script() och wp_enqueue_script() fick en överlagrad femte parameter $args, en array där du kan ange laddningsstrategi. Inga filter, ingen strängmagi, ingen risk att förstöra beroendeordningen.
Grundläggande syntax för 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 );
För async, samma mekanik:
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 );
Nyckeln in_footer inuti arrayen fungerar precis som den gamla booleska parametern: true placerar skriptet i sidfoten, false i <head>. För defer sätter du vanligtvis true (skriptet väntar ändå på DOM, ingen poäng att ladda det tidigt), för async det som fungerar bäst.
Den största fördelen med den inbyggda metoden är att core själv kontrollerar beroendeträdet. Om skript A med defer är beroende av skript B, och B är registrerat utan strategi (blockerande), kommer WordPress inte att förstöra din sajt: det nedgraderar automatiskt skript A:s strategi till blockerande. När du använder script_loader_tag saknar du detta skydd, filtret infogar helt enkelt attributet utan att titta på beroenden.
Viktigt: arrayen $args dök upp i WordPress 6.3. Om ett tema eller tillägg måste fungera på lägre versioner, använd metod 2 eller lägg till en kontroll:
1 if ( version_compare( $GLOBALS['wp_version'], '6.3', '>=' ) ) { 2 // native method 3 } else { 4 // script_loader_tag filter 5 }
Metod 2: script_loader_tag-filter (WordPress 4.1+)
Om sajten kör en version under 6.3 eller du behöver upprätthålla bakåtkompatibilitet, använd det beprövade script_loader_tag-filtret. Det har funnits sedan WordPress 4.1 och fungerar fortfarande felfritt.
Filtret körs precis innan <script>-taggen skrivs ut till HTML, du tar emot den färdiga taggsträngen, skripthandtaget och filsökvägen, och kan ersätta src med defer="defer" src eller async="async" src.
Enskilt 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 placeras i det aktiva temats functions.php eller, mer korrekt, i ett separat snippet-plugin som Code Snippets eller WPCode. Om du lägger den i ett barntemas functions.php kommer skripten att bli blockerande igen när du byter tema, och du märker det inte omedelbart.
Skripthandtaget är den första parameter du skickade till wp_register_script() eller wp_enqueue_script(). Det är detta som står i if-villkoret. Gissa inte handtaget, öppna källkoden för tillägget eller temat och hitta anropet till wp_enqueue_script.
Defer och async för flera skript
Att lägga till ett filter per skript är en väg till uppsvälld functions.php och copy-paste-fel. Den rätta lösningen: en array med handtag och 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);
För async ändras bara attributet och arraynamnet:
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);
Båda filtren kan krokas på samtidigt, defer på dina skript, async på tredjepartsspårare. De fungerar oberoende och krockar inte.
Praktiskt exempel: Google Maps API
Google Maps är en klassisk kandidat för defer. Kartan ligger vanligtvis i sidfoten på kontaktsidan, skriptet drar in 100+ KB, och användaren behöver inte kartan direkt. Dessutom är själva API:et inte beroende av andra sidskript, ett idealfall.
Anslut och defer:a:
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');
Samma 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);
Efter att du installerat någon av varianterna, kontrollera definitivt kartan på kontaktsidan. Öppna webbläsarens konsol (F12), säkerställ att det inte finns några JavaScript-fel och att kartan renderades korrekt. Om du får ett fel som initMap is not a function betyder det att ditt initialiseringsskript också måste märkas som defer och placeras strikt efter API-anslutningen.
Hur du verifierar att defer och async fungerar
Efter implementation kommer verifiering. Utan den vet du inte om optimeringen fungerade eller bara ligger som död kod.
Öppna sidkällan (Ctrl+U) och hitta dina skript. <script>-taggen ska ha attributen:
1 <script defer="defer" src="/wp-content/themes/my-theme/js/my-script.js"></script>
Om det inte finns några attribut, kontrollera om handtaget i filtret matchar det faktiska skripthandtaget. Vanligt misstag: i wp_enqueue_script är handtaget my-plugin-frontend, men i filtret är det my_plugin_frontend. Bindestreck mot understreck, och filtret hoppar tyst över skriptet.
Sista touchen, Google PageSpeed Insights eller Lighthouse i fliken Audits i utvecklarverktygen. Sektionen "Eliminera renderingsblockerande resurser" bör visa förbättring. Specifik vinst beror på antalet och storleken på skript, men för en typisk WordPress-sajt med 5-7 tillägg är en 40-60% minskning av blockerande JavaScript ett uppnåeligt resultat.
⁉️🤔 Vanliga frågor
Kan jag använda både defer och async på ett skript?
Nej. Om du anger båda attributen samtidigt ignorerar webbläsaren
deferoch kör skriptet somasync. Detta beteende är inbyggt i HTML-specifikationen,asynctar alltid prioritet. Välj ett baserat på om exekveringsordningen spelar roll.
Vad gör jag om skriptet slutade fungera efter att jag lagt till defer?
Troligen förväntar sig skriptet att DOM:en inte är uppbyggd än och försöker manipulera element som inte finns vid exekveringstillfället. Ersätt
defermed standard blockerad laddning för just det skriptet. Eller wrappa skriptkoden iDOMContentLoaded, då kan det fungera meddeferutan fel. Det andra alternativet är att föredra: du behåller optimeringen och fixar kompatibiliteten.
Vad är skillnaden mellan defer och att flytta skriptet till sidfoten via wp_enqueue_script med $in_footer = true?
$in_footer = trueflyttar bara<script>-taggen från<head>till slutet av<body>. Skriptet blockerar fortfarande rendering, bara senare.deferladdas parallellt med HTML-tolkning och körs strikt efter att DOM:en är uppbyggd. Kombinerad användning (in_footer => true+strategy => 'defer') ger maximal effekt: skriptet i sidfoten fördröjer inte första rendering, och defer garanterar att det inte heller blockerar slutrenderingen.
Bör jag uppdatera WordPress till 6.3 bara för den inbyggda metoden?
Om sajten är på version 6.2 eller äldre är en uppdatering värd besväret inte bara för
strategy. WordPress 6.3 stängde dussintals sårbarheter och medförde prestandaförbättringar i core. Men om en uppdatering är omöjlig av någon anledning fungerarscript_loader_tag-filtret helt tillförlitligt från version 4.1, släppt 2014. Du förlorar ingenting på att använda det.
Hur är det med jQuery, defer eller låta det vara som det är?
jQuery bör laddas med
deferom alla beroende skript också är märktadefer. Problemet är att WordPress-tillägg extremt sällan hanterar attribut för sina skript. Om du sätterdeferpå jQuery medan ett kontaktformulärstillägg ansluter sitt skript utan attribut, kommer webbläsaren att köra tillägget före jQuery och formuläret går sönder. Praktiskt råd: börja meddeferför dina egna temaskript. Rör inte jQuery förrän du har testat varje tillägg på sajten.
Vad du ska använda på en produktionssajt 2026
Om servern kör WordPress 6.3 eller nyare, endast den inbyggda metoden. Ren kod, skydd mot beroendekonflikter, core-support. Börja med defer för alla temaskript och kritiskt viktiga tillägg; reservera async för analys och tredjepartswidgets.
Om versionen är under 6.3, script_loader_tag-filtret med en array av handtag. Det har fungerat i ett decennium, inget att ha sönder. Det enda det inte kan göra är att automatiskt kontrollera beroendeträdet, så lägg till skript i arrayen ett i taget och kontrollera sajten efter varje.
Och viktigast av allt: ingen metod ersätter granskning av själva skripten. Om ett galleri-tillägg ansluter 15 filer bara för att visa tre bilder, kommer varken defer eller async att hjälpa radikalt. Laddningsoptimering börjar med frågan "behövs det här skriptet överhuvudtaget", och först därefter, "hur ska det laddas."
🔗 Officiell WordPress 6.3-dokumentation, Script Loading Strategies



