Make WordPress Core

Changeset 47359


Ignore:
Timestamp:
02/25/2020 01:40:52 PM (5 years ago)
Author:
SergeyBiryukov
Message:

Script Loader: Improve performance of wp_script_is() for scripts registered with complex dependencies.

This switches WP_Dependencies::recurse_deps() from recursively checking the same handles over and over again to keep a flattened array of queued items and their dependencies for faster lookup in WP_Dependencies::query().

Props superdav42.
Fixes #46469.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class.wp-dependencies.php

    r47170 r47359  
    7575     */
    7676    public $group = 0;
     77
     78    /**
     79     * Cached lookup array of flattened queued items and dependencies.
     80     *
     81     * @since 5.4.0
     82     * @var array
     83     */
     84    private $all_queued_deps;
    7785
    7886    /**
     
    303311        foreach ( (array) $handles as $handle ) {
    304312            $handle = explode( '?', $handle );
    305             if ( ! in_array( $handle[0], $this->queue ) && isset( $this->registered[ $handle[0] ] ) ) {
     313
     314            if ( ! in_array( $handle[0], $this->queue, true ) && isset( $this->registered[ $handle[0] ] ) ) {
    306315                $this->queue[] = $handle[0];
     316
     317                // Reset all dependencies so they must be recalculated in recurse_deps().
     318                $this->all_queued_deps = null;
     319
    307320                if ( isset( $handle[1] ) ) {
    308321                    $this->args[ $handle[0] ] = $handle[1];
     
    326339        foreach ( (array) $handles as $handle ) {
    327340            $handle = explode( '?', $handle );
    328             $key    = array_search( $handle[0], $this->queue );
     341            $key    = array_search( $handle[0], $this->queue, true );
     342
    329343            if ( false !== $key ) {
     344                // Reset all dependencies so they must be recalculated in recurse_deps().
     345                $this->all_queued_deps = null;
     346
    330347                unset( $this->queue[ $key ] );
    331348                unset( $this->args[ $handle[0] ] );
     
    335352
    336353    /**
    337      * Recursively search the passed dependency tree for $handle
     354     * Recursively search the passed dependency tree for $handle.
    338355     *
    339356     * @since 4.0.0
     
    344361     */
    345362    protected function recurse_deps( $queue, $handle ) {
    346         foreach ( $queue as $queued ) {
    347             if ( ! isset( $this->registered[ $queued ] ) ) {
    348                 continue;
    349             }
    350 
    351             if ( in_array( $handle, $this->registered[ $queued ]->deps ) ) {
    352                 return true;
    353             } elseif ( $this->recurse_deps( $this->registered[ $queued ]->deps, $handle ) ) {
    354                 return true;
    355             }
    356         }
    357 
    358         return false;
     363        if ( isset( $this->all_queued_deps ) ) {
     364            return isset( $this->all_queued_deps[ $handle ] );
     365        }
     366
     367        $all_deps = array_fill_keys( $queue, true );
     368        $queues   = array();
     369        $done     = array();
     370
     371        while ( $queue ) {
     372            foreach ( $queue as $queued ) {
     373                if ( ! isset( $done[ $queued ] ) && isset( $this->registered[ $queued ] ) ) {
     374                    $deps = $this->registered[ $queued ]->deps;
     375                    if ( $deps ) {
     376                        $all_deps += array_fill_keys( $deps, true );
     377                        array_push( $queues, $deps );
     378                    }
     379                    $done[ $queued ] = true;
     380                }
     381            }
     382            $queue = array_pop( $queues );
     383        }
     384
     385        $this->all_queued_deps = $all_deps;
     386
     387        return isset( $this->all_queued_deps[ $handle ] );
    359388    }
    360389
     
    380409            case 'enqueued':
    381410            case 'queue':
    382                 if ( in_array( $handle, $this->queue ) ) {
     411                if ( in_array( $handle, $this->queue, true ) ) {
    383412                    return true;
    384413                }
     
    387416            case 'to_do':
    388417            case 'to_print': // Back compat.
    389                 return in_array( $handle, $this->to_do );
     418                return in_array( $handle, $this->to_do, true );
    390419
    391420            case 'done':
    392421            case 'printed': // Back compat.
    393                 return in_array( $handle, $this->done );
     422                return in_array( $handle, $this->done, true );
    394423        }
    395424        return false;
Note: See TracChangeset for help on using the changeset viewer.