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:

  1. Theme setups up script enqueues as normal
  2. script_loader_tag filter hooks into each script tag output
  3. Checks if the script source matches enqueue handles
  4. If match, filter adds defer attribute to tag
  5. 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:

  1. Filter name script_loader_tag to hook output
  2. $defer_scripts array lists handles to target
  3. Check if $handle matches target handles
  4. If yes, return modified tag with defer added
  5. 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:

  1. Disable filter temporarily
  2. Test if issues resolve when sync loaded
  3. If fixed, inspect dependencies and stage execution
  4. 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.

Leave a Reply

Your email address will not be published. Required fields are marked *