Using The Script_Loader_Tag Filter To Add Defer Tag To Scripts
Loading external scripts can block the initial rendering of web pages. The defer attribute allows scripts to load asynchronously without blocking page rendering. Using the WordPress script_loader_tag filter allows theme developers to automatically add the defer attribute to enqueued scripts. This improves performance by preventing rendering blocking while loading essential scripts.
What is the defer Attribute?
The Boolean defer attribute indicates to browsers that the script file should load asynchronously in the background without blocking page rendering. Defer scripts only execute after the entire HTML document has loaded. This allows the browser to prioritize displaying visible content first before executing JavaScript code.
Defer vs Async
Both defer and async achieve non-blocking async script loading. However, defer guarantees executing scripts in the order they appear in the HTML. Async scripts load fully parallel with no guaranteed sequence. Using defer over async ensures dependencies execute properly without errors.
Why Use defer for Scripts?
Adding defer improves page performance and the user experience by preventing render blocking scripts. Benefits include:
- Faster first paint and content display
- Prioritizes visible content over background processes
- Loads scripts asynchronously after parsing
- Executes scripts in proper sequence
When Not to Use defer
Avoid using defer for scripts that need to execute in the initial parsing stage before the DOM loads. Some examples include:
- Scripts that modify early DOM elements
- Script JSON data needed in page body
- Scripts that generate above-the-fold content
Adding defer to Scripts with script_loader_tag
The script_loader_tag filter allows programatically adding attributes like defer to enqueued scripts. This prevents having to edit all script tags manually. Here is how it works:
- Theme setups up script enqueues as normal
- script_loader_tag filter hooks into each script tag output
- Checks if the script source matches enqueue handles
- If match, filter adds defer attribute to tag
- Script loads with defer attribute automatically
Alternate Approaches
There are a couple alternative approaches to adding defer including:
- Manually adding defer to each script tag
- Using JavaScript to add defer after loading
- Defer plugin to handle automatically
The script_loader_tag filter handles adding defer seamlessly without editing individual tags manually. Automating it eliminates the potential for missed tags.
Example: Implement script_loader_tag Filter
Here is example code for implementing the script_loader_tag filter in theme functions.php:
/** * Add defer attribute to enqueued scripts */ function namespace_defer_scripts( $tag, $handle, $src ) { // List of script handles to defer $defer_scripts = array( 'jquery', 'main-script' ); // Check if handle needs defer if ( in_array( $handle, $defer_scripts ) ) { return '' . "\n"; } return $tag; } add_filter( 'script_loader_tag', 'namespace_defer_scripts', 10, 3 );
Breaking down the key parts:
- Filter name script_loader_tag to hook output
- $defer_scripts array lists handles to target
- Check if $handle matches target handles
- If yes, return modified tag with defer added
- Use add_filter to hook in function
This seamlessly adds defer only to the selected enqueued scripts without having to change tags manually. Dynamic and reusable for any enqueues.
Customizing Implementation
Some ways to extend implementation:
- Add/remove script handles to target
- Add logic checks before adding defer
- Use an options setting to control enabled
- Set defer based on script dependencies
Verifying defer Attribute on Scripts
To confirm scripts are loading with the defer attribute from the filter, view the processed source code and check for the defer addition.
Example script tag without defer:
<script type='text/javascript' src='js/script.js'></script>
Example script tag with defer:
<script defer src='js/script.js'></script>
Alternatively, browser developer tools allow inspecting the tag to verify the defer attribute. Script behavior switching to async non-blocking loading confirms functionality.
Debugging Defer Script Issues
If a deferred script causes errors or conflicts, debug steps include:
- Disable filter temporarily
- Test if issues resolve when sync loaded
- If fixed, inspect dependencies and stage execution
- Resolve execution order then re-enable
Potential Issues to Watch Out For
While defer improves performance, there are edge cases where it can cause conflicts including:
Script Dependencies
Deferring scripts can cause issues if dependent scripts load in incorrect order. Watch for errors based on execution sequence.
Early DOM Manipulation
Defer issues may occur if scripts expect to interact with early page elements before fully loading.
Legacy Browser Support
Some older browsers have partial or no support for defer. Test across target browser versions if legacy support is needed.
Thorough script testing helps avoid defer conflicts. Toggle specific handles on/off as needed if issues emerge.
Summary
Intelligently adding defer to scripts by hooking into the script_loader_tag filter streamlines performance optimization. Automating the process with code eliminates tedious manual tag editing one by one. Just activating the filter handles automatically deferring select scripts across all pages.Configured thoughtfully, deferred script loading can greatly accelerate site speed without disruption.