Make WordPress Core

Changeset 34270


Ignore:
Timestamp:
09/17/2015 08:00:31 PM (9 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.