Make WordPress Core


Ignore:
Timestamp:
08/31/2022 10:44:04 PM (4 years ago)
Author:
flixos90
Message:

Site Health: Introduce page cache check.

This changeset adds a new page_cache check which determines whether the site uses a full page cache, and in addition assesses the server response time. If no page cache is present and the server response time is slow, the check will suggest use of a page cache.

A few filters are included for customization of the check:

  • site_status_good_response_time_threshold filters the number of milliseconds below which the server response time is considered good. The default value is based on the server-response-time Lighthouse audit and can be altered using this filter.
  • site_status_page_cache_supported_cache_headers filters the map of supported cache headers and their callback to determine whether it was a cache hit. The default list includes commonly used cache headers, and it is filterable to support e.g. additional cache headers used by specific vendors.

Note that due to the nature of this check it is only run in production environments.

Props furi3r, westonruter, spacedmonkey, swissspidy, Clorith.
Fixes #56041.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/site-health.php

    r53955 r54043  
    110110
    111111        /**
     112         * @ticket 56041
     113         * @dataProvider data_page_cache_test
     114         * @covers ::get_test_page_cache()
     115         * @covers ::get_page_cache_detail()
     116         * @covers ::get_page_cache_headers()
     117         * @covers ::check_for_page_caching()
     118         */
     119        public function test_get_page_cache( $responses, $expected_status, $expected_label, $good_basic_auth = null, $delay_the_response = false ) {
     120                $wp_site_health = new WP_Site_Health();
     121
     122                $expected_props = array(
     123                        'badge'  => array(
     124                                'label' => __( 'Performance' ),
     125                                'color' => 'blue',
     126                        ),
     127                        'test'   => 'page_cache',
     128                        'status' => $expected_status,
     129                        'label'  => $expected_label,
     130                );
     131
     132                if ( null !== $good_basic_auth ) {
     133                        $_SERVER['PHP_AUTH_USER'] = 'admin';
     134                        $_SERVER['PHP_AUTH_PW']   = 'password';
     135                }
     136
     137                $threshold = 10;
     138                if ( $delay_the_response ) {
     139                        add_filter(
     140                                'site_status_good_response_time_threshold',
     141                                static function () use ( $threshold ) {
     142                                        return $threshold;
     143                                }
     144                        );
     145                }
     146
     147                add_filter(
     148                        'pre_http_request',
     149                        function ( $r, $parsed_args ) use ( &$responses, &$is_unauthorized, $good_basic_auth, $delay_the_response, $threshold ) {
     150
     151                                $expected_response = array_shift( $responses );
     152
     153                                if ( $delay_the_response ) {
     154                                        usleep( $threshold * 1000 + 1 );
     155                                }
     156
     157                                if ( 'unauthorized' === $expected_response ) {
     158                                        $is_unauthorized = true;
     159
     160                                        return array(
     161                                                'response' => array(
     162                                                        'code'    => 401,
     163                                                        'message' => 'Unauthorized',
     164                                                ),
     165                                        );
     166                                }
     167
     168                                if ( null !== $good_basic_auth ) {
     169                                        $this->assertArrayHasKey(
     170                                                'Authorization',
     171                                                $parsed_args['headers']
     172                                        );
     173                                }
     174
     175                                $this->assertIsArray( $expected_response );
     176
     177                                return array(
     178                                        'headers'  => $expected_response,
     179                                        'response' => array(
     180                                                'code'    => 200,
     181                                                'message' => 'OK',
     182                                        ),
     183                                );
     184                        },
     185                        20,
     186                        2
     187                );
     188
     189                $actual = $wp_site_health->get_test_page_cache();
     190                $this->assertArrayHasKey( 'description', $actual );
     191                $this->assertArrayHasKey( 'actions', $actual );
     192                if ( $is_unauthorized ) {
     193                        $this->assertStringContainsString( 'Unauthorized', $actual['description'] );
     194                } else {
     195                        $this->assertStringNotContainsString( 'Unauthorized', $actual['description'] );
     196                }
     197
     198                $this->assertEquals(
     199                        $expected_props,
     200                        wp_array_slice_assoc( $actual, array_keys( $expected_props ) )
     201                );
     202        }
     203
     204        /**
    112205         * @group ms-excluded
    113206         * @ticket 56040
    … …  
    160253                $this->assertTrue(
    161254                        $wp_site_health->should_suggest_persistent_object_cache()
     255                );
     256        }
     257
     258        /**
     259         * Gets response data for get_test_page_cache().
     260         * @ticket 56041
     261         *
     262         * @return array[]
     263         */
     264        public function data_page_cache_test() {
     265                $recommended_label = 'Page cache is not detected but the server response time is OK';
     266                $good_label        = 'Page cache is detected and the server response time is good';
     267                $critical_label    = 'Page cache is not detected and the server response time is slow';
     268                $error_label       = 'Unable to detect the presence of page cache';
     269
     270                return array(
     271                        'basic-auth-fail'                        => array(
     272                                'responses'       => array(
     273                                        'unauthorized',
     274                                ),
     275                                'expected_status' => 'recommended',
     276                                'expected_label'  => $error_label,
     277                                'good_basic_auth' => false,
     278                        ),
     279                        'no-cache-control'                       => array(
     280                                'responses'          => array_fill( 0, 3, array() ),
     281                                'expected_status'    => 'critical',
     282                                'expected_label'     => $critical_label,
     283                                'good_basic_auth'    => null,
     284                                'delay_the_response' => true,
     285                        ),
     286                        'no-cache'                               => array(
     287                                'responses'       => array_fill( 0, 3, array( 'cache-control' => 'no-cache' ) ),
     288                                'expected_status' => 'recommended',
     289                                'expected_label'  => $recommended_label,
     290                        ),
     291                        'no-cache-arrays'                        => array(
     292                                'responses'       => array_fill(
     293                                        0,
     294                                        3,
     295                                        array(
     296                                                'cache-control' => array(
     297                                                        'no-cache',
     298                                                        'no-store',
     299                                                ),
     300                                        )
     301                                ),
     302                                'expected_status' => 'recommended',
     303                                'expected_label'  => $recommended_label,
     304                        ),
     305                        'no-cache-with-delayed-response'         => array(
     306                                'responses'          => array_fill( 0, 3, array( 'cache-control' => 'no-cache' ) ),
     307                                'expected_status'    => 'critical',
     308                                'expected_label'     => $critical_label,
     309                                'good_basic_auth'    => null,
     310                                'delay_the_response' => true,
     311                        ),
     312                        'age'                                    => array(
     313                                'responses'       => array_fill(
     314                                        0,
     315                                        3,
     316                                        array( 'age' => '1345' )
     317                                ),
     318                                'expected_status' => 'good',
     319                                'expected_label'  => $good_label,
     320                        ),
     321                        'cache-control-max-age'                  => array(
     322                                'responses'       => array_fill(
     323                                        0,
     324                                        3,
     325                                        array( 'cache-control' => 'public; max-age=600' )
     326                                ),
     327                                'expected_status' => 'good',
     328                                'expected_label'  => $good_label,
     329                        ),
     330                        'etag'                                   => array(
     331                                'responses'       => array_fill(
     332                                        0,
     333                                        3,
     334                                        array( 'etag' => '"1234567890"' )
     335                                ),
     336                                'expected_status' => 'good',
     337                                'expected_label'  => $good_label,
     338                        ),
     339                        'cache-control-max-age-after-2-requests' => array(
     340                                'responses'       => array(
     341                                        array(),
     342                                        array(),
     343                                        array( 'cache-control' => 'public; max-age=600' ),
     344                                ),
     345                                'expected_status' => 'good',
     346                                'expected_label'  => $good_label,
     347                        ),
     348                        'cache-control-with-future-expires'      => array(
     349                                'responses'       => array_fill(
     350                                        0,
     351                                        3,
     352                                        array( 'expires' => gmdate( 'r', time() + MINUTE_IN_SECONDS * 10 ) )
     353                                ),
     354                                'expected_status' => 'good',
     355                                'expected_label'  => $good_label,
     356                        ),
     357                        'cache-control-with-past-expires'        => array(
     358                                'responses'          => array_fill(
     359                                        0,
     360                                        3,
     361                                        array( 'expires' => gmdate( 'r', time() - MINUTE_IN_SECONDS * 10 ) )
     362                                ),
     363                                'expected_status'    => 'critical',
     364                                'expected_label'     => $critical_label,
     365                                'good_basic_auth'    => null,
     366                                'delay_the_response' => true,
     367                        ),
     368                        'cache-control-with-basic-auth'          => array(
     369                                'responses'       => array_fill(
     370                                        0,
     371                                        3,
     372                                        array( 'cache-control' => 'public; max-age=600' )
     373                                ),
     374                                'expected_status' => 'good',
     375                                'expected_label'  => $good_label,
     376                                'good_basic_auth' => true,
     377                        ),
     378                        'x-cache-enabled'                        => array(
     379                                'responses'       => array_fill(
     380                                        0,
     381                                        3,
     382                                        array( 'x-cache-enabled' => 'true' )
     383                                ),
     384                                'expected_status' => 'good',
     385                                'expected_label'  => $good_label,
     386                        ),
     387                        'x-cache-enabled-with-delay'             => array(
     388                                'responses'          => array_fill(
     389                                        0,
     390                                        3,
     391                                        array( 'x-cache-enabled' => 'false' )
     392                                ),
     393                                'expected_status'    => 'critical',
     394                                'expected_label'     => $critical_label,
     395                                'good_basic_auth'    => null,
     396                                'delay_the_response' => true,
     397                        ),
     398                        'x-cache-disabled'                       => array(
     399                                'responses'       => array_fill(
     400                                        0,
     401                                        3,
     402                                        array( 'x-cache-disabled' => 'off' )
     403                                ),
     404                                'expected_status' => 'good',
     405                                'expected_label'  => $good_label,
     406                        ),
    162407                );
    163408        }
Note: See TracChangeset for help on using the changeset viewer.