Make WordPress Core

Opened 13 years ago

Closed 9 years ago

#16343 closed enhancement (maybelater)

API for WP_Scripts: allow async loading, version checks

Reported by: jltallon's profile jltallon Owned by:
Milestone: Priority: normal
Severity: normal Version:
Component: Script Loader Keywords: needs-patch
Focuses: performance Cc:


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');

(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 (9)

#1 @jltallon
13 years ago

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

#2 @mikeschinkel
13 years ago

  • Cc mikeschinkel@… added

#3 @ericmann
13 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.

#4 @jltallon
13 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 = '';
          $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 = '';
        	$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.

Last edited 13 years ago by nacin (previous) (diff)

#5 @mikeschinkel
13 years ago

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

#6 @jltallon
13 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.

#7 @scribu
13 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.

#8 @nacin
10 years ago

  • Component changed from Performance to Script Loader
  • Focuses performance added

#9 @chriscct7
9 years ago

  • Milestone Future Release deleted
  • Resolution set to maybelater
  • Severity changed from minor to normal
  • Status changed from assigned to closed

Closing as maybelater. Complete lack of interest on the feature on the ticket over the last 5 years. Feel free to reopen when more interest re-emerges (particularly if there's a patch)

Note: See TracTickets for help on using tickets.