Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize compute_style_properties by reducing the number of iterations it performs #51983

Closed

Conversation

oandregal
Copy link
Member

@oandregal oandregal commented Jun 27, 2023

Related #45171

What?

This PR improves TTFB by improving how WP_Theme_JSON_Gutenberg::compute_style_properties operates.

Why?

The faster, the better.

TTFB using a production environment locally (data):

image

How?

The compute_style_properties method is responsible for converting a "style node" coming from a theme.json structure into a list of CSS declarations.

Input:

array(
  'color' => array(
    'background' => 'background-value',
    'text'              => 'text-value',
  ),
)

Output:

array(
  array( 'name' => 'background-color', 'value' => 'background-value' ),
  array( 'name' => 'color', 'value' => 'text-value' ),
)

To do such conversion, it maintains a map of CSS properties to paths in a "style node" within a theme.json file: PROPERTIES_METADATA. At the time of writing this, there's 54 of them.

The compute_style_properties method iterates over all of them for every input node. As a result, in a theme such as TwentyTwentyThree with 65 style nodes, some code paths are executed 65 * 54 = 3510 times.

This PR updates how compute_style_properties works to iterate over the properties that exist in the input, not over all of them. In a theme such as TwentyTwentyThree this can be less than 3 properties per style node, amounting to 65 * 3 ~= 195 times.

Testing Instructions

Make sure the automated tests pass.

How to reproduce the benchmarks locally:

  • Build the plugin: npm install && npm run build.
  • Create a .wp-env.override.json file with the following contents:
{
        "config": {
                "WP_DEBUG": false,
                "SCRIPT_DEBUG": false
        }
}
  • Run the docker environment: npm run wp-env start.
  • Request the homepage of the theme 250 times: eq 250 | xargs -Iz curl -o /dev/null -H 'Cache-Control: no-cache' -s -w "%{time_starttransfer}\n" http://localhost:8888/ | xclip -selection clipboard.
  • Paste the results into a spreadsheet.

Do the above for each one of the last default themes (TwentyTwenty, TwentyTwentyOne, TwentyTwentyTwo, TwentyTwentyThree) for this branch. Then, do the same using trunk at 72b7d89.

@oandregal oandregal requested a review from spacedmonkey as a code owner June 27, 2023 15:13
@oandregal oandregal self-assigned this Jun 27, 2023
@oandregal oandregal added the [Type] Performance Related to performance efforts label Jun 27, 2023
@spacedmonkey
Copy link
Member

Screenshot 2023-06-27 at 16 44 21 This is from a profile today.

@oandregal oandregal force-pushed the update/compute-style-properties-iterate-over-styles branch from cd8d56c to 10d5c77 Compare June 27, 2023 15:45

foreach ( $properties as $css_property => $value_path ) {
$root_variable_duplicates = array();
foreach ( $properties_to_inspect as $css_property => $value_path ) {
$value = static::get_property_value( $styles, $value_path, $theme_json );

if ( str_starts_with( $css_property, '--wp--style--root--' ) && ( static::ROOT_BLOCK_SELECTOR !== $selector || ! $use_root_padding ) ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if ( str_starts_with( $css_property, '--wp--style--root--' ) && ( static::ROOT_BLOCK_SELECTOR !== $selector || ! $use_root_padding ) ) {
if ( ( static::ROOT_BLOCK_SELECTOR !== $selector || ! $use_root_padding ) && str_starts_with( $css_property, '--wp--style--root--' ) ) {

Changing this line also helps performance.

@spacedmonkey
Copy link
Member

After profile

Screenshot 2023-06-27 at 16 51 28

@github-actions
Copy link

Flaky tests detected in 10d5c77.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/5391880948
📝 Reported issues:

@oandregal
Copy link
Member Author

This is the performance impact for the metrics we track:

image

Locally, I'm not seeing the performance impact I was expecting either:

image

@oandregal
Copy link
Member Author

In profiling, the results are big enough that warranted an investigation:

  • total time improved from 490ms to 400ms.
  • WP_Theme_JSON->get_styles_for_block improved from 46ms to 14ms.
  • WP_Theme_JSON::compute_style_properties improved from 31ms to 8ms.

Before:

image

After:

image

Note:

  • "Incl." in all the time of the function and "Self" is the time attributed to the function excluding the callees
  • "Incl." and "Self" are reported as 10ns. To get the ms, multiply by 10 and divide by 1000000.

@oandregal
Copy link
Member Author

I'm unconvinced this has a real impact, given the benchmark numbers I've shared. I'll close it in a few days, unless someone else wants to review the benchmark I've done, or provide a different one that shows impact. See "How to reproduce the benchmarks locally" section in the issue description.

It sounds like this is one of those cases where the observational cost of profiling reports bigger gains than it actually is.

@oandregal
Copy link
Member Author

@spacedmonkey I presume those screenshots you shared are from a profiling tool, are they? While useful for initial investigations, we cannot count on profiler numbers to show impact on production environments. See how profiling and benchmarking differ in this PR as an example.

@oandregal
Copy link
Member Author

cc @felixarntz This PR doesn't have any urgency. I know your benchmark setup is different from mine, so I was curious to see what your benchmark would report, when you have the time.

@oandregal oandregal closed this Aug 1, 2023
@oandregal oandregal deleted the update/compute-style-properties-iterate-over-styles branch August 1, 2023 10:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Type] Performance Related to performance efforts
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants