diff --git a/plugins/performance-lab/includes/server-timing/class-perflab-server-timing-metric.php b/plugins/performance-lab/includes/server-timing/class-perflab-server-timing-metric.php index fc01e682c3..8f23c9e86f 100644 --- a/plugins/performance-lab/includes/server-timing/class-perflab-server-timing-metric.php +++ b/plugins/performance-lab/includes/server-timing/class-perflab-server-timing-metric.php @@ -30,13 +30,21 @@ class Perflab_Server_Timing_Metric { private $value; /** - * The value measured before relevant execution logic in seconds, if used. + * The value measured before relevant execution logic in microseconds, if used. * * @since 1.8.0 * @var float|null */ private $before_value; + /** + * The metric description, if used. + * + * @since n.e.x.t + * @var string|null + */ + private $description; + /** * Constructor. * @@ -109,6 +117,50 @@ public function get_value() { return $this->value; } + /** + * Sets the start time. + * + * @since n.e.x.t + * + * @param float $value Start time in microseconds. + */ + public function set_start_time( float $value ): void { + $this->before_value = $value; + } + + /** + * Returns the start time if set. + * + * @since n.e.x.t + * + * @return float|null Start time if set. + */ + public function get_start_time(): ?float { + return $this->before_value; + } + + /** + * Sets the metric description. + * + * @since n.e.x.t + * + * @param string $description Description. + */ + public function set_description( string $description ): void { + $this->description = $description; + } + + /** + * Returns the metric description. + * + * @since n.e.x.t + * + * @return string|null Description if set. + */ + public function get_description(): ?string { + return $this->description; + } + /** * Captures the current time, as a reference point to calculate the duration of a task afterward. * @@ -118,7 +170,7 @@ public function get_value() { * @since 1.8.0 */ public function measure_before(): void { - $this->before_value = microtime( true ); + $this->set_start_time( microtime( true ) ); } /** diff --git a/plugins/performance-lab/includes/server-timing/class-perflab-server-timing.php b/plugins/performance-lab/includes/server-timing/class-perflab-server-timing.php index 3eed6ad703..ad20824256 100644 --- a/plugins/performance-lab/includes/server-timing/class-perflab-server-timing.php +++ b/plugins/performance-lab/includes/server-timing/class-perflab-server-timing.php @@ -288,19 +288,43 @@ function ( string $output, ?int $phase ): string { */ private function format_metric_header_value( Perflab_Server_Timing_Metric $metric ): ?string { $value = $metric->get_value(); - - // If no value is set, make sure it's just passed through. - if ( null === $value ) { - return null; - } + $start = $metric->get_start_time(); + $desc = $metric->get_description(); if ( is_float( $value ) ) { $value = round( $value, 2 ); } + if ( is_float( $start ) ) { + $start = round( $start, 2 ) * 1000.00; + } + + // If no value is set, make sure it's just passed through. + if ( null === $start && null === $value ) { + return null; + } + // See https://github.com/WordPress/performance/issues/955. $name = preg_replace( '/[^!#$%&\'*+\-.^_`|~0-9a-zA-Z]/', '-', $metric->get_slug() ); - return sprintf( 'wp-%1$s;dur=%2$s', $name, $value ); + if ( 'response-start' !== $name && 'response-end' !== $name ) { + $name = 'wp-' . $name; + } + + $header_value = sprintf( '%s', $name ); + + if ( $value ) { + $header_value .= sprintf( ';dur=%s', $value ); + } + + if ( $start ) { + $header_value .= sprintf( ';start=%s', $start ); + } + + if ( $desc ) { + $header_value .= sprintf( ';desc=%s', $desc ); + } + + return $header_value; } } diff --git a/plugins/performance-lab/includes/server-timing/defaults.php b/plugins/performance-lab/includes/server-timing/defaults.php index da7c8d3426..3a8838ccb3 100644 --- a/plugins/performance-lab/includes/server-timing/defaults.php +++ b/plugins/performance-lab/includes/server-timing/defaults.php @@ -31,6 +31,7 @@ function perflab_register_default_server_timing_before_template_metrics(): void 'measure_callback' => static function ( $metric ): void { // The 'timestart' global is set right at the beginning of WordPress execution. $metric->set_value( ( microtime( true ) - $GLOBALS['timestart'] ) * 1000.0 ); + $metric->set_start_time( $GLOBALS['timestart'] ); }, 'access_cap' => 'exist', ) @@ -135,6 +136,27 @@ static function (): void { 'measure_callback' => static function ( $metric ): void { // The 'timestart' global is set right at the beginning of WordPress execution. $metric->set_value( ( microtime( true ) - $GLOBALS['timestart'] ) * 1000.0 ); + $metric->set_start_time( $GLOBALS['timestart'] ); + }, + 'access_cap' => 'exist', + ) + ); + + perflab_server_timing_register_metric( + 'response-start', + array( + 'measure_callback' => static function ( $metric ): void { + $metric->set_start_time( $GLOBALS['timestart'] ); + }, + 'access_cap' => 'exist', + ) + ); + + perflab_server_timing_register_metric( + 'response-end', + array( + 'measure_callback' => static function ( $metric ): void { + $metric->set_start_time( microtime( true ) ); }, 'access_cap' => 'exist', ) @@ -170,6 +192,7 @@ static function ( $acc, $query ) { 0.0 ); $metric->set_value( ( $total_query_time - $GLOBALS['perflab_query_time_before_template'] ) * 1000.0 ); + $metric->set_start_time( $GLOBALS['perflab_query_time_before_template'] ); }, 'access_cap' => 'exist', )