Skip to content

Commit 51c4222

Browse files
committed
Revamp Server-Timing API to simplify API usage.
1 parent 692cd60 commit 51c4222

File tree

3 files changed

+239
-174
lines changed

3 files changed

+239
-174
lines changed

‎server-timing/class-perflab-server-timing-metric.php‎

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,21 @@ class Perflab_Server_Timing_Metric {
2222
private $slug;
2323

2424
/**
25-
* The metric value.
25+
* The metric value in milliseconds.
2626
*
2727
* @since n.e.x.t
2828
* @var int|float|null
2929
*/
3030
private $value;
3131

32+
/**
33+
* The value measured before relevant execution logic in seconds, if used.
34+
*
35+
* @since n.e.x.t
36+
* @var float|null
37+
*/
38+
private $before_value;
39+
3240
/**
3341
* Constructor.
3442
*
@@ -54,6 +62,9 @@ public function get_slug() {
5462
/**
5563
* Sets the metric value.
5664
*
65+
* Alternatively to setting the metric value directly, the {@see Perflab_Server_Timing_Metric::measure_before()}
66+
* and {@see Perflab_Server_Timing_Metric::measure_after()} methods can be used to further simplify measuring.
67+
*
5768
* @since n.e.x.t
5869
*
5970
* @param int|float $value The metric value to set, in milliseconds.
@@ -90,4 +101,38 @@ public function set_value( $value ) {
90101
public function get_value() {
91102
return $this->value;
92103
}
104+
105+
/**
106+
* Captures the current time, as a reference point to calculate the duration of a task afterwards.
107+
*
108+
* This should be used in combination with {@see Perflab_Server_Timing_Metric::measure_after()}. Alternatively,
109+
* {@see Perflab_Server_Timing_Metric::set_value()} can be used to set a calculated value manually.
110+
*
111+
* @since n.e.x.t
112+
*/
113+
public function measure_before() {
114+
$this->before_value = microtime( true );
115+
}
116+
117+
/**
118+
* Captures the current time and compares it to the reference point to calculate a task's duration.
119+
*
120+
* This should be used in combination with {@see Perflab_Server_Timing_Metric::measure_before()}. Alternatively,
121+
* {@see Perflab_Server_Timing_Metric::set_value()} can be used to set a calculated value manually.
122+
*
123+
* @since n.e.x.t
124+
*/
125+
public function measure_after() {
126+
if ( ! $this->before_value ) {
127+
_doing_it_wrong(
128+
__METHOD__,
129+
/* translators: %s: PHP method name */
130+
sprintf( __( 'The %s method must be called before.', 'performance-lab' ), __CLASS__ . '::measure_before()' ),
131+
''
132+
);
133+
return;
134+
}
135+
136+
$this->set_value( ( microtime( true ) - $this->before_value ) * 1000.0 );
137+
}
93138
}

‎server-timing/class-perflab-server-timing.php‎

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ class Perflab_Server_Timing {
3232
/**
3333
* Registers a metric to calculate for the Server-Timing header.
3434
*
35+
* This method must be called before the {@see 'perflab_server_timing_send_header'} hook.
36+
*
3537
* @since n.e.x.t
3638
*
3739
* @param string $metric_slug The metric slug.
@@ -47,6 +49,16 @@ class Perflab_Server_Timing {
4749
* }
4850
*/
4951
public function register_metric( $metric_slug, array $args ) {
52+
if ( did_action( 'perflab_server_timing_send_header' ) && ! doing_action( 'perflab_server_timing_send_header' ) ) {
53+
_doing_it_wrong(
54+
__METHOD__,
55+
/* translators: %s: WordPress action name */
56+
sprintf( __( 'The method must be called before or during the %s action.', 'performance-lab' ), 'perflab_server_timing_send_header' ),
57+
''
58+
);
59+
return;
60+
}
61+
5062
$args = wp_parse_args(
5163
$args,
5264
array(
@@ -93,7 +105,7 @@ public function register_metric( $metric_slug, array $args ) {
93105
*
94106
* @since n.e.x.t
95107
*/
96-
public function add_header() {
108+
public function send_header() {
97109
if ( headers_sent() ) {
98110
_doing_it_wrong(
99111
__METHOD__,
@@ -103,6 +115,15 @@ public function add_header() {
103115
return;
104116
}
105117

118+
/**
119+
* Fires right before the Server-Timing header is sent.
120+
*
121+
* This action is the last possible point to register a Server-Timing metric.
122+
*
123+
* @since n.e.x.t
124+
*/
125+
do_action( 'perflab_server_timing_send_header' );
126+
106127
$header_value = $this->get_header_value();
107128
if ( ! $header_value ) {
108129
return;
@@ -145,6 +166,55 @@ function( $value ) {
145166
return implode( ', ', $metric_header_values );
146167
}
147168

169+
/**
170+
* Returns whether an output buffer should be used to gather Server-Timing metrics during template rendering.
171+
*
172+
* @since n.e.x.t
173+
*
174+
* @return bool True if an output buffer should be used, false otherwise.
175+
*/
176+
public function use_output_buffer() {
177+
/**
178+
* Filters whether an output buffer should be used to be able to gather additional Server-Timing metrics.
179+
*
180+
* @since n.e.x.t
181+
*
182+
* @param bool $use_output_buffer Whether to use an output buffer.
183+
*/
184+
return apply_filters( 'perflab_server_timing_use_output_buffer', false );
185+
}
186+
187+
/**
188+
* Hook callback for the 'template_include' filter.
189+
*
190+
* This effectively initializes the class to send the Server-Timing header at the right point.
191+
*
192+
* This method is solely intended for internal use within WordPress.
193+
*
194+
* @since n.e.x.t
195+
*
196+
* @param mixed $passthrough Optional. Filter value. Default null.
197+
* @return mixed Unmodified value of $passthrough.
198+
*/
199+
public function on_template_include( $passthrough = null ) {
200+
if ( ! $this->use_output_buffer() ) {
201+
$this->send_header();
202+
return $passthrough;
203+
}
204+
205+
ob_start();
206+
add_action(
207+
'shutdown',
208+
function() {
209+
$output = ob_get_clean();
210+
$this->send_header();
211+
echo $output;
212+
},
213+
-1000
214+
);
215+
return $passthrough;
216+
}
217+
148218
/**
149219
* Formats the header segment for a single metric.
150220
*

0 commit comments

Comments
 (0)