WordPress.org

Make WordPress Core

Opened 2 years ago

Last modified 8 weeks ago

#40731 reviewing enhancement

locate_template() performance improvement

Reported by: danielhuesken Owned by:
Milestone: Future Release Priority: normal
Severity: normal Version:
Component: Themes Keywords: has-patch needs-testing
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 2 years ago.

Download all attachments as: .zip

Change History (13)

#1 @danielhuesken
2 years ago

  • Keywords dev-feedback added

@danielhuesken
2 years ago

#2 @danielhuesken
2 years ago

  • Keywords has-patch added

#3 @danielhuesken
2 years ago

  • Version 4.6.4 deleted

#4 @SergeyBiryukov
2 years ago

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

#5 follow-up: @johnbillion
2 years 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
2 years 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
2 years 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
20 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
20 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.

#10 @johnbillion
9 months ago

  • Milestone changed from 5.0 to 5.1

#11 @pento
6 months ago

  • Keywords needs-testing added
  • Milestone changed from 5.1 to Future Release

Given @dd32's comment, I'd like to see some performance measurements on modern PHP versions that show a significant boost from 40731.patch.

#12 @johnbillion
8 weeks ago

  • Owner johnbillion deleted
Note: See TracTickets for help on using tickets.