Changeset 61176
- Timestamp:
- 11/07/2025 06:11:24 AM (2 weeks ago)
- Location:
- trunk
- Files:
-
- 2 edited
-
src/wp-includes/class-wp-scripts.php (modified) (5 diffs)
-
tests/phpunit/tests/dependencies/scripts.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/class-wp-scripts.php
r60948 r61176 998 998 * @since 6.3.0 999 999 * 1000 * @param string $handle The script handle. 1001 * @param string[]|null $eligible_strategies Optional. The list of strategies to filter. Default null. 1002 * @param array<string, true> $checked Optional. An array of already checked script handles, used to avoid recursive loops. 1000 * @param string $handle The script handle. 1001 * @param string[]|null $eligible_strategies Optional. The list of strategies to filter. Default null. 1002 * @param array<string, true> $checked Optional. An array of already checked script handles, used to avoid recursive loops. 1003 * @param array<string, string[]> $stored_results Optional. An array of already computed eligible loading strategies by handle, used to increase performance in large dependency lists. 1003 1004 * @return string[] A list of eligible loading strategies that could be used. 1004 1005 */ 1005 private function filter_eligible_strategies( $handle, $eligible_strategies = null, $checked = array() ) { 1006 private function filter_eligible_strategies( $handle, $eligible_strategies = null, $checked = array(), array &$stored_results = array() ) { 1007 if ( isset( $stored_results[ $handle ] ) ) { 1008 return $stored_results[ $handle ]; 1009 } 1010 1006 1011 // If no strategies are being passed, all strategies are eligible. 1007 1012 if ( null === $eligible_strategies ) { … … 1054 1059 } 1055 1060 1056 $eligible_strategies = $this->filter_eligible_strategies( $dependent, $eligible_strategies, $checked );1057 } 1058 1061 $eligible_strategies = $this->filter_eligible_strategies( $dependent, $eligible_strategies, $checked, $stored_results ); 1062 } 1063 $stored_results[ $handle ] = $eligible_strategies; 1059 1064 return $eligible_strategies; 1060 1065 } … … 1067 1072 * @see WP_Script_Modules::get_highest_fetchpriority_with_dependents() 1068 1073 * 1069 * @param string $handle Script module ID. 1070 * @param array<string, true> $checked Optional. An array of already checked script handles, used to avoid recursive loops. 1074 * @param string $handle Script module ID. 1075 * @param array<string, true> $checked Optional. An array of already checked script handles, used to avoid recursive loops. 1076 * @param array<string, string> $stored_results Optional. An array of already computed max priority by handle, used to increase performance in large dependency lists. 1071 1077 * @return string|null Highest fetch priority for the script and its dependents. 1072 1078 */ 1073 private function get_highest_fetchpriority_with_dependents( string $handle, array $checked = array() ): ?string { 1079 private function get_highest_fetchpriority_with_dependents( string $handle, array $checked = array(), array &$stored_results = array() ): ?string { 1080 if ( isset( $stored_results[ $handle ] ) ) { 1081 return $stored_results[ $handle ]; 1082 } 1083 1074 1084 // If there is a recursive dependency, return early. 1075 1085 if ( isset( $checked[ $handle ] ) ) { … … 1100 1110 if ( $highest_priority_index !== $high_priority_index ) { 1101 1111 foreach ( $this->get_dependents( $handle ) as $dependent_handle ) { 1102 $dependent_priority = $this->get_highest_fetchpriority_with_dependents( $dependent_handle, $checked );1112 $dependent_priority = $this->get_highest_fetchpriority_with_dependents( $dependent_handle, $checked, $stored_results ); 1103 1113 if ( is_string( $dependent_priority ) ) { 1104 1114 $highest_priority_index = max( … … 1112 1122 } 1113 1123 } 1114 1124 $stored_results[ $handle ] = $priorities[ $highest_priority_index ]; // @phpstan-ignore parameterByRef.type (We know the index is valid and that this will be a string.) 1115 1125 return $priorities[ $highest_priority_index ]; 1116 1126 } -
trunk/tests/phpunit/tests/dependencies/scripts.php
r61006 r61176 1437 1437 1438 1438 /** 1439 * Tests that `WP_Scripts::get_highest_fetchpriority_with_dependents()` correctly reuses cached results. 1440 * 1441 * @ticket 64194 1442 * 1443 * @covers WP_Scripts::get_highest_fetchpriority_with_dependents 1444 */ 1445 public function test_highest_fetchpriority_with_dependents_uses_cached_result() { 1446 $wp_scripts = new WP_Scripts(); 1447 $wp_scripts->add( 'd', 'https://example.com/d.js' ); 1448 $wp_scripts->add_data( 'd', 'fetchpriority', 'low' ); 1449 1450 /* 1451 * Simulate a pre-existing `$stored_results` cache entry for `d`. 1452 * If the caching logic works, the function should use this "high" value 1453 * instead of recalculating based on the actual (lower) value. 1454 */ 1455 $stored_results = array( 'd' => 'high' ); 1456 1457 // Access the private method using reflection. 1458 $method = new ReflectionMethod( WP_Scripts::class, 'get_highest_fetchpriority_with_dependents' ); 1459 if ( PHP_VERSION_ID < 80100 ) { 1460 $method->setAccessible( true ); 1461 } 1462 1463 // Pass `$stored_results` BY REFERENCE. 1464 $result = $method->invokeArgs( $wp_scripts, array( 'd', array(), &$stored_results ) ); 1465 1466 $this->assertSame( 1467 'high', 1468 $result, 1469 'Expected "high" indicates that the cached `$stored_results` entry for D was used instead of recalculating.' 1470 ); 1471 } 1472 1473 /** 1439 1474 * Tests that printing a script without enqueueing has the same output as when it is enqueued. 1440 1475 * … … 1533 1568 $expected = str_replace( "'", '"', $expected ); 1534 1569 $this->assertSame( $expected, $output, 'Scripts registered with no strategy assigned, and who have no dependencies, should have no loading strategy attributes printed.' ); 1570 } 1571 1572 /** 1573 * Tests that `WP_Scripts::filter_eligible_strategies()` correctly reuses cached results. 1574 * 1575 * @ticket 64194 1576 * 1577 * @covers WP_Scripts::filter_eligible_strategies 1578 */ 1579 public function test_filter_eligible_strategies_uses_cached_result() { 1580 $wp_scripts = new WP_Scripts(); 1581 $wp_scripts->add( 'd', 'https://example.com/d.js' ); 1582 $wp_scripts->add_data( 'd', 'strategy', 'defer' ); 1583 1584 /* 1585 * Simulate a cached result in `$stored_results` for D. 1586 * If caching logic is functioning properly, this cached value 1587 * should be returned immediately without recomputing. 1588 */ 1589 $stored_results = array( 'd' => array( 'async' ) ); 1590 1591 // Access the private method via reflection. 1592 $method = new ReflectionMethod( WP_Scripts::class, 'filter_eligible_strategies' ); 1593 if ( PHP_VERSION_ID < 80100 ) { 1594 $method->setAccessible( true ); 1595 } 1596 1597 // Invoke the method with `$stored_results` passed by reference. 1598 $result = $method->invokeArgs( $wp_scripts, array( 'd', null, array(), &$stored_results ) ); 1599 1600 $this->assertSame( 1601 array( 'async' ), 1602 $result, 1603 'Expected cached `$stored_results` value for D to be reused instead of recomputed.' 1604 ); 1535 1605 } 1536 1606
Note: See TracChangeset
for help on using the changeset viewer.