WordPress.org

Make WordPress Core

Opened 6 months ago

Last modified 13 days ago

#46469 reviewing defect (bug)

wp_script_is() is super slow

Reported by: superdav42 Owned by: SergeyBiryukov
Milestone: 5.3 Priority: normal
Severity: normal Version: 5.0
Component: Script Loader Keywords: has-patch dev-feedback
Focuses: performance Cc:

Description

Because of the WP_Dependencies::query() recursively transverses scripts' dependencies plugins checking if a script handle has been registered using wp_script_is() can be very slow if scripts are registered with more complex dependencies. This will become more of a problem as more plugins start implementing Gutenberg blocks and register scripts with dependencies on Gutenberg components. As an example this simple plugin will show how the slow down can happen:

<?php
/*
Plugin Name: Show slow deps
*/

add_action(
        'enqueue_block_assets',
        // Some plugins regigister scripts which depend on wordpress components.
        function () {
                wp_register_script(
                        'a-script-handle',
                        'https://www.example.com/somescript.js',
                        array(
                                'wp-element',
                                'wp-blocks',
                                'wp-editor',
                                'wp-components',
                                'wp-data',
                        ),
                        '1.1.1',
                        true
                );
                wp_register_script(
                        'another-script-handle',
                        'https://www.example.com/anotherscript.js',
                        array(
                                'wp-element',
                                'wp-blocks',
                                'wp-editor',
                                'wp-components',
                                'wp-data',
                        ),
                        '1.1.1',
                        true
                );
                wp_register_script(
                        'more-script-handle',
                        'https://www.example.com/anotherscript.js',
                        array(
                                'wp-element',
                                'wp-blocks',
                                'wp-editor',
                                'wp-components',
                                'wp-data',
                        ),
                        '1.1.1',
                        true
                );

                // Same plugin or others check if a script is registered.
                for ( $i = 1; $i < 20; $i++ ) {
                        wp_script_is( 'some-other-plugin-again' ); // This call is super slow.
                }
        }
);

If you installed this plugin and ran a code profiler on it you'd see WP_Dependencies::recurse_deps() being called 50,000+ time and take over 100ms to do so.

The way the recursion happens the same handles will be checked thousands of times. WP_Dependencies should probably be updated to keep a flattened array of scripts which have been queued including each queue script and their deps for faster lookup in WP_Dependencies::query()

Attachments (3)

recurse-deps.patch (3.3 KB) - added by superdav42 6 months ago.
recurse_deps() performance improvements
recurse-deps-fixed.diff (3.3 KB) - added by superdav42 6 months ago.
Fixed issue with diff formatting
recurse-deps-v2.diff (3.3 KB) - added by superdav42 6 months ago.
Fix bug causing false positives

Download all attachments as: .zip

Change History (8)

@superdav42
6 months ago

recurse_deps() performance improvements

@superdav42
6 months ago

Fixed issue with diff formatting

#1 @SergeyBiryukov
6 months ago

  • Milestone changed from Awaiting Review to 5.2
  • Owner set to SergeyBiryukov
  • Status changed from new to reviewing

@superdav42
6 months ago

Fix bug causing false positives

#2 @superdav42
6 months ago

Worth noting that WooCommerce calls wp_script_is() about 50 times in WC_Frontend_Scripts so anyone running almost any version of WC that enqueues a script on the frontend which depends on wp-* will be affected by this slowdown. In WP core this is limited to the edit screen which only performs 1 call to wp_script_is() so the slowdown is not as noticeable.

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


5 months ago

#4 @audrasjb
5 months ago

  • Keywords has-patch dev-feedback added
  • Milestone changed from 5.2 to 5.3

As per today's bug scrub, we are going to move this one to the next Release since beta 3 and RC are approaching.

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


13 days ago

Note: See TracTickets for help on using tickets.