WordPress.org

Make WordPress Core

Opened 16 months ago

Closed 2 months ago

#26111 closed enhancement (fixed)

wp_localize_script array from callback for performance

Reported by: ciantic Owned by: wonderboymusic
Milestone: 4.2 Priority: low
Severity: normal Version: 2.6
Component: Script Loader Keywords: has-patch 2nd-opinion
Focuses: performance Cc:

Description

These days wp_localize_script is being used to shovel all kinds of PHP -> JavaScript data, not just localization, and the performance may become bottleneck. It's recommended to write localize scripts during enequeue scripts action but this is still run every time.

It would be useful for performance to be able to put callback parameter which in turn would return the array, e.g. for my imaginary date_i18n script:

wp_localize_script("date_i18n", "DATE_I18N", null, function () { 
	global $wp_locale;
	$monthNames = array_map(array(&$wp_locale, 'get_month'), range(1, 12));
	$monthNamesShort = array_map(array(&$wp_locale, 'get_month_abbrev'), $monthNames);
	$dayNames = array_map(array(&$wp_locale, 'get_weekday'), range(0, 6));
	$dayNamesShort = array_map(array(&$wp_locale, 'get_weekday_abbrev'), $dayNames);

	return array(
		"month_names" => $monthNames,
		"month_names_short" => $monthNamesShort,
		"day_names" => $dayNames,
		"day_names_short" => $dayNamesShort
	);
});

WordPress could then run the callback only if the script e.g. date_18n is enqueued.

For backwards compatibility it is required to introduce fourth parameter the $l10n_callback for the wp_localize_script, this is why in my example third is null.

I must also note, that since wp_localize_script is being used to pass data to javascript (e.g. retrieving posts from db) one could also introduce a new function like wp_data_script, but this would not be backwards compatible.

Thank you for considering.

Attachments (2)

26111.diff (1.6 KB) - added by jtsternberg 6 months ago.
Pretty simple fix that checks if $l10n argument is callable and call it if so.
26111-2.diff (545 bytes) - added by jtsternberg 2 months ago.
Include script handle and object name for context in callback function

Download all attachments as: .zip

Change History (16)

comment:1 @johnbillion16 months ago

  • Cc johnbillion added
  • Version changed from trunk to 2.6

comment:2 follow-up: @SergeyBiryukov16 months ago

  • Keywords close added

WordPress could then run the callback only if the script e.g. date_18n is enqueued.

You can check if the script is enqueued using wp_script_is():

function date_i18n_callback() {
	...
	return array( ... );
}

function localize_scripts_26111() {
	if ( wp_script_is( 'date_i18n' ) ) {
		wp_localize_script( 'date_i18n', 'DATE_I18N', date_i18n_callback() );
	}
}
add_action( 'wp_enqueue_scripts', 'localize_scripts_26111', 11 );

date_i18n_callback() will only run if 'date_i18n' is enqueued. No changes to wp_localize_script() are needed.

comment:3 in reply to: ↑ 2 @ciantic16 months ago

Neat that it is possible, however this is not very developer friendly way.

Adding a callback to wp_localize_script would make this more usable and provide better performance benefit over time if people start to use it.

Replying to SergeyBiryukov:

WordPress could then run the callback only if the script e.g. date_18n is enqueued.

You can check if the script is enqueued using wp_script_is():

function date_i18n_callback() {
	...
	return array( ... );
}

function localize_scripts_26111() {
	if ( wp_script_is( 'date_i18n' ) ) {
		wp_localize_script( 'date_i18n', 'DATE_I18N', date_i18n_callback() );
	}
}
add_action( 'wp_enqueue_scripts', 'localize_scripts_26111', 11 );

date_i18n_callback() will only run if 'date_i18n' is enqueued. No changes to wp_localize_script() are needed.

comment:4 @nacin13 months ago

  • Component changed from Performance to Script Loader
  • Focuses performance added
  • Priority changed from normal to low

I've wanted to move this (and post type labels) to a closure for a while. We still support PHP 5.2, though. I wouldn't mind adding it so others can benefit from it in their own environments, though it's not much of a priority as it's more than 50% of all WordPress sites.

I'd be happy to consider a patch. I don't think a new parameter is needed. One would only need to check if the passed parameter is an array or a closure, and than handle that internal to WP_Scripts somehow.

comment:5 @wonderboymusic8 months ago

  • Milestone Awaiting Review deleted
  • Resolution set to maybelater
  • Status changed from new to closed

Reopen if anyone is interested and can provide a patch

@jtsternberg6 months ago

Pretty simple fix that checks if $l10n argument is callable and call it if so.

comment:6 @jtsternberg6 months ago

  • Keywords has-patch reporter-feedback added; close removed
  • Resolution maybelater deleted
  • Status changed from closed to reopened

comment:7 @SergeyBiryukov6 months ago

  • Keywords needs-testing added; reporter-feedback removed
  • Milestone set to Awaiting Review

comment:8 @wonderboymusic2 months ago

  • Keywords needs-testing removed
  • Milestone changed from Awaiting Review to 4.2

comment:9 @wonderboymusic2 months ago

  • Owner set to wonderboymusic
  • Resolution set to fixed
  • Status changed from reopened to closed

In 31030:

Allow the 3rd argument to wp_localize_script()/WP_Scripts->localize() to be a callable, allowing data to be lazy-loaded when the script is actually enqueued.

Props jtsternberg.
Fixes #26111.

comment:10 follow-up: @dd322 months ago

Minor suggestion: The function should be called with the script handle, or any other context details about the enqueue.

comment:11 @wonderboymusic2 months ago

  • Resolution fixed deleted
  • Status changed from closed to reopened

comment:12 in reply to: ↑ 10 @jtsternberg2 months ago

Replying to dd32:

Minor suggestion: The function should be called with the script handle, or any other context details about the enqueue.

I'm a bit ashamed I didn't think of that. Patch incoming.

@jtsternberg2 months ago

Include script handle and object name for context in callback function

comment:13 @jtsternberg2 months ago

  • Keywords 2nd-opinion added

comment:14 @wonderboymusic2 months ago

  • Resolution set to fixed
  • Status changed from reopened to closed

In 31033:

After [31030]: if a callable is passed as the 3rd arg to wp_localize_script()/WP_Scripts->localize(), pass $handle and $object_name to the user func when invoking it.

Props jtsternberg.
Fixes #26111.

Note: See TracTickets for help on using tickets.