WordPress.org

Make WordPress Core

Opened 14 months ago

Last modified 6 months ago

#40731 reviewing enhancement

locate_template() performance improvement

Reported by: danielhuesken Owned by: johnbillion
Milestone: 5.0 Priority: normal
Severity: normal Version:
Component: Themes Keywords: has-patch
Focuses: template, performance Cc:

Description

If the theme uses massive the *_template functions it can come to a slow performance because the the files will be searched again and again.

We can improve the performance if we use a static cache like this:

function locate_template($template_names, $load = false, $require_once = true ) {
	static $template_cache;
	
	$located = '';
	foreach ( (array) $template_names as $template_name ) {
		if ( !$template_name )
			continue;
		if ( $template_cache[$template_name] ) {
			$located = $template_cache[$template_name];
			break;
		}
		if ( isset( $template_cache[$template_name] ) && ! $template_cache[$template_name] )
			continue;
		if ( file_exists(STYLESHEETPATH . '/' . $template_name)) {
			$located = STYLESHEETPATH . '/' . $template_name;
			$template_cache[$template_name] = $located;
			break;
		} elseif ( file_exists(TEMPLATEPATH . '/' . $template_name) ) {
			$located = TEMPLATEPATH . '/' . $template_name;
			$template_cache[$template_name] = $located;
			break;
		} elseif ( file_exists( ABSPATH . WPINC . '/theme-compat/' . $template_name ) ) {
			$located = ABSPATH . WPINC . '/theme-compat/' . $template_name;
			$template_cache[$template_name] = $located;
			break;
		}
		$template_cache[$template_name] = false;
	}

	if ( $load && '' != $located )
		load_template( $located, $require_once );

	return $located;
} 

Attachments (1)

40731.patch (1.6 KB) - added by danielhuesken 13 months ago.

Download all attachments as: .zip

Change History (10)

#1 @danielhuesken
13 months ago

  • Keywords dev-feedback added

#2 @danielhuesken
13 months ago

  • Keywords has-patch added

#3 @danielhuesken
13 months ago

  • Version 4.6.4 deleted

#4 @SergeyBiryukov
13 months ago

  • Summary changed from locate_template() preformance improvment to locate_template() performance improvement

#5 follow-up: @johnbillion
12 months ago

  • Keywords reporter-feedback added; dev-feedback removed

Thanks for the patch @danielhuesken.

Can you let us know in what situation this would improve performance please? It appears that performance is only improved with repeated calls to locate templates of the same name. Is this is common occurrence?

#6 @danielhuesken
12 months ago

Yes. If you have the same template for a post and you have a post list, that the template will be located every time again and the file_exists() calls will be many.

In our case we have WooCommerce and Products and in the product a plugin will do many things with templates that must be located every time again, with the expensive file_exits(). On that project is a page where the load will be increased by 1.5 seconds with this change.

I could see the calls in a xdebug profile.

#7 in reply to: ↑ 5 @Biont
11 months ago

Replying to johnbillion:

Can you let us know in what situation this would improve performance please? It appears that performance is only improved with repeated calls to locate templates of the same name. Is this is common occurrence?

This is definetely common. I routinely build wrappers for template functions to cache all those filesystem accesses wherever I can. A proper system-wide would speed up complex themes noticeably - and practically "for free". While this issue does not rank among the worst offenders when looking at an average xdebug profile, it certainly does show up an it's low-hanging fruit that's easy to tackle.

#8 @johnbillion
6 months ago

  • Keywords reporter-feedback removed
  • Milestone changed from Awaiting Review to 5.0
  • Owner set to johnbillion
  • Status changed from new to reviewing

#9 @dd32
6 months ago

Just wanted to note, that while this may speed things up ever so slightly, file_exists() calls are already internally cached by both PHP and the underlying filesystem and subsequent calls to the same file_exists() calls should return significantly faster than the initial call.

Note: See TracTickets for help on using tickets.