| 1 |
<?php |
| 2 |
/** |
| 3 |
* Server-Timing API integration file |
| 4 |
* |
| 5 |
* @package performance-lab |
| 6 |
* @since 1.8.0 |
| 7 |
*/ |
| 8 |
|
| 9 |
/** |
| 10 |
* Provides access the Server-Timing API. |
| 11 |
* |
| 12 |
* When called for the first time, this also initializes the API to schedule the header for output. |
| 13 |
* In case that no metrics are registered, this is still called on {@see 'wp_loaded'}, so that even then it still fires |
| 14 |
* its action hooks as expected. |
| 15 |
* |
| 16 |
* @since 1.8.0 |
| 17 |
*/ |
| 18 |
function perflab_server_timing() { |
| 19 |
static $server_timing; |
| 20 |
|
| 21 |
if ( null === $server_timing ) { |
| 22 |
$server_timing = new Perflab_Server_Timing(); |
| 23 |
add_filter( 'template_include', array( $server_timing, 'on_template_include' ), PHP_INT_MAX ); |
| 24 |
} |
| 25 |
|
| 26 |
return $server_timing; |
| 27 |
} |
| 28 |
add_action( 'wp_loaded', 'perflab_server_timing' ); |
| 29 |
|
| 30 |
/** |
| 31 |
* Registers a metric to calculate for the Server-Timing header. |
| 32 |
* |
| 33 |
* This method must be called before the {@see 'perflab_server_timing_send_header'} hook. |
| 34 |
* |
| 35 |
* @since 1.8.0 |
| 36 |
* |
| 37 |
* @param string $metric_slug The metric slug. |
| 38 |
* @param array $args { |
| 39 |
* Arguments for the metric. |
| 40 |
* |
| 41 |
* @type callable $measure_callback The callback that initiates calculating the metric value. It will receive |
| 42 |
* the Perflab_Server_Timing_Metric instance as a parameter, in order to set |
| 43 |
* the value when it has been calculated. Metric values must be provided in |
| 44 |
* milliseconds. |
| 45 |
* @type string $access_cap Capability required to view the metric. If this is a public metric, this |
| 46 |
* needs to be set to "exist". |
| 47 |
* } |
| 48 |
*/ |
| 49 |
function perflab_server_timing_register_metric( $metric_slug, array $args ) { |
| 50 |
perflab_server_timing()->register_metric( $metric_slug, $args ); |
| 51 |
} |
| 52 |
|
| 53 |
/** |
| 54 |
* Returns whether an output buffer should be used to gather Server-Timing metrics during template rendering. |
| 55 |
* |
| 56 |
* @since 1.8.0 |
| 57 |
* |
| 58 |
* @return bool True if an output buffer should be used, false otherwise. |
| 59 |
*/ |
| 60 |
function perflab_server_timing_use_output_buffer() { |
| 61 |
return perflab_server_timing()->use_output_buffer(); |
| 62 |
} |
| 63 |
|
| 64 |
/** |
| 65 |
* Wraps a callback (e.g. for an action or filter) to be measured and included in the Server-Timing header. |
| 66 |
* |
| 67 |
* @since 1.8.0 |
| 68 |
* |
| 69 |
* @param callable $callback The callback to wrap. |
| 70 |
* @param string $metric_slug The metric slug to use within the Server-Timing header. |
| 71 |
* @param string $access_cap Capability required to view the metric. If this is a public metric, this needs to be |
| 72 |
* set to "exist". |
| 73 |
* @return callable Callback function that will run $callback and measure its execution time once called. |
| 74 |
*/ |
| 75 |
function perflab_wrap_server_timing( $callback, $metric_slug, $access_cap ) { |
| 76 |
return function( ...$callback_args ) use ( $callback, $metric_slug, $access_cap ) { |
| 77 |
// Gain access to Perflab_Server_Timing_Metric instance. |
| 78 |
$server_timing_metric = null; |
| 79 |
|
| 80 |
// Only register the metric the first time the function is called. |
| 81 |
// For now, this also means only the first function call is measured. |
| 82 |
if ( ! perflab_server_timing()->has_registered_metric( $metric_slug ) ) { |
| 83 |
perflab_server_timing_register_metric( |
| 84 |
$metric_slug, |
| 85 |
array( |
| 86 |
'measure_callback' => function( $metric ) use ( &$server_timing_metric ) { |
| 87 |
$server_timing_metric = $metric; |
| 88 |
}, |
| 89 |
'access_cap' => $access_cap, |
| 90 |
) |
| 91 |
); |
| 92 |
} |
| 93 |
|
| 94 |
// If metric instance was not set, this metric should not be calculated. |
| 95 |
if ( null === $server_timing_metric ) { |
| 96 |
return call_user_func_array( $callback, $callback_args ); |
| 97 |
} |
| 98 |
|
| 99 |
// Measure time before the callback. |
| 100 |
$server_timing_metric->measure_before(); |
| 101 |
|
| 102 |
// Execute the callback. |
| 103 |
$result = call_user_func_array( $callback, $callback_args ); |
| 104 |
|
| 105 |
// Measure time after the callback and calculate total. |
| 106 |
$server_timing_metric->measure_after(); |
| 107 |
|
| 108 |
// Return result (e.g. in case this is a filter callback). |
| 109 |
return $result; |
| 110 |
}; |
| 111 |
} |
| 112 |
|