Skip to content

Commit e2effe6

Browse files
authored
Merge pull request #1826 from WordPress/fix/bfcache-conditions
Remove `no-cache` and `max-age=0` from bfcache failure conditions
2 parents 2b1bf18 + ffa9c25 commit e2effe6

File tree

2 files changed

+33
-74
lines changed

2 files changed

+33
-74
lines changed

plugins/performance-lab/includes/site-health/bfcache-compatibility-headers/helper.php

Lines changed: 9 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ function perflab_bfcache_compatibility_headers_check(): array {
2929
'color' => 'blue',
3030
),
3131
'description' => '<p>' . wp_kses(
32-
__( 'If the <code>Cache-Control</code> page response header includes directives like <code>no-store</code>, <code>no-cache</code>, or <code>max-age=0</code> then it can prevent instant back/forward navigations (using the browser bfcache). These are not present for unauthenticated requests on your site, so it is configured properly. Note that WordPress adds these directives for logged-in page responses.', 'performance-lab' ),
32+
__( "If the <code>Cache-Control</code> page response header includes the <code>no-store</code> directive then it can prevent instant back/forward navigations (using the browser's bfcache). This is not present for unauthenticated requests on your site, so it is configured properly. Note that there are other ways that bfcache can be disabled (e.g. you have JavaScript which uses a <code>unload</code> event listener). Also note that WordPress adds this directive for logged-in page responses for privacy/security reasons.", 'performance-lab' ),
3333
array( 'code' => array() )
3434
) . '</p>',
3535
'actions' => '',
@@ -66,41 +66,17 @@ function perflab_bfcache_compatibility_headers_check(): array {
6666
}
6767

