Make WordPress Core

Opened 3 years ago

Closed 3 years ago

#54844 closed defect (bug) (fixed)

Unnecessary database queries when a block theme isn't in use

Reported by: johnbillion's profile johnbillion Owned by: audrasjb's profile audrasjb
Milestone: 5.9.1 Priority: normal
Severity: normal Version: 5.8
Component: Query Keywords: has-patch fixed-major
Focuses: template, performance Cc:

Description

When a standard theme is in use (not a block theme) database queries to fetch wp_template post types are still performed by get_block_templates() even though there will be no templates associated with a non-block theme. These queries are unnecessary and should be avoided.

Steps to reproduce:

  • Switch to the Twenty Twenty-One theme, which is not a block theme
  • Visit the home page
  • Using a debugging tool such as Query Monitor, observe that several database queries for wp_template post types are performed
  • As the theme is not a block template, observe that the queries all contain a AND ( 0 = 1 ) clause because there are no wp_theme terms for the theme

Introduced in 5.8.

The cause is the unconditional call to locate_block_template() inside get_query_template() (which ultimately calls get_block_templates()). This function should only be called if the theme is a block theme.

Change History (24)

#1 @ianatkins
3 years ago

Came here to note the same.

Had revoked theme support but it has no impact.

remove_theme_support( 'block-templates' )

#2 @Mamaduka
3 years ago

Pinging @costdev, I think your patch for #54910 includes a fix for this.

What do you think about cherry-picking get_query_template change into separate PR?

#3 @costdev
3 years ago

  • Milestone changed from Future Release to 5.9.1

@Mamaduka You're right!

What do you think about cherry-picking get_query_template change into separate PR?

Sounds good, I'll do that now.

I'll move this ticket to the 5.9.1 milestone for consideration.

This ticket was mentioned in PR #2256 on WordPress/wordpress-develop by costdev.


3 years ago
#4

  • Keywords has-patch added; needs-patch removed

Check that the theme is a block theme before calling locate_block_template() in get_query_template().

This change:

  • improves performance for classic themes by removing an unnecessary query.
  • fixes an issue where a classic theme would show "Empty template: Index" on the frontend when an empty (block-)templates/index.html file exists.

Trac ticket: https://core.trac.wordpress.org/ticket/54844

#5 @Mamaduka
3 years ago

Thanks for the quick follow-up, @costdev.

I think we might want to include get_theme_support( 'block-templates' ) in condition. The classic themes can also support block templates since #53176.

Cc @bernhard-reiter.

#6 @costdev
3 years ago

Good point! - PR updated.

#7 @manfcarlo
3 years ago

It looks like locate_block_template is actually called twice during get_query_template? Once directly and then again through the filter. Not sure what is happening there.

#8 follow-up: @costdev
3 years ago

Nicely spotted @manfcarlo. I'm not sure what's going on there either.


locate_block_template() is called in:

  1. get_query_template()
  2. _add_template_loader_filters()

Reviewing checks:

  • get_query_template() currently performs no checks.
  • _add_template_loader_filters() checks if the theme supports block-templates.
  • the_block_template_skip_link does a check for block-templates support which is documented as checking for a block theme. This may just need a doc change, but noting it here as it performs a check.
  • Related ticket #54917 proposes to add a block-templates check directly to locate_block_template() and has a patch.

In an effort to standardize the checks here, I think these functions should be evaluated when no checks exist, and existing checks should be evaluated to determine whether current_theme_supports( 'block-templates' ) is enough, or if is_wp_block_theme() should be added as well.


Both this ticket and #54917 aim to achieve the same thing, but #54917 is specifically targeting one instance.

As this ticket existed first, provides the reasons for a change, details the impact of not making a change, and its title applies to the whole codebase rather than one instance, we can either consider this an umbrella ticket, or move the patch from #54917 to here and close it as a duplicate.

Thoughts?

#9 @costdev
3 years ago

Pinging @bernhard-reiter as having done much of the work in #53176 for more insight on which checks may be applicable in each location.

#10 @dolphingg
3 years ago

@costdev Suggestion to use current_theme_supports instead of get_theme_support because the latter will return an array if the condition is true.

@sresok and me were testing your patch on version 5.8 and came to the conclusion that the function wp_is_block_theme() was introduced in WordPress version 5.9.

Can we change the version mentioned in this ticket?

Last edited 3 years ago by dolphingg (previous) (diff)

#11 @johnbillion
3 years ago

These queries occur in WP 5.8 too, see my notes at the bottom of the ticket description.

#12 @costdev
3 years ago

Hi @dolphingg,

I'm not opposed to changing get_theme_support to current_theme_supports (I've used current_ in the comments above), however I would highlight two things here:

  1. get_theme_support() returns array on success, which is a truthy value. In this sense, there is no difference when used in the context of a truthy condition.
  2. current_theme_supports() performs an additional check prior to checking if $_wp_theme_features[ $feature ] ) is set, so using get_theme_support() in an if statement should be slightly more performant.

Having said that, using get_theme_support() is a micro-optimization, which isn't necessarily a bad thing given the subject of the ticket, but current_theme_supports() is better for readability in this context.

I'm happy to go with the consensus on this.

In terms of the Version, this refers to when the unnecessary queries were introduced, not when a potential solution, i.e wp_is_block_theme(), became available.

#13 in reply to: ↑ 8 @manfcarlo
3 years ago

Replying to costdev:

Both this ticket and #54917 aim to achieve the same thing, but #54917 is specifically targeting one instance.

As this ticket existed first, provides the reasons for a change, details the impact of not making a change, and its title applies to the whole codebase rather than one instance, we can either consider this an umbrella ticket, or move the patch from #54917 to here and close it as a duplicate.

Thoughts?

The two tickets look like duplicates to me. I don't mind which one is closed, but I do prefer the patch over there to the one here. If the theme does not support block templates, it seems appropriate for locate_block_template to refuse to change the template regardless of the context in which it's called.

#14 @Mamaduka
3 years ago

I think we can check if the theme supports block-templates. They are always supported with Block Themes. See https://developer.wordpress.org/reference/functions/wp_enable_block_templates/

#15 @costdev
3 years ago

@Mamaduka Thanks for pointing this out.

Given this, I think we can go ahead and use the fix in PR 2246 from #54917.

I've left a comment on the ticket and PR explaining how to resolve the failing tests so that the fix can be considered for commit.

This ticket was mentioned in Slack in #core by audrasjb. View the logs.


3 years ago

#18 @audrasjb
3 years ago

As per today's bug scrub, let's keep this ticket to track this issue.
Committers: please make sure the following contributors are credited when the patch is comitted: madeinua, kapilpaul.

#19 @audrasjb
3 years ago

#54917 was marked as a duplicate.

#20 @costdev
3 years ago

Also suggest that rafiahmedd is credited too.

#21 @audrasjb
3 years ago

  • Owner set to audrasjb
  • Resolution set to fixed
  • Status changed from new to closed

In 52697:

Query: Check if the theme supports block-templates before calling locate_block_template() in get_query_template().

This change improves performance for classic themes by removing an unnecessary query and fixes an issue where a classic theme would show "Empty template: Index" on the frontend when an empty (block-)templates/index.html file exists.

Props johnbillion, ianatkins, Mamaduka, costdev, manfcarlo, dolphingg, audrasjb, madeinua, kapilpaul, rafiahmedd, SergeyBiryukov.
Fixes #54844.

#22 @audrasjb
3 years ago

  • Resolution fixed deleted
  • Status changed from closed to reopened

Reopening for backport consideration.

#23 @audrasjb
3 years ago

  • Keywords fixed-major added

#24 @audrasjb
3 years ago

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

In 52716:

Query: Check if the theme supports block-templates before calling locate_block_template() in get_query_template().

This change improves performance for classic themes by removing an unnecessary query and fixes an issue where a classic theme would show "Empty template: Index" on the frontend when an empty (block-)templates/index.html file exists.

Props johnbillion, ianatkins, Mamaduka, costdev, manfcarlo, dolphingg, audrasjb, madeinua, kapilpaul, rafiahmedd, SergeyBiryukov.
Merges [52697] to the 5.9 branch.
Fixes #54844.

Note: See TracTickets for help on using tickets.