Make WordPress Core

Opened 9 months ago

Last modified 7 weeks ago

#63021 reopened enhancement

Lazy load user meta

Reported by: spacedmonkey's profile spacedmonkey Owned by: spacedmonkey's profile spacedmonkey
Milestone: 7.0 Priority: normal
Severity: normal Version: 4.4
Component: Users Keywords: has-patch has-unit-tests needs-testing needs-dev-note dev-feedback
Focuses: performance Cc:

Description

Break out ticket from #58001.

WordPress already supports lazy loading for blog, comment, and term meta, significantly improving performance by reducing unnecessary database queries. However, user meta is still loaded immediately, which can lead to inefficiencies, especially on sites with large user bases or extensive user meta data.

Proposal:

This ticket proposes introducing a new wp_lazyload_user_meta() function to facilitate lazy loading of user meta. This function will be used within:

  • cache_users() to defer loading user meta until it’s explicitly requested.
  • The WP_User_Query class to optimise user queries and prevent unnecessary meta data retrieval.

Benefits:

  • Reduces the number of unnecessary database queries.
  • Improves performance, particularly for sites with many users.
  • Aligns user meta handling with existing lazy-loaded metadata (blogs, comments, terms).
  • Enhances consistency and efficiency across WordPress meta data handling.

Implementation Considerations:

  • wp_lazyload_user_meta( array $user_ids ) will preload user meta into cache but defer its retrieval until explicitly accessed.
  • Ensure backward compatibility by preserving expected behaviour for get_user_meta().
  • Modify cache_users() and WP_User_Query to use wp_lazyload_user_meta() instead of immediately fetching meta.
  • Evaluate and address potential edge cases, such as bulk user queries and caching mechanisms.

Follow on from #58185 #57801, #57496 #57645

Attachments (2)

63021-lazyload-user-meta.diff (2.2 KB) - added by sachinrajcp123 4 months ago.
Screenshot 2025-09-19 at 15.15.54.png (305.1 KB) - added by spacedmonkey 3 months ago.
2019 theme - Display name, lazily loaded.

Download all attachments as: .zip

Change History (28)

This ticket was mentioned in PR #8411 on WordPress/wordpress-develop by @spacedmonkey.


9 months ago
#1

  • Keywords has-patch has-unit-tests added

Introduce the wp_lazyload_user_meta function to queue user metadata for lazy-loading, optimizing user meta retrieval. Update related functions, tests, and metadata lazyloader to support this functionality, ensuring improved performance and consistency.

Trac ticket: https://core.trac.wordpress.org/ticket/63021

This ticket was mentioned in Slack in #core-performance by spacedmonkey. View the logs.


9 months ago

This ticket was mentioned in Slack in #core-performance by flixos90. View the logs.


9 months ago

#4 @spacedmonkey
9 months ago

  • Milestone changed from Awaiting Review to 6.8
  • Owner set to flixos90
  • Status changed from new to assigned

Assigning to @flixos90 for review.

#5 @flixos90
9 months ago

  • Milestone changed from 6.8 to 6.9

Similar to the related #58001, this needs to be punted to the 6.9 milestone. I don't think it requires early though as there are fewer risks with this change.

This ticket was mentioned in Slack in #core-performance by spacedmonkey. View the logs.


8 months ago

This ticket was mentioned in Slack in #core-performance by spacedmonkey. View the logs.


7 months ago

#8 @sachinrajcp123
4 months ago

Introduce wp_lazyload_user_meta() and update cache_users() and WP_User_Query to defer loading user meta until needed, improving performance on large sites.

This ticket was mentioned in Slack in #core-performance by spacedmonkey. View the logs.


3 months ago

#10 @westonruter
3 months ago

Question: How often are users queried in core without also getting the meta? For example, things as basic to a user such as display_name are stored not in wp_users but wp_usermeta. If most every query will need wp_usermeta, then adding lazy-loading will end up causing more queries not fewer, right? If so, then should this lazy-loading be opt-in and disabled by default?

This ticket was mentioned in Slack in #core by welcher. View the logs.


3 months ago

#12 @welcher
3 months ago

  • Keywords needs-testing added

#13 @welcher
3 months ago

  • Keywords needs-dev-note added