6868
foreach ( (array) $cache_control_headers as $cache_control_header ) {
69-
$cache_control_header = strtolower( $cache_control_header );
70-
$found_directives = array();
71-
foreach ( array( 'no-store', 'no-cache', 'max-age=0' ) as $directive ) {
72-
if ( str_contains( $cache_control_header, $directive ) ) {
73-
$found_directives[] = $directive;
74-
}
75-
}
76-
77-
if ( count( $found_directives ) > 0 ) {
69+
if ( str_contains( strtolower( $cache_control_header ), 'no-store' ) ) {
7870
$result['label'] = __( 'The Cache-Control page header is preventing fast back/forward navigations', 'performance-lab' );
7971
$result['status'] = 'recommended';
8072
$result['description'] = sprintf(
81-
'<p>%s %s</p>',
82-
wp_kses(
83-
sprintf(
84-
/* translators: %s: problematic directive(s) */
85-
_n(
86-
'The <code>Cache-Control</code> response header for an unauthenticated request to the home page includes the following directive: %s.',
87-
'The <code>Cache-Control</code> response header for an unauthenticated request to the home page includes the following directives: %s.',
88-
count( $found_directives ),
89-
'performance-lab'
90-
),
91-
implode(
92-
', ',
93-
array_map(
94-
static function ( $header ) {
95-
return "<code>$header</code>";
96-
},
97-
$found_directives
98-
)
99-
)
100-
),
101-
array( 'code' => array() )
102-
),
103-
esc_html__( 'This can affect the performance of your site by preventing fast back/forward navigations (via browser bfcache).', 'performance-lab' )
73+
'<p>%s</p>',
74+
sprintf(
75+
/* translators: 1: Cache-Control, 2: no-store */
76+
esc_html__( 'The %1$s response header for an unauthenticated request to the home page includes the %2$s directive. This can affect the performance of your site by preventing fast back/forward navigations (via the browser\'s bfcache).', 'performance-lab' ),
77+
'<code>Cache-Control</code>',
78+
'<code>no-store</code>'
79+
)
10480
);
10581
break;
10682
}

plugins/performance-lab/tests/includes/site-health/bfcache-compatibility-headers/test-bfcache-compatibility-headers.php

Lines changed: 24 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,6 @@
88

99
class Test_BFCache_Compatibility_Headers extends WP_UnitTestCase {
1010

11-
/**
12-
* Holds mocked response headers for different test scenarios.
13-
*
14-
* @var array<string, array<string, mixed>>
15-
*/
16-
protected $mocked_responses = array();
17-
18-
/**
19-
* Setup each test.
20-
*/
21-
public function setUp(): void {
22-
parent::setUp();
23-
24-
// Clear any filters or mocks.
25-
remove_all_filters( 'pre_http_request' );
26-
27-
// Add the filter to mock HTTP requests.
28-
add_filter( 'pre_http_request', array( $this, 'mock_http_requests' ), 10, 3 );
29-
}
30-
3111
/**
3212
* Test that the bfcache compatibility test is added to the site health tests.
3313
*
@@ -64,7 +44,7 @@ public function test_perflab_bfcache_compatibility_headers_add_test_is_attached(
6444
* @param string $expected_message The expected message.
6545
*/
6646
public function test_perflab_bfcache_compatibility_headers_check( $response, string $expected_status, string $expected_message ): void {
67-
$this->mocked_responses = array( home_url( '/' ) => $response );
47+
$this->mock_http_request( $response, home_url( '/' ) );
6848

6949
$result = perflab_bfcache_compatibility_headers_check();
7050

@@ -82,27 +62,27 @@ public function data_test_bfcache_compatibility(): array {
8262
'headers_not_set' => array(
8363
$this->build_response( 200, array( 'cache-control' => '' ) ),
8464
'good',
85-
'If the <code>Cache-Control</code> page response header includes directives like',
65+
'If the <code>Cache-Control</code> page response header includes',
8666
),
8767
'no_store' => array(
8868
$this->build_response( 200, array( 'cache-control' => 'no-store' ) ),
8969
'recommended',
90-
'<p>The <code>Cache-Control</code> response header for an unauthenticated request to the home page includes the following directive: <code>no-store</code>',
70+
'<p>The <code>Cache-Control</code> response header for an unauthenticated request to the home page includes',
9171
),
9272
'no_cache' => array(
9373
$this->build_response( 200, array( 'cache-control' => 'no-cache' ) ),
94-
'recommended',
95-
'<p>The <code>Cache-Control</code> response header for an unauthenticated request to the home page includes the following directive: <code>no-cache</code>',
74+
'good',
75+
'If the <code>Cache-Control</code> page response header includes',
9676
),
9777
'max_age_0' => array(
98-
$this->build_response( 200, array( 'cache-control' => 'max-age=0' ) ),
99-
'recommended',
100-
'<p>The <code>Cache-Control</code> response header for an unauthenticated request to the home page includes the following directive: <code>max-age=0</code>',
78+
$this->build_response( 200, array( 'cache-control' => 'no-cache' ) ),
79+
'good',
80+
'If the <code>Cache-Control</code> page response header includes',
10181
),
10282
'max_age_0_no_store' => array(
10383
$this->build_response( 200, array( 'cache-control' => 'max-age=0, no-store' ) ),
10484
'recommended',
105-
'<p>The <code>Cache-Control</code> response header for an unauthenticated request to the home page includes the following directives: <code>no-store</code>, <code>max-age=0</code>',
85+
'<p>The <code>Cache-Control</code> response header for an unauthenticated request to the home page includes',
10686
),
10787
'error' => array(
10888
new WP_Error( 'http_request_failed', 'HTTP request failed' ),
@@ -113,20 +93,23 @@ public function data_test_bfcache_compatibility(): array {
11393
}
11494

11595
/**
116-
* Mock HTTP requests for assets to simulate different responses.
96+
* Mock HTTP response for a given URL.
11797
*
118-
* @param bool $response A preemptive return value of an HTTP request. Default false.
119-
* @param array<string, mixed> $args Request arguments.
120-
* @param string $url The request URL.
121-
* @return array<string, mixed>|WP_Error Mocked response.
98+
* @param array<string, mixed>|WP_Error $mocked_response The mocked response.
99+
* @param non-empty-string $url The request URL.
122100
*/
123-
public function mock_http_requests( bool $response, array $args, string $url ) {
124-
if ( isset( $this->mocked_responses[ $url ] ) ) {
125-
return $this->mocked_responses[ $url ];
126-
}
127-
128-
// If no specific mock set, default to a generic success with no caching.
129-
return $this->build_response( 200 );
101+
public function mock_http_request( $mocked_response, string $url ): void {
102+
add_filter(
103+
'pre_http_request',
104+
static function ( $pre, $args, $request_url ) use ( $url, $mocked_response ) {
105+
if ( $url === $request_url ) {
106+
return $mocked_response;
107+
}
108+
return $pre;
109+
},
110+
10,
111+
3
112+
);
130113
}
131114

132115
/**

0 commit comments

Comments
 (0)