Opened 5 weeks ago
Last modified 3 days ago
#61849 new enhancement
Improve performance and memory usage of wp_list_post_revisions() / wp_get_post_revisions()
Reported by: | Toru | Owned by: | |
---|---|---|---|
Milestone: | 6.7 | Priority: | normal |
Severity: | normal | Version: | |
Component: | Revisions | Keywords: | has-patch reporter-feedback |
Focuses: | performance | Cc: |
Description
I came across an issue where opening a Page in editor causing Fatal error of Allowed memory size of 268435456 bytes exhausted
. Trouble shooting has lead me to find that there were over 4000 revisions (!) for this Page, causing slow query and high memory usage. However, xhprofiling revealed that higher memory usage was actually update_meta_cache()
.
Putting aside why on earth there were over 4000 revisions...
After studying [wp_post_revisions()](https://developer.wordpress.org/reference/functions/wp_list_post_revisions/), I think it is unnecessary to do cache priming here. We can improve the performance, and try to lower the possibility of exhausting memory.
wp_list_post_revisions()
calls wp_get_post_revisions()
, which calls get_children()
. WP_Post object returned by wp_get_post_revisions()
is substituted into $revisions
, but post meta data are not needed to create the list of revision links. Term data are also not needed.
So for [defaults args here](https://github.com/WordPress/WordPress/blob/ddab80be2c0623cc8971a75180de40343f839f71/wp-includes/revision.php#L667-L671)
$defaults = array( 'order' => 'DESC', 'orderby' => 'date ID', 'check_enabled' => true, );
adding
'update_post_meta_cache' => false, 'update_post_term_cache' => false,
should improve performance. On my local testing of above mentioned client site, this haved the memory usage.
Change History (10)
This ticket was mentioned in PR #7171 on WordPress/wordpress-develop by @Toru.
5 weeks ago
#1
- Keywords has-patch added
#2
@
5 weeks ago
- Milestone changed from Awaiting Review to 6.7
Looks reasonable to me, thanks for the patch!
#3
@
5 weeks ago
A further thought. Substituted $revisions
doesn't need to be object with all the field values? I think it only needs to be array of post ids. We can pass 'fields' => 'ids'
for $args
at line 1994.
Note, wp_get_post_revisions()
is called multiple times here. Once in line 1994, and in the foreach loop called by wp_is_post_autosave()
#4
@
5 weeks ago
Updated PR with a commit for changing how wp_list_post_revisions()
use wp_get_post_revisions()
.
https://github.com/WordPress/wordpress-develop/pull/7171/commits/141f8d017322921f615884bce4f0e82e0e2d978c
This ticket was mentioned in Slack in #core-performance by mukeshpanchal27. View the logs.
4 weeks ago
#6
@
4 weeks ago
@Toru - Hi, thanks for opening the ticket. This looks like a duplicate of https://core.trac.wordpress.org/ticket/45366 where a similar change to the query (only getting ids) is suggested. I'm going to close that older ticket and we can continue working on this here.
My concern with changing to only retrieving the IDs is some sort of breakage, not priming caches seems like a safer change. Also, since the underlying functions aren't going to call the database again to get the full revision data (or at least title, date) - I think these would already be cached, but if we only get ids here they will not be cached.
Did you see an actual performance improvement when swiching to IDs only?
I came across an issue where opening a Page in editor causing Fatal error of Allowed memory size of 268435456 bytes exhausted.
I am curious how you triggered this, do you have a plugin that calls wp_list_post_revisions
? the only use I found in core is for a revisions list widget.
Set
update_post_meta_cache
andupdate_post_term_cache
to false, for to use as default$args
to be passed toget_children()
.Trac ticket: https://core.trac.wordpress.org/ticket/61849