mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2026-06-28 14:20:15 +00:00
Script Loader: Move delayed head script to footer when there is a blocking footer dependent.
This prevents a performance regression when a blocking script is enqueued in the footer which depends on a delayed script in the `head` (with `async` or `defer`). In order to preserve the execution order, a delayed dependency must fall back to blocking when there is a blocking dependent. But since it was originally delayed (and thus executes similarly to a footer script), it does not need to be in the head and can be moved to the footer. This prevents blocking the critical rendering path. Props adamsilverstein, westonruter, flixos90. Fixes #59599. See #12009. git-svn-id: https://develop.svn.wordpress.org/trunk@56933 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
@@ -3065,4 +3065,291 @@ HTML
|
||||
protected function add_html5_script_theme_support() {
|
||||
add_theme_support( 'html5', array( 'script' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a script is moved to the footer if it is made non-deferrable, was in the header and
|
||||
* all scripts that depend on it are in the footer.
|
||||
*
|
||||
* @ticket 58599
|
||||
*
|
||||
* @dataProvider data_provider_script_move_to_footer
|
||||
*
|
||||
* @param callable $set_up Test setup.
|
||||
* @param string $expected_header Expected output for header.
|
||||
* @param string $expected_footer Expected output for footer.
|
||||
* @param string[] $expected_in_footer Handles expected to be in the footer.
|
||||
* @param array $expected_groups Expected groups.
|
||||
*/
|
||||
public function test_wp_scripts_move_to_footer( $set_up, $expected_header, $expected_footer, $expected_in_footer, $expected_groups ) {
|
||||
$set_up();
|
||||
|
||||
// Get the header output.
|
||||
ob_start();
|
||||
wp_scripts()->do_head_items();
|
||||
$header = ob_get_clean();
|
||||
|
||||
// Print a script in the body just to make sure it doesn't cause problems.
|
||||
ob_start();
|
||||
wp_print_scripts( array( 'jquery' ) );
|
||||
ob_end_clean();
|
||||
|
||||
// Get the footer output.
|
||||
ob_start();
|
||||
wp_scripts()->do_footer_items();
|
||||
$footer = ob_get_clean();
|
||||
|
||||
$this->assertEqualMarkup( $expected_header, $header, 'Expected header script markup to match.' );
|
||||
$this->assertEqualMarkup( $expected_footer, $footer, 'Expected footer script markup to match.' );
|
||||
$this->assertEqualSets( $expected_in_footer, wp_scripts()->in_footer, 'Expected to have the same handles for in_footer.' );
|
||||
$this->assertEquals( $expected_groups, wp_scripts()->groups, 'Expected groups to match.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_wp_scripts_move_to_footer.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function data_provider_script_move_to_footer() {
|
||||
return array(
|
||||
'footer-blocking-dependent-of-defer-head-script' => array(
|
||||
'set_up' => static function () {
|
||||
wp_enqueue_script( 'script-a', 'https://example.com/script-a.js', array(), null, array( 'strategy' => 'defer' ) );
|
||||
wp_enqueue_script( 'script-b', 'https://example.com/script-b.js', array( 'script-a' ), null, array( 'in_footer' => true ) );
|
||||
},
|
||||
'expected_header' => '',
|
||||
'expected_footer' => '
|
||||
<script type="text/javascript" src="https://example.com/script-a.js" id="script-a-js" data-wp-strategy="defer"></script>
|
||||
<script type="text/javascript" src="https://example.com/script-b.js" id="script-b-js"></script>
|
||||
',
|
||||
'expected_in_footer' => array(
|
||||
'script-a',
|
||||
'script-b',
|
||||
),
|
||||
'expected_groups' => array(
|
||||
'script-a' => 0,
|
||||
'script-b' => 1,
|
||||
'jquery' => 0,
|
||||
),
|
||||
),
|
||||
|
||||
'footer-blocking-dependent-of-async-head-script' => array(
|
||||
'set_up' => static function () {
|
||||
wp_enqueue_script( 'script-a', 'https://example.com/script-a.js', array(), null, array( 'strategy' => 'async' ) );
|
||||
wp_enqueue_script( 'script-b', 'https://example.com/script-b.js', array( 'script-a' ), null, array( 'in_footer' => true ) );
|
||||
},
|
||||
'expected_header' => '',
|
||||
'expected_footer' => '
|
||||
<script type="text/javascript" src="https://example.com/script-a.js" id="script-a-js" data-wp-strategy="async"></script>
|
||||
<script type="text/javascript" src="https://example.com/script-b.js" id="script-b-js"></script>
|
||||
',
|
||||
'expected_in_footer' => array(
|
||||
'script-a',
|
||||
'script-b',
|
||||
),
|
||||
'expected_groups' => array(
|
||||
'script-a' => 0,
|
||||
'script-b' => 1,
|
||||
'jquery' => 0,
|
||||
),
|
||||
),
|
||||
|
||||
'head-blocking-dependent-of-delayed-head-script' => array(
|
||||
'set_up' => static function () {
|
||||
wp_enqueue_script( 'script-a', 'https://example.com/script-a.js', array(), null, array( 'strategy' => 'defer' ) );
|
||||
wp_enqueue_script( 'script-b', 'https://example.com/script-b.js', array( 'script-a' ), null, array( 'in_footer' => false ) );
|
||||
},
|
||||
'expected_header' => '
|
||||
<script type="text/javascript" src="https://example.com/script-a.js" id="script-a-js" data-wp-strategy="defer"></script>
|
||||
<script type="text/javascript" src="https://example.com/script-b.js" id="script-b-js"></script>
|
||||
',
|
||||
'expected_footer' => '',
|
||||
'expected_in_footer' => array(),
|
||||
'expected_groups' => array(
|
||||
'script-a' => 0,
|
||||
'script-b' => 0,
|
||||
'jquery' => 0,
|
||||
),
|
||||
),
|
||||
|
||||
'delayed-footer-dependent-of-delayed-head-script' => array(
|
||||
'set_up' => static function () {
|
||||
wp_enqueue_script( 'script-a', 'https://example.com/script-a.js', array(), null, array( 'strategy' => 'defer' ) );
|
||||
wp_enqueue_script(
|
||||
'script-b',
|
||||
'https://example.com/script-b.js',
|
||||
array( 'script-a' ),
|
||||
null,
|
||||
array(
|
||||
'strategy' => 'defer',
|
||||
'in_footer' => true,
|
||||
)
|
||||
);
|
||||
},
|
||||
'expected_header' => '
|
||||
<script type="text/javascript" src="https://example.com/script-a.js" id="script-a-js" defer="defer" data-wp-strategy="defer"></script>
|
||||
',
|
||||
'expected_footer' => '
|
||||
<script type="text/javascript" src="https://example.com/script-b.js" id="script-b-js" defer="defer" data-wp-strategy="defer"></script>
|
||||
',
|
||||
'expected_in_footer' => array(
|
||||
'script-b',
|
||||
),
|
||||
'expected_groups' => array(
|
||||
'script-a' => 0,
|
||||
'script-b' => 1,
|
||||
'jquery' => 0,
|
||||
),
|
||||
),
|
||||
|
||||
'delayed-dependent-in-header-and-delayed-dependents-in-footer' => array(
|
||||
'set_up' => static function () {
|
||||
wp_enqueue_script( 'script-a', 'https://example.com/script-a.js', array(), null, array( 'strategy' => 'defer' ) );
|
||||
wp_enqueue_script(
|
||||
'script-b',
|
||||
'https://example.com/script-b.js',
|
||||
array( 'script-a' ),
|
||||
null,
|
||||
array(
|
||||
'strategy' => 'defer',
|
||||
'in_footer' => false,
|
||||
)
|
||||
);
|
||||
wp_enqueue_script(
|
||||
'script-c',
|
||||
'https://example.com/script-c.js',
|
||||
array( 'script-a' ),
|
||||
null,
|
||||
array(
|
||||
'strategy' => 'defer',
|
||||
'in_footer' => true,
|
||||
)
|
||||
);
|
||||
wp_enqueue_script(
|
||||
'script-d',
|
||||
'https://example.com/script-d.js',
|
||||
array( 'script-a' ),
|
||||
null,
|
||||
array(
|
||||
'strategy' => 'defer',
|
||||
'in_footer' => true,
|
||||
)
|
||||
);
|
||||
},
|
||||
'expected_header' => '
|
||||
<script type="text/javascript" src="https://example.com/script-a.js" id="script-a-js" defer="defer" data-wp-strategy="defer"></script>
|
||||
<script type="text/javascript" src="https://example.com/script-b.js" id="script-b-js" defer="defer" data-wp-strategy="defer"></script>
|
||||
',
|
||||
'expected_footer' => '
|
||||
<script type="text/javascript" src="https://example.com/script-c.js" id="script-c-js" defer="defer" data-wp-strategy="defer"></script>
|
||||
<script type="text/javascript" src="https://example.com/script-d.js" id="script-d-js" defer="defer" data-wp-strategy="defer"></script>
|
||||
',
|
||||
'expected_in_footer' => array(
|
||||
'script-c',
|
||||
'script-d',
|
||||
),
|
||||
'expected_groups' => array(
|
||||
'script-a' => 0,
|
||||
'script-b' => 0,
|
||||
'script-c' => 1,
|
||||
'script-d' => 1,
|
||||
'jquery' => 0,
|
||||
),
|
||||
),
|
||||
|
||||
'all-dependents-in-footer-with-one-blocking' => array(
|
||||
'set_up' => static function () {
|
||||
wp_enqueue_script( 'script-a', 'https://example.com/script-a.js', array(), null, array( 'strategy' => 'defer' ) );
|
||||
wp_enqueue_script(
|
||||
'script-b',
|
||||
'https://example.com/script-b.js',
|
||||
array( 'script-a' ),
|
||||
null,
|
||||
array(
|
||||
'strategy' => 'defer',
|
||||
'in_footer' => true,
|
||||
)
|
||||
);
|
||||
wp_enqueue_script( 'script-c', 'https://example.com/script-c.js', array( 'script-a' ), null, true );
|
||||
wp_enqueue_script(
|
||||
'script-d',
|
||||
'https://example.com/script-d.js',
|
||||
array( 'script-a' ),
|
||||
null,
|
||||
array(
|
||||
'strategy' => 'defer',
|
||||
'in_footer' => true,
|
||||
)
|
||||
);
|
||||
},
|
||||
'expected_header' => '',
|
||||
'expected_footer' => '
|
||||
<script type="text/javascript" src="https://example.com/script-a.js" id="script-a-js" data-wp-strategy="defer"></script>
|
||||
<script type="text/javascript" src="https://example.com/script-b.js" id="script-b-js" defer="defer" data-wp-strategy="defer"></script>
|
||||
<script type="text/javascript" src="https://example.com/script-c.js" id="script-c-js"></script>
|
||||
<script type="text/javascript" src="https://example.com/script-d.js" id="script-d-js" defer="defer" data-wp-strategy="defer"></script>
|
||||
',
|
||||
'expected_in_footer' => array(
|
||||
'script-a',
|
||||
'script-b',
|
||||
'script-c',
|
||||
'script-d',
|
||||
),
|
||||
'expected_groups' => array(
|
||||
'script-a' => 0,
|
||||
'script-b' => 1,
|
||||
'script-c' => 1,
|
||||
'script-d' => 1,
|
||||
'jquery' => 0,
|
||||
|
||||
),
|
||||
),
|
||||
|
||||
'blocking-dependents-in-head-and-footer' => array(
|
||||
'set_up' => static function () {
|
||||
wp_enqueue_script( 'script-a', 'https://example.com/script-a.js', array(), null, array( 'strategy' => 'defer' ) );
|
||||
wp_enqueue_script(
|
||||
'script-b',
|
||||
'https://example.com/script-b.js',
|
||||
array( 'script-a' ),
|
||||
null,
|
||||
array(
|
||||
'strategy' => 'defer',
|
||||
'in_footer' => false,
|
||||
)
|
||||
);
|
||||
wp_enqueue_script( 'script-c', 'https://example.com/script-c.js', array( 'script-a' ), null, true );
|
||||
wp_enqueue_script(
|
||||
'script-d',
|
||||
'https://example.com/script-d.js',
|
||||
array( 'script-a' ),
|
||||
null,
|
||||
array(
|
||||
'strategy' => 'defer',
|
||||
'in_footer' => true,
|
||||
)
|
||||
);
|
||||
},
|
||||
'expected_header' => '
|
||||
<script type="text/javascript" src="https://example.com/script-a.js" id="script-a-js" data-wp-strategy="defer"></script>
|
||||
<script type="text/javascript" src="https://example.com/script-b.js" id="script-b-js" defer="defer" data-wp-strategy="defer"></script>
|
||||
',
|
||||
'expected_footer' => '
|
||||
<script type="text/javascript" src="https://example.com/script-c.js" id="script-c-js"></script>
|
||||
<script type="text/javascript" src="https://example.com/script-d.js" id="script-d-js" defer="defer" data-wp-strategy="defer"></script>
|
||||
',
|
||||
'expected_in_footer' => array(
|
||||
'script-c',
|
||||
'script-d',
|
||||
),
|
||||
'expected_groups' => array(
|
||||
'script-a' => 0,
|
||||
'script-b' => 0,
|
||||
'script-c' => 1,
|
||||
'script-d' => 1,
|
||||
'jquery' => 0,
|
||||
),
|
||||
),
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user