|\WP_Error */ public static function sample( string $url ) { $url = esc_url_raw( $url ); if ( '' === $url ) { return new \WP_Error( 'xspeed_verify_url', __( 'A URL is required.', 'xspeed' ) ); } // Cache-buster: without it a static-cached HIT returns the pre-change // page and every check passes against stale HTML. $bust = add_query_arg( 'xspeed_verify', (string) time(), $url ); $t0 = microtime( true ); $resp = wp_remote_get( $bust, array( 'timeout' => 20, 'redirection' => 3, 'sslverify' => false, 'headers' => array( 'Cache-Control' => 'no-cache' ), // A real browser UA: some hosts and firewalls serve a // challenge page to unknown agents, which would read as the // site being broken. 'user-agent' => 'Mozilla/5.0 (compatible; xSpeed-Verifier/1.0)', ) ); if ( is_wp_error( $resp ) ) { return $resp; } $body = (string) wp_remote_retrieve_body( $resp ); return array( 'status' => (int) wp_remote_retrieve_response_code( $resp ), 'bytes' => strlen( $body ), 'complete' => (bool) preg_match( '##i', $body ), 'stylesheets' => self::count_stylesheets( $body ), 'scripts' => (int) preg_match_all( '#]*\bsrc=#i', $body ), 'title' => self::extract_title( $body ), // Wall-clock for the whole request, in ms. The cache-buster above // makes every sample an uncached render, so successive samples // measure the same thing and their medians are comparable — this // is what Optimizer's per-step regression check reads. (#310) 'elapsed_ms' => ( microtime( true ) - $t0 ) * 1000, ); } /** * Count real stylesheet links. * * `