tomusborne / generateblocks

GenerateBlocks is a small collection of lightweight WordPress blocks that can accomplish nearly anything.
https://generateblocks.com
189 stars 18 forks source link

generateblocks_get_block_defaults is horrendously slow on large pages #1129

Closed WalrusSoup closed 4 months ago

WalrusSoup commented 9 months ago

Description

generateblocks_get_block_defaults() - likely due to the array_merge, is causing horrendous slowdowns for us and doubling our page time to render.

If there is no issue with caching this, I think it my be a good idea to cache the value for further uses.

Steps to reproduce

  1. add a ton of blocks to a page filled with content

Expected behavior

generateblocks_get_block_defaults(), ideally, would cache these default options since they are not going to change between the first block and last block on the page.

Actual behavior

generateblocks-slow

With Cache Added (inline)

function generateblocks_get_block_defaults() {
    if(get_transient('generateblocks_defaults')) {
        return apply_filters('generateblocks_defaults', get_transient('generateblocks_defaults'));
    }
    $trueDefaults = [
        'container' => generateblocks_with_global_defaults( GenerateBlocks_Block_Container::defaults() ),
        'buttonContainer' => generateblocks_with_global_defaults( GenerateBlocks_Block_Button_Container::defaults() ),
        'button' => generateblocks_with_global_defaults( GenerateBlocks_Block_Button::defaults() ),
        'gridContainer' => generateblocks_with_global_defaults( GenerateBlocks_Block_Grid::defaults() ),
        'headline' => generateblocks_with_global_defaults( GenerateBlocks_Block_Headline::defaults() ),
        'image' => generateblocks_with_global_defaults( GenerateBlocks_Block_Image::defaults() ),
    ];
    set_transient('generateblocks_defaults', $trueDefaults, 60 * 60 * 24);

    return apply_filters('generateblocks_defaults', $trueDefaults);
}
generateblocks-fast

Around 5.25x faster

References:

...


edit: also in add_filter( 'generateblocks_defaults', 'generateblocks_pro_set_block_defaults' ); we see a lot of slowdown. This looks to be about twice as fast, still testing:

$newDefaults = [
        'container' => [
            'backgroundColorHover' => '',
            'backgroundColorHoverOpacity' => 1,
            'borderColorHover' => '',
            'borderColorHoverOpacity' => 1,
            'textColorHover' => '',
            'useOpacity' => false,
            'opacities' => [],
            'useTransition' => false,
            'transitions' => [],
            'useTransform' => false,
            'transforms' => [],
            'useFilter' => false,
            'filters' => [],
            'useBoxShadow' => false,
            'boxShadows' => [],
            'useTextShadow' => false,
            'textShadows' => [],
            'useAdvBackgrounds' => false,
            'advBackgrounds' => [],
            'linkType' => 'hidden-link',
            'url' => '',
            'hiddenLinkAriaLabel' => '',
            'relNoFollow' => false,
            'target' => false,
            'relSponsored' => false,
            'hideOnDesktop' => false,
            'hideOnTablet' => false,
            'hideOnMobile' => false,
            'useGlobalStyle' => false,
            'globalStyleId' => '',
            'backgroundColorCurrent' => '',
            'textColorCurrent' => '',
            'borderColorCurrent' => ''
        ],
        'buttonContainer' => [
            'hideOnDesktop' => false,
            'hideOnTablet' => false,
            'hideOnMobile' => false,
            'useGlobalStyle' => false,
            'globalStyleId' => ''
        ],
        'button' => [
            'useOpacity' => false,
            'opacities' => [],
            'useTransition' => false,
            'transitions' => [],
            'useTransform' => false,
            'transforms' => [],
            'useFilter' => false,
            'filters' => [],
            'useBoxShadow' => false,
            'boxShadows' => [],
            'useTextShadow' => false,
            'textShadows' => [],
            'hideOnDesktop' => false,
            'hideOnTablet' => false,
            'hideOnMobile' => false,
            'useGlobalStyle' => false,
            'globalStyleId' => ''
        ],
        'headline' => [
            'useOpacity' => false,
            'opacities' => [],
            'useTransition' => false,
            'transitions' => [],
            'useTransform' => false,
            'transforms' => [],
            'useFilter' => false,
            'filters' => [],
            'useBoxShadow' => false,
            'boxShadows' => [],
            'useTextShadow' => false,
            'textShadows' => [],
            'hideOnDesktop' => false,
            'hideOnTablet' => false,
            'hideOnMobile' => false,
            'useGlobalStyle' => false,
            'globalStyleId' => ''
        ],
        'gridContainer' => [
            'hideOnDesktop' => false,
            'hideOnTablet' => false,
            'hideOnMobile' => false,
            'useGlobalStyle' => false,
            'globalStyleId' => ''
        ],
        'image' => [
            'useOpacity' => false,
            'opacities' => [],
            'useTransition' => false,
            'transitions' => [],
            'useTransform' => false,
            'transforms' => [],
            'useFilter' => false,
            'filters' => [],
            'useBoxShadow' => false,
            'boxShadows' => [],
            'useTextShadow' => false,
            'textShadows' => [],
            'hideOnDesktop' => false,
            'hideOnTablet' => false,
            'hideOnMobile' => false,
            'useGlobalStyle' => false,
            'globalStyleId' => ''
        ]
    ];

    return array_merge_recursive($defaults, $newDefaults);
tomusborne commented 9 months ago

Thanks for the feedback here!

When you say tons of blocks, how many are we talking?

Not sure transients are best for this, but maybe object cache?:

function generateblocks_get_block_defaults() {
    $cached_data = wp_cache_get(
        'generateblocks_defaults_cache',
        'generateblocks_cache_group'
    );

    if ( $cached_data ) {
        return $cached_data;
    }

    $defaults = apply_filters(
        'generateblocks_defaults',
        [
            'container' => generateblocks_with_global_defaults( GenerateBlocks_Block_Container::defaults() ),
            'buttonContainer' => generateblocks_with_global_defaults( GenerateBlocks_Block_Button_Container::defaults() ),
            'button' => generateblocks_with_global_defaults( GenerateBlocks_Block_Button::defaults() ),
            'gridContainer' => generateblocks_with_global_defaults( GenerateBlocks_Block_Grid::defaults() ),
            'headline' => generateblocks_with_global_defaults( GenerateBlocks_Block_Headline::defaults() ),
            'image' => generateblocks_with_global_defaults( GenerateBlocks_Block_Image::defaults() ),
        ]
    );

    wp_cache_set(
        'generateblocks_defaults_cache',
        $defaults,
        'generateblocks_cache_group'
    );

    return $defaults;
}
WalrusSoup commented 9 months ago

Good morning,

We're using at least 200 in total, since we use headlines a lot too and the pages are pretty huge. We love generateblocks since it helps us meet our design needs to a T based on figma - but we noticed at some point things just started to slow down and we weren't sure what it was.

For the cache, I'm not a WP dev by trade so the difference is admittedly lost on me - I was just triaging our server response time and found something fast to throw in.

I updated it to the code provided and things are flying 🚀 - it's not even listed now. Just the render, which I expect.

Screenshot 2023-10-16 at 8 18 58 AM

If there is anything I can do to help push this along let so it makes it into the official release let me know. Appreciate the fast response!

tomusborne commented 4 months ago

Just merged this into the upcoming 1.9.0 release.

However, we wanted to be careful with caching these, so we made it opt-in for now.

You can turn it on (when using that branch) like this:

add_filter( 'generateblocks_use_block_defaults_cache', '__return_true' );