From d03ae82c32444a4f1ed7015389d94b5cc170741f Mon Sep 17 00:00:00 2001 From: Boone Gorges Date: Sat, 13 Feb 2016 03:04:05 +0000 Subject: [PATCH] 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. git-svn-id: https://develop.svn.wordpress.org/trunk@36524 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/query.php | 42 ++++----------------------------------- 1 file changed, 4 insertions(+), 38 deletions(-) diff --git a/src/wp-includes/query.php b/src/wp-includes/query.php index ad407c1fdd..a8fbbc52e2 100644 --- a/src/wp-includes/query.php +++ b/src/wp-includes/query.php @@ -1303,24 +1303,6 @@ class WP_Query { */ public $thumbnails_cached = false; - /** - * Whether the term meta cache for matched posts has been primed. - * - * @since 4.4.0 - * @access protected - * @var bool - */ - public $updated_term_meta_cache = false; - - /** - * Whether the comment meta cache for matched posts has been primed. - * - * @since 4.4.0 - * @access protected - * @var bool - */ - public $updated_comment_meta_cache = false; - /** * Cached list of search stopwords. * @@ -4874,14 +4856,6 @@ class WP_Query { * another value if filtered by a plugin. */ public function lazyload_term_meta( $check, $term_id ) { - /* - * We only do this once per `WP_Query` instance. - * Can't use `remove_filter()` because of non-unique object hashes. - */ - if ( $this->updated_term_meta_cache ) { - return $check; - } - // We can only lazyload if the entire post object is present. $posts = array(); foreach ( $this->posts as $post ) { @@ -4915,13 +4889,13 @@ class WP_Query { */ if ( isset( $term_ids[ $term_id ] ) ) { update_termmeta_cache( array_keys( $term_ids ) ); - $this->updated_term_meta_cache = true; + remove_filter( 'get_term_metadata', array( $this, 'lazyload_term_meta' ), 10, 2 ); } } // If no terms were found, there's no need to run this again. if ( empty( $term_ids ) ) { - $this->updated_term_meta_cache = true; + remove_filter( 'get_term_metadata', array( $this, 'lazyload_term_meta' ), 10, 2 ); } return $check; @@ -4940,14 +4914,6 @@ class WP_Query { * @return mixed The original value of `$check`, to not affect 'get_comment_metadata'. */ public function lazyload_comment_meta( $check, $comment_id ) { - /* - * We only do this once per `WP_Query` instance. - * Can't use `remove_filter()` because of non-unique object hashes. - */ - if ( $this->updated_comment_meta_cache ) { - return $check; - } - // Don't use `wp_list_pluck()` to avoid by-reference manipulation. $comment_ids = array(); if ( is_array( $this->comments ) ) { @@ -4963,9 +4929,9 @@ class WP_Query { */ if ( in_array( $comment_id, $comment_ids ) ) { update_meta_cache( 'comment', $comment_ids ); - $this->updated_comment_meta_cache = true; + remove_filter( 'get_comment_metadata', array( $this, 'lazyload_comment_meta' ), 10, 2 ); } elseif ( empty( $comment_ids ) ) { - $this->updated_comment_meta_cache = true; + remove_filter( 'get_comment_metadata', array( $this, 'lazyload_comment_meta' ), 10, 2 ); } return $check;