WordPress.org

Make WordPress Core

Opened 3 years ago

Last modified 3 months ago

#16343 assigned enhancement

API for WP_Scripts: allow async loading, version checks

Reported by: jltallon Owned by:
Milestone: Future Release Priority: normal
Severity: minor Version:
Component: Script Loader Keywords: needs-patch
Focuses: performance Cc:

Description

When developping a theme lately, I have found myself in the need of directly accesing the internals of the WP_Scripts class. I feel the funcionality I need might well help other developers.

Use cases:

1.- Asynchronously load a (JS) script loaded by a/another plugin

When loading a certain page, we needed to asynchronously load some (relatively heavy) scripts which are only seldom used. In order to keep page rendering fast, we only load them on demand, after the page frame has been rendered.
In order to avoid having to bundle (potentially conflicting versions) scripts in every plugin and prevent duplicate loading, I suggest adding an API which would enable querying the source (as used by 'scripts-loader')

2.- Version checks for loaded scripts

For high-performance sites, it might be useful to load a Google (or some other CDN) -provided jQuery et al ---which the user might already have cached--- instead of the bundled one, as long as it is the same version.

Code example:

$ver = $wp_scripts->version('jquery');
wp_unregister_script('jquery');
wp_register_script('jquery',"http://ajax.googleapis.com/jquery/$ver/jquery.min.js",false,$ver);

(needs discussion)

I can provide the code (or the patch against Core) when the solution is decided (or soonish, if a proof-of-concept is needed)
If WP 3.2 is going to finally be PHP 5.2+, I'd rather basically rewrite WP_Scripts (and/or WP_Dependencies).

Change History (8)

comment:1 jltallon3 years ago

  • Cc jltallon added
  • Owner jltallon deleted
  • Status changed from new to assigned

comment:2 mikeschinkel3 years ago

  • Cc mikeschinkel@… added

comment:3 ericmann3 years ago

I can see the potential need for #1. Though you already have a solution for #2 (unregister the packaged version of jQuery and register your own from a CDN). So I'm not sure what you're asking for there.

Though if you already have an idea of how you'd like to see #1 implemented, it would be beneficial to the discussion to see at least your proof-of-concept code. It makes it easier to understand an idea and discuss both it's implementation and implications if we can all see for certain what you're talking about.

comment:4 jltallon3 years ago

public static function scriptSrc($handle)
{

global $wp_scripts;

if ( !is_a($wp_scripts, 'WP_Scripts') )
{

$wp_scripts = new WP_Scripts();
return 'ERROR';

}


if ( !isset($wp_scripts->registered[$handle]) )

return ; script not registered


$item =& $wp_scripts->registered[$handle];
$wps =& $wp_scripts;


Code from WP_Scripts
if ( null === $item->ver )

$ver = ;

else

$ver = $item->ver ? $item->ver : $wps->default_version;


if ( isset($wps->args[$handle]) )

$ver = $ver ? $ver.'&'.$wps->args[$handle] : $wps->args[$handle];


$src = $item->src;
if ( !preg_match('|https?:|', $src) && ! ( $wps->content_url && 0 === strpos($src, $wps->content_url) ) )

$src = $wps->base_url . $src;

if ( !empty($ver) )
$src = add_query_arg('ver', $ver, $src);


$src = esc_url(apply_filters( 'script_loader_src', $src, $handle ));

return "{$src}?$ver";

}

public static function scriptVer($handle)

{

global $wp_scripts;

if ( !is_a($wp_scripts, 'WP_Scripts') )
{

$wp_scripts = new WP_Scripts();
return 'ERROR';

}


if ( !isset($wp_scripts->registered[$handle]) )

return false; script not registered


$item =& $wp_scripts->registered[$handle];
if ( null === $item->ver )

$ver = ;

else

$ver = $item->ver ? $item->ver : $wp_scripts->default_version;

return $ver;

}

(these would be much better as members of the WP_Scripts class -- I'm only abusing the fact that PHP4-style classes lack any protection for their members whatsoever)

Use case for #2: "hotlink" *precisely the same* version that WP would have used, in order to ensure compatibility (and also to allow plugins check for version mismatches)
For example, I have a plugin which loads the components of jQueryUI which are not bundled with WP, for use by other components (plugins and theme). When a certain (or more recent) version of a script is required, plugins can check for potential conflicts.
e.g.: WP 3.0's admin scripts don't play well with the "stock" version of jQuery 1.4.2 / jQueryUI 1.8.6. With WP 3.1rc, however, the bundled version of jQuery is perfectly fine.

Version 0, edited 3 years ago by jltallon (next)

comment:5 mikeschinkel3 years ago

@jltallon - FYI, you'll get better traction is you attach the code as a patch.

comment:6 jltallon3 years ago

Thanks. This is just a quick copy-and-paste of what we are doing right now.
Considering that WP 3.2 is going to be PHP5, we could certainly do better.

Moreover, proper wrapper functions would be required to make this really useful.

Now that this is considered useful by others, it's worth preparing a full-fledged patch.
Thanks.

comment:7 scribu3 years ago

  • Keywords needs-patch added; WP_Scripts async-load cache-friendliness removed
  • Milestone changed from Awaiting Review to Future Release

I agree that a function for retrieving the src of bundled JS files would be useful.

comment:8 nacin3 months ago

  • Component changed from Performance to Script Loader
  • Focuses performance added
Note: See TracTickets for help on using tickets.