#14 @welcher
3 months ago

  • Keywords dev-feedback added

This ticket was mentioned in Slack in #core-performance by westonruter. View the logs.


3 months ago

#16 @westonruter
3 months ago

  • Owner changed from flixos90 to spacedmonkey

@spacedmonkey
3 months ago

2019 theme - Display name, lazily loaded.

#17 @spacedmonkey
3 months ago

@westonruter I did some testing on some of block and classic themes. As you can see, if in 2019, I am seeing the user meta loaded if you have an author block in content. Once this block is removed, I do not see the author meta loading.

In short, if you do render display name or other data that is loaded from user meta, the lazy loading is working, otherwise it is not loaded.

This change, breaks nothing but it only of benefit if you do not load user capabilties or display name.

#18 @spacedmonkey
2 months ago

All feedback has been actioned and PR has been rebased.

@westonruter commented on PR #8411:


2 months ago
#19

@spacedmonkey I'm trying to follow your testing instructions, but I'm having trouble.

  1. I've activated the Twenty Nineteen theme.
  2. I've created two pages: One without an Author block and another with an Author block.
  3. I only have Query Monitor active.
  4. I'm viewing Page template.

# Trunk

Without Author Block | With the Author Block

--

https://github.com/user-attachments/assets/65b90306-7319-496c-9ae4-c027b70d2c10 | https://github.com/user-attachments/assets/738f01bb-fef8-4f3e-b9a9-a3ada0c9e240

# PR

Without Author Block | With the Author Block

--

https://github.com/user-attachments/assets/2d54a6ce-0518-418e-a200-9d7edd441f7e | https://github.com/user-attachments/assets/2e060bd1-fbe8-4389-a773-72b5d72025b5

👉🏻 In all cases, I see the same count of 21 queries. What am I missing?

@spacedmonkey commented on PR #8411:


2 months ago
#20

@westonruter Sorry for the confused but to see the benefit, this must first be committed.

Now it is committed and this PR rebased, I am seeing the benefit.
Trunk | PR

--

https://github.com/user-attachments/assets/9651f17f-eb4f-43c1-b833-a02e8d0de56e73 queries | https://github.com/user-attachments/assets/cb922faf-3287-4137-99dc-0bbd617b10b572 queries
https://github.com/user-attachments/assets/114a2a61-3953-43a1-882a-dcd2be38f6a5 67 queries| https://github.com/user-attachments/assets/7c40bfbd-bb0f-437f-9c44-438eaa2089f9 66 queries

I am seeing one less query on a number of different types of page load.

The query I am no longer seeing this one.
https://github.com/user-attachments/assets/725e9cfc-dc8c-44b8-a243-fb092e50bfbb

This means 28 less rows of user meta loaded. For sites with lots of user meta or multisite, this could be a massive win.

#21 @westonruter
7 weeks ago

  • Keywords commit added

#22 @spacedmonkey
7 weeks ago

  • Resolution set to fixed
  • Status changed from assigned to closed

In 60989:

Users: Lazy-load user meta.

In [36566], a framework for lazily loading metadata was introduced, initially supporting term and comment meta. This commit extends that support to user meta.

User meta can contain a large amount of data that is not always needed, particularly on the front end. To address this, cache_users() now calls the new function wp_lazyload_user_meta(). This function accepts an array of user IDs and adds them to the queue of metadata to be lazily loaded.

Follows on from [55671], [55747].

Props spacedmonkey, westonruter.
Fixes #63021.

@spacedmonkey commented on PR #8411:


7 weeks ago
#23

Committed in [60989]

This ticket was mentioned in Slack in #core by ella. View the logs.


7 weeks ago

#25 @davidbaumwald
7 weeks ago

In 61038:

Users: Revert Lazy-load user meta.

With [60915] reverted, this changeset is also being reverted to resolve test failures due to common code.

Reverts [60989].

Follow-up to [61037].

Props jorbin, ellatrix, spacedmonkey.
See #63021, #58001.

#26 @johnbillion
7 weeks ago

  • Keywords commit removed
  • Milestone changed from 6.9 to 7.0
  • Resolution fixed deleted
  • Status changed from closed to reopened
Note: See TracTickets for help on using tickets.