-
Notifications
You must be signed in to change notification settings - Fork 107
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
Implement logic to measure specific hook execution time with Server-Timing controlled by a WP Admin screen #784
Conversation
…iming controlled by a WP Admin screen.
add_action( "load-{$hook_suffix}", 'perflab_load_server_timing_page' ); | ||
} | ||
|
||
return $hook_suffix; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are you returning this for? This is hooked into an action right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, this would only be useful for test coverage, which I'm planning to add.
server-timing/load.php
Outdated
function perflab_sanitize_server_timing_setting( $value ) { | ||
if ( ! is_array( $value ) ) { | ||
return array(); | ||
} | ||
|
||
// Ensure that every element is an indexed array of hook names. | ||
return array_filter( | ||
array_map( | ||
static function( $hooks ) { | ||
if ( ! is_array( $hooks ) ) { | ||
$hooks = explode( "\n", $hooks ); | ||
} | ||
return array_filter( array_map( 'sanitize_key', $hooks ) ); | ||
}, | ||
$value | ||
) | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could do with a unit test IMO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I haven't added unit tests yet, but definitely planning to do so.
Just from looking at the screenshot alone it is not clear what exactly would be measured. Is it the time since the last hook (i.e. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @felixarntz for the PR, If anyone add duplicate value in Actions or Filters then it shows error.
For ex.
init
wp_loaded
init
Thanks @swissspidy @mukeshpanchal27 for the feedback.
I'll work on some test coverage now, mostly relevant for the WP Admin UI. |
server-timing/load.php
Outdated
* Any duplicates across a group of hooks are removed. | ||
*/ | ||
return array_filter( | ||
array_map( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be checking whether the keys are those which are allowed, i.e. benchmarking_actions
and benchmarking_filters
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, updated in 7f99021
server-timing/load.php
Outdated
}, | ||
$hooks | ||
) | ||
) | ||
) | ||
); | ||
}, | ||
$value | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a lot of nesting happening here. Not a problem, but just makes it a bit hard on the eyes. Not a blocker.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reduced the nesting a bit in 7f99021
For some reason when I add a filter to get Server-Timing for, e.g. Notice: Function Perflab_Server_Timing::register_metric was called incorrectly. The method must be called before or during the perflab_server_timing_send_header action. Please see Debugging in WordPress for more information. in /var/www/html/wp-includes/functions.php on line 5865 I don't get it for when I add actions, however. 😕 |
@westonruter That's because the |
Oh, of course. Same as mentioned in #784 (comment). What do you think about the presence of any Server-Timing hooks to automatically cause output buffering to be enabled automatically? That would prevent others from getting tripped up the same way I did. |
@westonruter I think it would be better to have an explicit setting for it. To clarify the limitation when output buffering is not enabled, I have added a message for it in fd41db1 (see also the updated screenshot in the PR description). Once we add a setting control for it, we can consider toggling that with JS based on the checkbox. |
admin/server-timing.php
Outdated
static function() { | ||
?> | ||
<p> | ||
<?php esc_html_e( 'In this section, you can provide hook names to include measurements for them in the Server-Timing header.', 'performance-lab' ); ?> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the Server-Timing
header is not something that should be translated, I'd recommend using sprintf
with a placeholder here (+ a translator comment of course).
admin/server-timing.php
Outdated
<br> | ||
<?php | ||
echo wp_kses( | ||
__( 'Since the Server-Timing header is sent before the template is loaded, only hooks before the <code>template_include</code> filter can be measured.', 'performance-lab' ), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd use sprintf with a placeholder for template_include
so that it does not get translated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, just two i18n notes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @felixarntz for the updates.
I still reproduce #784 (review) error. Could you please take a look. Thanks.
Maybe it was because you had those settings saved from before? The actual behavior from having duplicate hooks was not changed, but I added sanitization to strip duplicate values. So can you please try to go to the Tools screen again and re-save? It should result in the duplicates being stripped. |
I'd like to propose Output Buffering as a new module. This module would be to explore implementation of Core-43258/Core-58285 while also providing an easy way to implement the toggle. It will give us an area to explore use of output buffering to make Performance enhancements as well, such as applying LCP enhancements to arbitrary elements not rendered using the normal WordPress mechanisms (e.g. hard-coded images and page builders). cc @joemcgill @kt-12 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @felixarntz, I test in fresh installation and it working for me.
I'll work on this. |
See #801 |
Summary
This PR implements a WP Admin screen Tools > Server-Timing which allows providing action and filter names. Any hook names provided will be measured and exposed in the
Server-Timing
header in the frontend.While the Server-Timing API from #553 has been a powerful foundation, it can sometimes be cumbersome to measure specific hooks performance, since it always requires writing custom code. Gists like this one can be used for that, but even with such thing it may be easier to just add the action or filter to a UI instead of having to modify a plugin's code. This PR makes it really easy and gives site owners control about specific hooks to measure.
The new admin screen with example input
Relevant technical choices
Testing
console.table( performance.getEntries()[0].serverTiming )
in the browser's dev tools console.wp-action-{$action}
/wp-filter-{$filter}
metrics.wp_enqueue_scripts
action), they won't show up by default. You'll need to activate output buffering (e.g. via this Gist plugin) so that those can be exposed as well.Checklist
[Focus]
orInfrastructure
label.[Type]
label.no milestone
label.