Opened 2 days ago
Last modified 39 hours ago
#64719 assigned defect (bug)
Optimize themes REST collection request when querying active theme
| Reported by: |
|
Owned by: |
|
|---|---|---|---|
| Milestone: | 7.0 | Priority: | normal |
| Severity: | normal | Version: | 5.0 |
| Component: | REST API | Keywords: | has-patch |
| Focuses: | rest-api, performance | Cc: |
Description
The current implementation of `WP_REST_Themes_Controller#get_items` always calls wp_get_themes, which is documented as "quite expensive, and grows linearly with additional themes". When requesting themes with status=active, we know that we're only interested in the active theme, so it's wasteful to call wp_get_themes and loop over all of the available themes. Instead, we can shortcut and return the current theme directly.
This could have a noticeable performance impact on Gutenberg, which queries active themes in several places, like its `getCurrentTheme` and `__experimentalGetCurrentGlobalStylesId` selectors.
Change History (5)
This ticket was mentioned in PR #11032 on WordPress/wordpress-develop by @aduth.
2 days ago
#1
- Keywords has-patch added
#2
@
2 days ago
- Milestone changed from Awaiting Review to 7.0
- Owner set to aduth
- Status changed from new to assigned
- Type changed from enhancement to defect (bug)
- Version set to 5.0
Re-classifying this as a defect since themes are being wastefully iterated over.
@westonruter commented on PR #11032:
2 days ago
#3
It might be good to add a unit test or assertion to which verifies that when the provided status is just active that only one theme ever is returned:
@aduth commented on PR #11032:
39 hours ago
#4
It might be good to add a unit test or assertion to which verifies that when the provided status is just
activethat only one theme ever is returned:
Yeah, I see there's a fair bit of indirect coverage of status=active because perform_active_theme_request is the primary helper used in the tests and sets this query. Though it could be good to have an explicit test for it, and also to your point about returning a single entry. We could alternatively make the assertion in test_get_items.
I had considering adding test coverage for the specific optimization here, especially after realizing with a695820d9c9ea03d1d4565ebd01b6f6a33cdac9b that I was "doing it wrong" and the condition never actually matched. I decided against it since this kind of change feels very much the "refactor" stage of TDD red-green-refactor optimizing within the bounds of existing test coverage, and that testing the optimization would ultimately lead to mocking or testing the implementation.
@aduth commented on PR #11032:
39 hours ago
#5
I added a test case for active themes request in 6d4f4e60088db8a0817d78336a9e53c95c084ee2 . Although I do feel like there's some redundancy with test_get_items. For example, there are some fields that are returned only for active theme (default_template_part_areas, default_template_types, theme_supports), which is already tested there. I wonder if it would be better to just move the $this->assertEquals( array( 'rest-api' ), wp_list_pluck( $data, 'stylesheet' ) ); into that existing test case to verify the single returned theme.
Updates
WP_REST_Themes_Controller#get_itemsto shortcut returning the current theme when the request explicitly queries for the active theme, avoiding expensive call towp_get_themes.Trac ticket: https://core.trac.wordpress.org/ticket/64719
## Use of AI Tools
No AI was used in the generating any of the code changes here, though I did use Claude Opus 4.6 as part of the research process in investigating whether an optimization was possible.