Make WordPress Core

Opened 2 years ago

Closed 2 years ago

Last modified 2 years ago

#56745 closed defect (bug) (fixed)

Performance/Bug: calling array_map repeatedly inside WP_Theme_JSON::get_default_slugs is a bottleneck for page-loads.

Reported by: aristath's profile aristath Owned by: sergeybiryukov's profile SergeyBiryukov
Milestone: 6.1 Priority: normal
Severity: normal Version: 6.1
Component: Themes Keywords: has-patch
Focuses: performance Cc:

Description

Issue discovered when running profiling using Xdebug & webgrind. Replacing the array_map call with a simple foreach loop improves the page-load speed significantly.
More info in the PR below.

Change History (8)

This ticket was mentioned in PR #3410 on WordPress/wordpress-develop by aristath.


2 years ago
#1

  • Keywords has-patch added

When loading a page on the frontend, the biggest performance bottleneck right now (on the PHP side) is WP_Theme_JSON->merge. Analysing the data a bit more, it becomes evident that WP_Theme_JSON::get_default_slugs is the part of that function that takes most of the resources and time (see screenshot below)

https://i0.wp.com/user-images.githubusercontent.com/588688/194285929-847418a1-3134-48de-a090-51f18df461fe.png

Further analysis of the WP_Theme_JSON::get_default_slugs method reveals that array_map() is the call that slows it down:

https://i0.wp.com/user-images.githubusercontent.com/588688/194286171-25bb9589-9599-4e6c-b855-4831dbb7e48e.png

This PR replaces array_map with a simple foreach loop. The end result is the same, and processing happens a lot faster:

https://i0.wp.com/user-images.githubusercontent.com/588688/194286421-80d3f867-beb8-42ed-806e-1f2e1733ae44.png

Notes:
Screenshots above shown with % values. So overall this changes makes each page-load ~1% faster.
In all tests, the actual page-load was reduced from ~6300ms to ~5900
Tests were performed on a new WP installation with no plugins activated, using the twentytwentythree theme.
Reports generated using Xdebug & webgrind.

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

#2 @SergeyBiryukov
2 years ago

  • Component changed from General to Themes

#3 @SergeyBiryukov
2 years ago

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

In 54398:

Themes: Replace array_map() usage in WP_Theme_JSON::get_default_slugs().

When loading a page on the frontend using Xdebug & Webgrind, with the Twenty Twenty-Three theme and no plugins activated, the biggest performance bottleneck currently (on the PHP side) is WP_Theme_JSON::merge(). Analysing the data a bit more, it became evident that WP_Theme_JSON::get_default_slugs() is the part of that method which takes most of the resources and time.

Further analysis of the method revealed that array_map() was the call that slowed it down.

This commit replaces the array_map() call with a simple foreach loop, improving page load speed significantly.

Follow-up to [52275], [52364].

Props aristath.
Fixes #56745.

SergeyBiryukov commented on PR #3410:


2 years ago
#4

Thanks for the PR! Merged in r54398.

jrfnl commented on PR #3410:


2 years ago
#5

I'm honestly surprised that array_merge() being called in a loop (😱) wasn't the culprit...

aristath commented on PR #3410:


2 years ago
#6

I'm honestly surprised that array_merge() being called in a loop (😱) wasn't the culprit...

The WP_Theme_JSON->merge call is still the most expensive call during a page-load. We'll definitely need to refactor some things there, I'll keep looking for ways to optimize that code 😅
I agree though, all those expensive function calls inside loops (and sometimes deep-nested loops of a loop of a loop) are... "less than ideal".

jrfnl commented on PR #3410:


2 years ago
#7

@aristath Just based on array_merge() being used in a loop I can think of a few things, but I'd need to study the code a little more to be sure. Might be an interesting one to do a pairing session on between the two of us ? (in a few weeks, still pretty busy now)

aristath commented on PR #3410:


2 years ago
#8

Might be an interesting one to do a pairing session on between the two of us?

Definitely! Ping me when you're available and we'll do that 👍

Note: See TracTickets for help on using tickets.