When testing a Store Locator Plus® for WordPress setup with the base plugin and Premier plugin active…
Google Maps JavaScript API has been loaded directly without loading=async. This can result in suboptimal performance. For best-practice loading patterns please see https://goo.gle/js-api-loading
Reproduction
- Activate the Store Locator Plus® plugin
- Activate the Premier plugin
- Go to Store Locator Plus | Locations on the sidebar menu.
- Open the JavaScript console in the developer mode in the browser.
- Ensure the notification filter in the console is set to “warning” or “all”.
Result
Google API async warning reported.
Expected Result
On the admin pages the Google API should be loaded in asynchronous mode.
Resolution
Updated \SLPlus::nqGoogleMaps to load the script with an async HTML attribute.
Also add loading=async to the Google URL.
This resolved the original issue.
Findings
\SLP_Premier_Admin_Locations::initialize
Calls add_action( ‘admin_enqueue_scripts’, array( $this->slplus, ‘nqGoogleMaps’ ), 9 );
Which calls \SLPlus::nqGoogleMaps when the WordPress admin_enqueue_scripts hook is called.
\SLPlus::nqGoogleMaps
calls \SLPlus::get_google_maps_url which builds the URL.
Only called by the Premier plugin (WordPress/wp-content/plugins/slp-premier)
\SLPlus::get_google_maps_url
is only called by
\SLPlus::enqueue_google_maps_script
\SLPlus::nqGoogleMaps
The \SLPlus class is found at WordPress/wp-content/plugins/store-locator-plus/include/SLPlus.php
Async Scripts
Async is a script tag attribute.
<script async
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&loading=async&callback=initMap">
</script>
That means that WordPress wp_enqueue_script needs to support the async tag.
According to the documentation, as of WordPress 6.3+ there is a strategy argument that can be passed:
Supported strategies are as follows:
- defer
- Added by specifying an array key value pair of
'strategy' => 'defer'to the$argsparameter.- Scripts marked for deferred execution — via the
deferscript attribute — are only executed once the DOM tree has fully loaded (but before theDOMContentLoadedand window load events). Deferred scripts are executed in the same order they were printed/added in the DOM, unlike asynchronous scripts.- async
- Added by specifying an array key value pair of
'strategy' => 'async'to the$argsparameter.- Scripts marked for asynchronous execution — via the
asyncscript attribute — are executed as soon as they are loaded by the browser. Asynchronous scripts do not have a guaranteed execution order, as script B (although added to the DOM after script A) may execute first given that it may complete loading prior to script A. Such scripts may execute either before the DOM has been fully constructed or after theDOMContentLoadedeven