awesomemotive / easy-digital-downloads

Sell digital downloads through WordPress
https://easydigitaldownloads.com
GNU General Public License v2.0
868 stars 472 forks source link

`edd_get_option()` is slow #9743

Open zackkatz opened 5 months ago

zackkatz commented 5 months ago

A close cousin to #9741 ! Same reasoning: a function that's called this many times should be performant. Re-running filters each time it's called is slow.

Calls

The function is called over 65 times on a single front-end page load on my site:

/wp-content/plugins/easy-digital-downloads-pro/includes/gateways/functions.php@110
/wp-content/plugins/easy-digital-downloads-pro/includes/gateways/functions.php@553
/wp-content/plugins/easy-digital-downloads-pro/src/Emails/Base.php@199
/wp-content/plugins/easy-digital-downloads-pro/includes/misc-functions.php@60
/wp-content/plugins/easy-digital-downloads-pro/includes/gateways/stripe/includes/elements/functions.php@12
/wp-content/plugins/easy-digital-downloads-pro/includes/gateways/stripe/includes/class-stripe-connect.php@32
/wp-content/plugins/easy-digital-downloads-pro/includes/misc-functions.php@103
/wp-content/plugins/easy-digital-downloads-pro/includes/gateways/functions.php@134
/wp-content/plugins/easy-digital-downloads-pro/includes/checkout/functions.php@32
/wp-content/plugins/easy-digital-downloads-pro/includes/gateways/stripe/includes/payment-methods/payment-request/functions.php@31
/wp-content/plugins/easy-digital-downloads-pro/includes/gateways/functions.php@194
/wp-content/plugins/edd-recurring/includes/gateways/edd-recurring-stripe.php@81
/wp-content/plugins/edd-recurring/includes/gateways/paypal/functions.php@18
/wp-content/plugins/edd-recurring/includes/gateways/edd-recurring-paypalexpress.php@42
/wp-content/plugins/edd-recurring/src/Legacy/Emails.php@44
/wp-content/plugins/edd-recurring/src/Legacy/Emails.php@48
/wp-content/plugins/edd-recurring/src/Legacy/Emails.php@52
/wp-content/plugins/easy-digital-downloads-pro/src/Licensing/License.php@262
/wp-content/plugins/easy-digital-downloads-pro/includes/tax-functions.php@28
/wp-content/plugins/easy-digital-downloads-pro/includes/scripts.php@49
/wp-content/plugins/edd-all-access/includes/functions/misc-functions.php@545
/wp-content/plugins/easy-digital-downloads-pro/includes/checkout/pages.php@38
/wp-content/plugins/easy-digital-downloads-pro/includes/formatting.php@32
/wp-content/plugins/easy-digital-downloads-pro/includes/formatting.php@33
/wp-content/plugins/easy-digital-downloads-pro/includes/currency/functions.php@81
/wp-content/plugins/easy-digital-downloads-pro/includes/checkout/functions.php@181
/wp-content/plugins/easy-digital-downloads-pro/includes/checkout/functions.php@283
/wp-content/plugins/edd-paypal-pro-express/paypal/edd-functions.php@433
/wp-content/plugins/easy-digital-downloads-pro/includes/blocks/includes/styles.php@27
/wp-content/plugins/easy-digital-downloads-pro/src/Currency/Currency.php@86
/wp-content/plugins/easy-digital-downloads-pro/src/Currency/Currency.php@87
/wp-content/plugins/easy-digital-downloads-pro/src/Currency/Currency.php@88
/wp-content/plugins/easy-digital-downloads-pro/includes/misc-functions.php@125
/wp-content/plugins/easy-digital-downloads-pro/includes/checkout/functions.php@85
/wp-content/plugins/easy-digital-downloads-pro/includes/checkout/functions.php@108
/wp-content/plugins/easy-digital-downloads-pro/includes/checkout/functions.php@167
/wp-content/plugins/easy-digital-downloads-pro/includes/template-functions.php@809
/wp-content/plugins/edd-paypal-commerce-pro/includes/advanced/functions.php@28
/wp-content/plugins/edd-software-licensing/src/Assets/Loader.php@54
/wp-content/plugins/edd-software-licensing/src/Assets/Loader.php@63
/wp-content/plugins/easy-digital-downloads-pro/includes/blocks/includes/forms/recaptcha.php@207
/wp-content/plugins/easy-digital-downloads-pro/includes/blocks/includes/forms/recaptcha.php@208
/wp-content/plugins/easy-digital-downloads-pro/includes/gateways/paypal/class-paypal-api.php@109
/wp-content/plugins/edd-paypal-commerce-pro/includes/payment-method-filters.php@21
/wp-content/plugins/easy-digital-downloads-pro/includes/gateways/stripe/includes/scripts.php@37
/wp-content/plugins/easy-digital-downloads-pro/includes/scripts.php@230
/wp-content/plugins/easy-digital-downloads-pro/includes/template-functions.php@778
/wp-content/plugins/easy-digital-downloads-pro/includes/template-functions.php@779
/wp-content/plugins/easy-digital-downloads-pro/includes/template-functions.php@780
/wp-content/plugins/easy-digital-downloads-pro/includes/template-functions.php@52
/wp-content/plugins/easy-digital-downloads-pro/includes/template-functions.php@92
/wp-content/plugins/easy-digital-downloads-pro/includes/blocks/includes/styles.php@63
/wp-content/plugins/easy-digital-downloads-pro/includes/misc-functions.php@78
/wp-content/plugins/edd-all-access/src/Helpers/DownloadAccessChecker.php@213
/wp-content/plugins/easy-digital-downloads-pro/includes/cart/functions.php@107
/wp-content/plugins/edd-recurring/includes/edd-recurring-checkout.php@475
/wp-content/plugins/edd-recurring/includes/edd-recurring-checkout.php@317
/wp-content/plugins/edd-software-licensing/includes/license-upgrades.php@1133
/wp-content/plugins/edd-all-access/includes/functions/download-form.php@54
/wp-content/plugins/edd-all-access/includes/functions/download-form.php@69
/wp-content/plugins/edd-all-access/includes/functions/download-form.php@172
/wp-content/plugins/edd-all-access/includes/functions/download-form.php@387
/wp-content/plugins/edd-all-access/src/Helpers/DownloadAccessChecker.php@318
/wp-content/plugins/edd-all-access/src/Helpers/DownloadAccessChecker.php@186
/wp-content/plugins/edd-recurring/includes/edd-recurring-checkout.php@359
/wp-content/plugins/edd-recurring/includes/edd-recurring-checkout.php@180
/wp-content/plugins/edd-all-access/includes/functions/misc-functions.php@396
/wp-content/plugins/easy-digital-downloads-pro/includes/users/login.php@213

A potential fix: static caching

By applying a simple static cache, the function fully processes once per request.

Stats

These are numbers generated using the Code Profiler Pro plugin:

Potential downsides to this fix:

Since the filters are currently being run after each call, and the function is called in so many places, perhaps a plugin may want to modify the response from edd_get_option() inside one of the callers and not another. Or hook in and then remove the filter.

These concerns have more validity than the edd_is_checkout() question, which is "is this a checkout page". The edd_get_option() filter is related to options that may be manipulated differently based on the caller.

I'll leave this up to you, but I'll put forward a PR. It's improved speed on my site.

robincornett commented 4 months ago

Hey @zackkatz thank you for submitting this and the supporting research. I agree that this is an area we can look at improving, but we need to ensure that it will work with any kind of filter no matter where it's run. So it may work on a tightly controlled and configured site, but we need to account for the many different ways code interacts with EDD. I'm logging this for us to look into, and we'll keep you updated on our progress.

zackkatz commented 4 months ago

Hi @robincornett, yep, I have zero expectations of a quick merge! I know this is going to require lots of testing.