Make WordPress Core

Opened 6 years ago

Last modified 8 hours ago

#43160 accepted enhancement

Reduce wp-admin/update-core.php load time by half

Reported by: lano1106's profile lano1106 Owned by: pbearne's profile pbearne
Milestone: 6.7 Priority: normal
Severity: normal Version: 4.9.2
Component: Upgrade/Install Keywords: has-patch
Focuses: administration, performance Cc:

Description

I had this problem where loading this page was taking over a minute.
It turns out that this is caused by premium plugins that makes remote calls to validate license and/or verify the existence of update.

My whole journey is documented here:
https://wordpress.org/support/topic/displaying-wp-admin-update-core-php-takes-about-50-secs/

There is not much that can be done about that but this can be mitigated a lot when you realise that wp_update_plugins() calls set_site_transient() twice and this is where the expensive hook calls are made.

So here is my attempt to improve the situation:

$ diff wp-includes/option.php{.orig,}
1721a1722,1759
>  * Set/update the value of a site transient without calling the sometimes expensive hooks.
>  *
>  * This is particularly for the special case of wp_update_plugins() where set_site_transient() was called twice
>  * and the first time was only for setting up the last_checked update_plugins option.
>  *
>  * @since 4.9.2
>  *
>  * @see wp_update_plugins()
>  *
>  * @param string $transient  Transient name. Expected to not be SQL-escaped. Must be
>  *                           167 characters or fewer in length.
>  * @param mixed  $value      Transient value. Expected to not be SQL-escaped.
>  * @param int    $expiration Optional. Time until expiration in seconds. Default 0 (no expiration).
>  * @return bool False if value was not set and true if value was set.
>  */
> function set_site_transient_nohook( $transient, $value, $expiration = 0 ) {
> 
>     $expiration = (int) $expiration;
> 
> 	if ( wp_using_ext_object_cache() ) {
> 		$result = wp_cache_set( $transient, $value, 'site-transient', $expiration );
> 	} else {
> 		$transient_timeout = '_site_transient_timeout_' . $transient;
> 		$option = '_site_transient_' . $transient;
> 		if ( false === get_site_option( $option ) ) {
> 			if ( $expiration )
> 				add_site_option( $transient_timeout, time() + $expiration );
> 			$result = add_site_option( $option, $value );
> 		} else {
> 			if ( $expiration )
> 				update_site_option( $transient_timeout, time() + $expiration );
> 			$result = update_site_option( $option, $value );
> 		}
> 	}
> 	return $result;
> }
> 
> /**
1767,1781c1805
< 	if ( wp_using_ext_object_cache() ) {
< 		$result = wp_cache_set( $transient, $value, 'site-transient', $expiration );
< 	} else {
< 		$transient_timeout = '_site_transient_timeout_' . $transient;
< 		$option = '_site_transient_' . $transient;
< 		if ( false === get_site_option( $option ) ) {
< 			if ( $expiration )
< 				add_site_option( $transient_timeout, time() + $expiration );
< 			$result = add_site_option( $option, $value );
< 		} else {
< 			if ( $expiration )
< 				update_site_option( $transient_timeout, time() + $expiration );
< 			$result = update_site_option( $option, $value );
< 		}
< 	}
---
> 	$result = set_site_transient_nohook( $transient, $value, $expiration );
$ diff wp-includes/update.php{.orig,}
68c68
< 	set_site_transient( 'update_core', $current );
---
> 	set_site_transient_nohook( 'update_plugins', $current );

Attachments (1)

a43160.diff (3.2 KB) - added by kitchin 6 years ago.
Here it is as a patch against trunk. Not tested.

Download all attachments as: .zip

Change History (6)

@kitchin
6 years ago

Here it is as a patch against trunk. Not tested.

#1 @lano1106
6 years ago

Hi, I have new info concerning my wp-admin/update-core.php slowness issue. It is caused by the plugin Ad Inserter Pro (author contacted) who does this:

<?php
add_filter ('http_headers_useragent', 'ai_http_headers_useragent');

function ai_http_headers_useragent ($useragent) {

 $useragent = get_bloginfo ('url');

 return $useragent;

}

This appears to disrupt all the other premium plugins when they contact their servers to check the license validity. One of the things that they do remotely is to authenticate the request by checking the user-agent header field. By messing with it, it disrupts a LOT of stuff. and makes a lot of things VERY slow.

http_headers_useragent filter hook appears to be VERY VERY risky hook...

Last edited 6 years ago by lano1106 (previous) (diff)

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


6 years ago

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


8 hours ago
#3

  • Keywords has-patch added

This commit refactors the transient API to include a non-hook version named, set_site_transient_nohook. This update reduces redundancy in setting transients and creates a more streamlined, efficient operation in option.php. Additionally, the update method has been changed in update.php to utilize this new non-hook version.

#4 @pbearne
8 hours ago

  • Owner set to pbearne
  • Status changed from new to accepted

refreshed patch

#5 @pbearne
8 hours ago

  • Milestone changed from Awaiting Review to 6.7
Note: See TracTickets for help on using tickets.