Make WordPress Core


Ignore:
Timestamp:
02/13/2016 03:04:05 AM (9 years ago)
Author:
boonebgorges
Message:

Improve WP_Query lazyloading logic, for better performance.

Lazyloading for comment meta and term meta, introduced into WP_Query in
4.4, used flags - updated_term_meta_cache and updated_comment_meta_cache -
in an attempt to prevent cache priming from happening more than once per query
object. This technique was mostly effective, but not entirely efficient, since
the flag didn't prevent the lazyload_*_meta callbacks from running. The
obvious solution - removing the filter callback after it'd be run once - was
dismissed for 4.4 because of concerns that remove_filter() could disable
lazyloading too generally in the context of nested queries, due to the way
_wp_filter_build_unique_id() doesn't always build sufficiently unique IDs for
similar objects. However, further testing shows that this concern is only valid
in a very small subset of cases, while the cost of keeping the query objects in
memory, via the $wp_filter global, is quite significant. As such, this
changeset removes the flags in favor of the remove_filter() technique.

See #35454, #35816.

File:
1 edited

Legend:

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

    r36484 r36524  
    13031303     */
    13041304     public $thumbnails_cached = false;
    1305 
    1306     /**
    1307      * Whether the term meta cache for matched posts has been primed.
    1308      *
    1309      * @since 4.4.0
    1310      * @access protected
    1311      * @var bool
    1312      */
    1313     public $updated_term_meta_cache = false;
    1314 
    1315     /**
    1316      * Whether the comment meta cache for matched posts has been primed.
    1317      *
    1318      * @since 4.4.0
    1319      * @access protected
    1320      * @var bool
    1321      */
    1322     public $updated_comment_meta_cache = false;
    13231305
    13241306    /**
     
    48754857     */
    48764858    public function lazyload_term_meta( $check, $term_id ) {
    4877         /*
    4878          * We only do this once per `WP_Query` instance.
    4879          * Can't use `remove_filter()` because of non-unique object hashes.
    4880          */
    4881         if ( $this->updated_term_meta_cache ) {
    4882             return $check;
    4883         }
    4884 
    48854859        // We can only lazyload if the entire post object is present.
    48864860        $posts = array();
     
    49164890            if ( isset( $term_ids[ $term_id ] ) ) {
    49174891                update_termmeta_cache( array_keys( $term_ids ) );
    4918                 $this->updated_term_meta_cache = true;
     4892                remove_filter( 'get_term_metadata', array( $this, 'lazyload_term_meta' ), 10, 2 );
    49194893            }
    49204894        }
     
    49224896        // If no terms were found, there's no need to run this again.
    49234897        if ( empty( $term_ids ) ) {
    4924             $this->updated_term_meta_cache = true;
     4898            remove_filter( 'get_term_metadata', array( $this, 'lazyload_term_meta' ), 10, 2 );
    49254899        }
    49264900
     
    49414915     */
    49424916    public function lazyload_comment_meta( $check, $comment_id ) {
    4943         /*
    4944          * We only do this once per `WP_Query` instance.
    4945          * Can't use `remove_filter()` because of non-unique object hashes.
    4946          */
    4947         if ( $this->updated_comment_meta_cache ) {
    4948             return $check;
    4949         }
    4950 
    49514917        // Don't use `wp_list_pluck()` to avoid by-reference manipulation.
    49524918        $comment_ids = array();
     
    49644930        if ( in_array( $comment_id, $comment_ids ) ) {
    49654931            update_meta_cache( 'comment', $comment_ids );
    4966             $this->updated_comment_meta_cache = true;
     4932            remove_filter( 'get_comment_metadata', array( $this, 'lazyload_comment_meta' ), 10, 2 );
    49674933        } elseif ( empty( $comment_ids ) ) {
    4968             $this->updated_comment_meta_cache = true;
     4934            remove_filter( 'get_comment_metadata', array( $this, 'lazyload_comment_meta' ), 10, 2 );
    49694935        }
    49704936
Note: See TracChangeset for help on using the changeset viewer.