Skip to content
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

wpseo_init options data #21228

Open
1 task
bmcpherson-malware opened this issue Mar 12, 2024 · 2 comments
Open
1 task

wpseo_init options data #21228

bmcpherson-malware opened this issue Mar 12, 2024 · 2 comments

Comments

@bmcpherson-malware
Copy link

bmcpherson-malware commented Mar 12, 2024

  • [x ] I've read and understood the contribution guidelines.
  • [ x] I've searched for any related issues and avoided creating a duplicate issue.

Please give us a description of what happened

We've taken note that the wpseo plugin appears to exhibit heavy database interaction during its initialization routine. Specifically, the init function stands out as a high-utilization process, primarily due to the get_all function.

This function is used to retrieve a vast number of options, and in scenarios where the data is not cached, it can lead to significant performance bottlenecks due to the multiple database requests it generates.

Upon profiling the plugin, we discovered that the get_all function within the WPSEO_Options class methodically pulls a number of option entries from the WordPress database. The absence of a caching mechanism at this level means that each page load calls the database afresh to fetch these options. This is particularly problematic on high-traffic sites or those with limited server resources, as the cumulative effect can cause substantial resource strain and slow down response times. This excessive querying can not only decrease the site's performance but also impact overall server health, leading to decreased scalability and potential downtime.

Suggestion
To mitigate the load on the database and enhance the performance of the wpseo plugin, a caching mechanism should be introduced for the options retrieved by the get_all function. The recommended approach involves caching this data for a set duration—such as one hour—to reduce the frequency of database queries while ensuring that the options remain up-to-date.
We suggest using the following code to replace the get_all function

public static function get_all() {
$_cached_key = '_wpseo_getalloptions'; $_cached_result = wp_cache_get( $_cached_key, 'WPSEO' ); static::$option_values = [];
       // Handle Returned Cache
       if ( !empty( $_cached_result ) ) {
           if ( 'WPSEO_DND' === $_cached_result ) $_cached_result = []; // when "Do Not
Disturb"
           static::$option_values = $_cached_result;
       }
       // Handle Missing Cache
       else if ( empty( $_cached_result ) ) {
           $_cached_result = static::get_options( static::get_option_names() );
           if ( empty( $_cached_result ) ) {
                  $_cached_result = 'WPSEO_DND';
           }
           wp_cache_set( $_cached_key, $_cached_result, 'WPSEO', HOUR_IN_SECONDS );
           static::$option_values = $_cached_result;
       }
       return static::$option_values;
   }

While the data will be cached, the clearing can be handled by manually deleting the cache using the key wpseo_getalloptions, or by wiping all related cache entries under the group WPSEO. Implementing such a caching system would improve the loading times and reduce the load on the database, resulting in better scalability and a more responsive site experience.

Technical info

  • Which browser is affected (or browsers):
  • [x ] Chrome
  • [ x] Firefox
  • [ x] Safari
  • Other:

Used versions

  • Operating system: Linux 5.10.0-26-amd64 x86_64
  • PHP version: 8.1.27 (Supports 64bit values)
  • WordPress version: 6.4.3
  • Yoast SEO version: 21.7
@josevarghese
Copy link
Contributor

Hi @bmcpherson-malware

Thanks for using the Yoast SEO plugin and also for creating the issue.

I've forwarded this information to our development team to take a closer look. We will keep you posted.

@leonidasmi
Copy link
Contributor

Hi there @bmcpherson-malware and thank you for the report.

Your caching proposal attempts to decrease the database queries with each page load, that are due to the get_all() function. But:

  1. The get_all() function works mostly with autoloaded options. Which means that those options have already been loaded in memory by WordPress, so there's no really queries to be prevented by your approach. We're interested to know if you find the contrary in your tests though, so let us know if that's the case.
  2. For completeness sake, even if we had queries to be saved from the caching approach, we would need some cache invalidation mechanism, so as to not rely solely on cache expiration to prevent serving stale data. So the final solution for caching around the load of our options would be much more involved than just storing them in cache.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants