-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Lazy load post meta #4216
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Lazy load post meta #4216
Changes from 28 commits
e77768b
a9e45a1
b5f297e
efcdbc7
85ad4ae
9f19cac
77fa22e
753379d
093b224
ef8e797
b2e72e1
657aebb
ee9e65e
14aec68
d6d9934
8f33b9a
e61d194
55b32c3
4330c69
4f90281
046cdf5
cbe16f1
dc7344a
a077f46
f4ec367
59a3aee
a6b8d34
4e3a8ec
79f93c1
434cb55
95df19a
ebf588e
7893aee
01f785d
34855d1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -61,6 +61,10 @@ public function __construct() { | |
| 'filter' => 'get_comment_metadata', | ||
| 'callback' => array( $this, 'lazyload_meta_callback' ), | ||
| ), | ||
| 'post' => array( | ||
| 'filter' => 'get_post_metadata', | ||
| 'callback' => array( $this, 'lazyload_post_meta' ), | ||
| ), | ||
| 'blog' => array( | ||
| 'filter' => 'get_blog_metadata', | ||
| 'callback' => array( $this, 'lazyload_meta_callback' ), | ||
|
|
@@ -163,6 +167,41 @@ public function lazyload_comment_meta( $check ) { | |
| return $this->lazyload_meta_callback( $check, 0, '', false, 'comment' ); | ||
| } | ||
|
|
||
| /** | ||
| * Lazy-loads post meta for queued posts. | ||
| * | ||
| * This method is public so that it can be used as a filter callback. As a rule, there | ||
| * is no need to invoke it directly. | ||
| * | ||
| * @since x.x.x | ||
| * | ||
| * @param mixed $check The `$check` param passed from the 'get_*_metadata' hook. | ||
| * @param int $object_id ID of the object metadata is for. | ||
| * @param string $meta_key Unused. | ||
| * @param bool $single Unused. | ||
| * @param string $meta_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user', | ||
| * or any other object type with an associated meta table. | ||
| * @return mixed In order not to short-circuit `get_metadata()`. Generally, this is `null`, but it could be | ||
| * another value if filtered by a plugin. | ||
| */ | ||
| public function lazyload_post_meta( $check, $object_id, $meta_key, $single, $meta_type ) { | ||
| if ( empty( $this->pending_objects[ $meta_type ] ) ) { | ||
| return $check; | ||
| } | ||
|
|
||
| $object_ids = array_keys( $this->pending_objects[ $meta_type ] ); | ||
| if ( $object_id && ! in_array( $object_id, $object_ids, true ) ) { | ||
| return $check; | ||
|
||
| } | ||
|
|
||
| update_meta_cache( $meta_type, $object_ids ); | ||
|
|
||
| // No need to run again for this set of objects. | ||
| $this->reset_queue( $meta_type ); | ||
|
|
||
| return $check; | ||
| } | ||
|
|
||
| /** | ||
| * Lazy-loads meta for queued objects. | ||
| * | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -648,6 +648,7 @@ public function fill_query_vars( $query_vars ) { | |||||
| * @since 5.3.0 Introduced the `$meta_type_key` parameter. | ||||||
| * @since 6.1.0 Introduced the `$update_menu_item_cache` parameter. | ||||||
| * @since 6.2.0 Introduced the `$search_columns` parameter. | ||||||
| * @since 6.8.0 Introduced the `$lazy_load_post_meta` parameter. | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This needs updating now. |
||||||
| * | ||||||
| * @param string|array $query { | ||||||
| * Optional. Array or string of Query parameters. | ||||||
|
|
@@ -784,6 +785,9 @@ public function fill_query_vars( $query_vars ) { | |||||
| * disable cache priming for term meta, so that each | ||||||
| * get_term_meta() call will hit the database. | ||||||
| * Defaults to the value of `$update_post_term_cache`. | ||||||
| * @type bool $lazy_load_post_meta Whether to lazy-load post meta. Setting to false will | ||||||
| * disable cache priming for post meta, so that each | ||||||
| * get_post_meta() call will hit the database. | ||||||
| * @type int $w The week number of the year. Default empty. Accepts numbers 0-53. | ||||||
| * @type int $year The four-digit year. Default empty. Accepts any four-digit year. | ||||||
| * } | ||||||
|
|
@@ -1967,6 +1971,12 @@ public function get_posts() { | |||||
| $q['update_post_meta_cache'] = true; | ||||||
| } | ||||||
|
|
||||||
| if ( ! isset( $q['lazy_load_post_meta'] ) ) { | ||||||
| $q['lazy_load_post_meta'] = false; | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Per the DocBlock, shouldn't this be the following?
Suggested change
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rather than just removing the docs about the default in 4e3a8ec, can it be updated to be accurate?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @joemcgill I am not sure what is being asked here. |
||||||
| } elseif ( $q['lazy_load_post_meta'] ) { | ||||||
| $q['update_post_meta_cache'] = false; | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For term meta, lazy loading requires term cache priming. Can you add an inline comment about why this is different? Also, the Docblock states...
...but that doesn't seem to be implemented.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @spacedmonkey it still doesn't seem that this comment was addressed:
Am I missing something?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @joemcgill I have added some inline comments. |
||||||
| } | ||||||
|
|
||||||
| if ( ! isset( $q['post_type'] ) ) { | ||||||
| if ( $this->is_search ) { | ||||||
| $q['post_type'] = 'any'; | ||||||
|
|
@@ -3243,6 +3253,10 @@ public function get_posts() { | |||||
| $this->post_count = count( $this->posts ); | ||||||
| $this->set_found_posts( $q, $limits ); | ||||||
|
|
||||||
| if ( $q['lazy_load_post_meta'] ) { | ||||||
| wp_lazyload_post_meta( $this->posts ); | ||||||
| } | ||||||
|
|
||||||
| if ( $q['cache_results'] && $id_query_is_cacheable ) { | ||||||
| $cache_value = array( | ||||||
| 'posts' => $this->posts, | ||||||
|
|
@@ -3281,6 +3295,10 @@ public function get_posts() { | |||||
| // Prime post parent caches, so that on second run, there is not another database query. | ||||||
| wp_cache_add_multiple( $post_parents_cache, 'posts' ); | ||||||
|
|
||||||
| if ( $q['lazy_load_post_meta'] ) { | ||||||
| wp_lazyload_post_meta( $post_ids ); | ||||||
| } | ||||||
|
|
||||||
| if ( $q['cache_results'] && $id_query_is_cacheable ) { | ||||||
| $cache_value = array( | ||||||
| 'posts' => $post_ids, | ||||||
|
|
@@ -3535,6 +3553,7 @@ public function get_posts() { | |||||
| 'update_post_meta_cache' => $q['update_post_meta_cache'], | ||||||
| 'update_post_term_cache' => $q['update_post_term_cache'], | ||||||
| 'lazy_load_term_meta' => $q['lazy_load_term_meta'], | ||||||
| 'lazy_load_post_meta' => $q['lazy_load_post_meta'], | ||||||
| ) | ||||||
| ); | ||||||
|
|
||||||
|
|
@@ -3592,6 +3611,11 @@ public function get_posts() { | |||||
| wp_queue_posts_for_term_meta_lazyload( $this->posts ); | ||||||
| } | ||||||
|
|
||||||
| if ( $q['lazy_load_post_meta'] ) { | ||||||
| $post_ids = wp_list_pluck( $this->posts, 'ID' ); | ||||||
| wp_lazyload_post_meta( $post_ids ); | ||||||
| } | ||||||
|
|
||||||
| return $this->posts; | ||||||
| } | ||||||
|
|
||||||
|
|
@@ -3692,6 +3716,9 @@ public function the_post() { | |||||
| $post_ids = array_filter( $post_ids ); | ||||||
| if ( $post_ids ) { | ||||||
| _prime_post_caches( $post_ids, $this->query_vars['update_post_term_cache'], $this->query_vars['update_post_meta_cache'] ); | ||||||
| if ( $this->query_vars['lazy_load_post_meta'] ) { | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This changeset [59993] brought major changes in this section. |
||||||
| wp_lazyload_post_meta( $post_ids ); | ||||||
| } | ||||||
| } | ||||||
| $post_objects = array_map( 'get_post', $this->posts ); | ||||||
| update_post_author_caches( $post_objects ); | ||||||
|
|
@@ -4880,6 +4907,7 @@ protected function generate_cache_key( array $args, $sql ) { | |||||
| $args['cache_results'], | ||||||
| $args['fields'], | ||||||
| $args['lazy_load_term_meta'], | ||||||
| $args['lazy_load_post_meta'], | ||||||
| $args['update_post_meta_cache'], | ||||||
| $args['update_post_term_cache'], | ||||||
| $args['update_menu_item_cache'], | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| <?php | ||
|
|
||
| /** | ||
| * @group query | ||
| * @group meta | ||
| */ | ||
| class Tests_Lazy_Load_Post_Meta extends WP_UnitTestCase { | ||
| /** | ||
| * Post IDs. | ||
| * | ||
| * @var int[] | ||
| */ | ||
| private static $post_ids = array(); | ||
|
|
||
| public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) { | ||
| // Register CPT for use with shared fixtures. | ||
| register_post_type( 'wptests_pt' ); | ||
|
|
||
| self::$post_ids = $factory->post->create_many( 5, array( 'post_type' => 'wptests_pt' ) ); | ||
| foreach ( self::$post_ids as $post_id ) { | ||
| update_post_meta( $post_id, 'foo', 'bar' ); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * @dataProvider data_lazy_load_post_meta | ||
| * @ticket 57496 | ||
| */ | ||
| public function test_lazy_load_post_meta( $query_args ) { | ||
| wp_cache_delete_multiple( self::$post_ids, 'posts' ); | ||
| wp_cache_delete_multiple( self::$post_ids, 'post_meta' ); | ||
| $action1 = new MockAction(); | ||
| $action2 = new MockAction(); | ||
| add_filter( 'update_post_metadata_cache', array( $action1, 'filter' ), 10, 2 ); | ||
| add_action( 'metadata_lazyloader_queued_objects', array( $action2, 'action' ) ); | ||
|
|
||
| new WP_Query( $query_args ); | ||
|
|
||
| $args1 = $action1->get_args(); | ||
| $args2 = $action2->get_args(); | ||
| $last = end( $args2 ); | ||
| $this->assertSameSets( self::$post_ids, $last[0], 'wp_lazyload_post_meta() was not executed.' ); | ||
| $this->assertSameSets( array(), $args1, 'update_meta_cache() was executed.' ); | ||
| $num_queries = get_num_queries(); | ||
| get_post_meta( self::$post_ids[0], 'foo', true ); | ||
| $this->assertSame( $num_queries + 1, get_num_queries(), 'wp_lazyload_post_meta() was not executed.' ); | ||
| $args1 = $action1->get_args(); | ||
| $last = end( $args1 ); | ||
| $this->assertSameSets( self::$post_ids, $last[1], 'update_meta_cache() was not executed.' ); | ||
| } | ||
|
|
||
| /** | ||
| * Provides test data for lazy loading post metadata. | ||
| * | ||
| * @return array | ||
| */ | ||
| public function data_lazy_load_post_meta() { | ||
| return array( | ||
| 'lazy load post meta' => array( | ||
| array( | ||
| 'post_type' => 'wptests_pt', | ||
| 'lazy_load_post_meta' => true, | ||
| ), | ||
| ), | ||
| 'lazy load post meta fields id' => array( | ||
| array( | ||
| 'post_type' => 'wptests_pt', | ||
| 'fields' => 'ids', | ||
| 'lazy_load_post_meta' => true, | ||
| ), | ||
| ), | ||
| 'lazy load post meta fields id=>parent' => array( | ||
| array( | ||
| 'post_type' => 'wptests_pt', | ||
| 'fields' => 'id=>parent', | ||
| 'lazy_load_post_meta' => true, | ||
| ), | ||
| ), | ||
| 'lazy load post meta - update_post_meta_cache true' => array( | ||
| array( | ||
| 'post_type' => 'wptests_pt', | ||
| 'update_post_meta_cache' => true, | ||
| 'lazy_load_post_meta' => true, | ||
| ), | ||
| ), | ||
| 'lazy load post meta - update_post_meta_cache false' => array( | ||
| array( | ||
| 'post_type' => 'wptests_pt', | ||
| 'update_post_meta_cache' => false, | ||
| 'lazy_load_post_meta' => true, | ||
| ), | ||
| ), | ||
| 'lazy load post meta - cache_results false' => array( | ||
| array( | ||
| 'post_type' => 'wptests_pt', | ||
| 'cache_results' => false, | ||
| 'lazy_load_post_meta' => true, | ||
| ), | ||
| ), | ||
| ); | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.