@@ -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