Make WordPress Core

Changeset 34270


Ignore:
Timestamp:
09/17/2015 08:00:31 PM (11 years ago)
Author:
boonebgorges
Message:

Lazy-load comment meta on single post pages.

[34268] introduced cache priming for commentmeta, enabled by default. To
ensure performance on single post pages - where commentmeta is most likely
to cause performance issues - we disable up-front cache-priming. Instead, we
prime commentmeta caches for all comments in the loop the first time
get_comment_meta() is called on the page.

Props bradt, dd32, wonderboymusic, boonebgorges.
Fixes #16894.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/comment-functions.php

    r34268 r34270  
    23772377}
    23782378
     2379/**
     2380 * Lazy load comment meta when inside of a `WP_Query` loop.
     2381 *
     2382 * @since 4.4.0
     2383 *
     2384 * @param null $check      The `$check` param passed from the 'pre_comment_metadata' hook.
     2385 * @param int  $comment_id ID of the comment whose metadata is being cached.
     2386 * @return null In order not to short-circuit `get_metadata()`.
     2387 */
     2388function wp_lazyload_comment_meta( $check, $comment_id ) {
     2389        global $wp_query;
     2390
     2391        if ( ! empty( $wp_query->comments ) ) {
     2392                // Don't use `wp_list_pluck()` to avoid by-reference manipulation.
     2393                $comment_ids = array();
     2394                foreach ( $wp_query->comments as $comment ) {
     2395                        $comment_ids[] = $comment->comment_ID;
     2396                }
     2397                update_meta_cache( 'comment', $comment_ids );
     2398        }
     2399
     2400        return $check;
     2401}
     2402
    23792403//
    23802404// Internal
  • trunk/src/wp-includes/comment-template.php

    r34245 r34270  
    12121212                'status'  => 'approve',
    12131213                'post_id' => $post->ID,
     1214                'update_comment_meta_cache' => false, // We lazy-load comment meta for performance.
    12141215        );
    12151216
  • trunk/src/wp-includes/default-filters.php

    r34252 r34270  
    201201add_filter( 'xmlrpc_pingback_error',    'xmlrpc_pingback_error'               );
    202202add_filter( 'title_save_pre',           'trim'                                );
     203add_filter( 'get_comment_metadata',     'wp_lazyload_comment_meta',     10, 2 );
    203204
    204205add_filter( 'http_request_host_is_external', 'allowed_http_request_hosts', 10, 2 );
  • trunk/tests/phpunit/tests/comment/metaCache.php

    r34268 r34270  
    8282        }
    8383
    84         public function test_comment_meta_cache() {
    85                 $post_id = $this->factory->post->create( array(
    86                         'post_status' => 'publish'
    87                 ) );
     84        /**
     85         * @ticket 16894
     86         */
     87        public function test_comment_meta_should_be_lazy_loaded_for_all_comments_in_comments_template() {
     88                global $wpdb;
    8889
    89                 $comment_ids = $this->factory->comment->create_post_comments( $post_id, 10 );
     90                $p = $this->factory->post->create( array( 'post_status' => 'publish' ) );
     91                $comment_ids = $this->factory->comment->create_post_comments( $p, 3 );
    9092
    9193                foreach ( $comment_ids as $cid ) {
     
    9395                }
    9496
    95                 $post = get_post( $post_id );
     97                $this->go_to( get_permalink( $p ) );
    9698
    97                 $this->assertEquals( $post->comment_count, count( $comment_ids ) );
     99                if ( have_posts() ) {
     100                        while ( have_posts() ) {
     101                                the_post();
    98102
    99                 $this->go_to( get_permalink( $post_id ) );
     103                                // Load comments with `comments_template()`.
     104                                $cform = get_echo( 'comments_template' );
    100105
    101                 $this->assertTrue( is_single() );
    102                 $this->assertTrue( have_posts() );
     106                                // First request will hit the database.
     107                                $num_queries = $wpdb->num_queries;
     108                                get_comment_meta( $comment_ids[0], 'sauce' );
     109                                $this->assertSame( $num_queries + 1, $wpdb->num_queries );
    103110
    104                 global $wp_query;
    105 
    106                 while ( have_posts() ) {
    107                         the_post();
    108 
    109                         $comment_args = array(
    110                                 'order'   => 'ASC',
    111                                 'orderby' => 'comment_date_gmt',
    112                                 'status'  => 'approve',
    113                                 'post_id' => get_the_ID(),
    114                         );
    115 
    116                         $comments = get_comments( $comment_args );
    117 
    118                         // This is beyond awful
    119                         $wp_query->comments = $comments;
    120 
    121                         wp_list_comments( array(
    122                                 'echo' => false,
    123                                 'callback' => array( $this, '_comment_callback' )
    124                         ) );
     111                                // Second and third requests should be in cache.
     112                                get_comment_meta( $comment_ids[1], 'sauce' );
     113                                get_comment_meta( $comment_ids[2], 'sauce' );
     114                                $this->assertSame( $num_queries + 1, $wpdb->num_queries );
     115                        }
    125116                }
    126117        }
    127 
    128         public function _comment_callback( $comment ) {
    129                 global $wpdb;
    130 
    131                 get_comment_meta( $comment->comment_ID, 'sauce' );
    132 
    133                 if ( 0 === $this->i ) {
    134                         $this->queries = $wpdb->num_queries;
    135                 } else {
    136                         $this->assertEquals( $this->queries, $wpdb->num_queries );
    137                 }
    138 
    139                 $this->i++;
    140         }
    141118}
Note: See TracChangeset for help on using the changeset viewer.