Opened 16 months ago
Last modified 5 months ago
#61657 new defect (bug)
Script "in_footer" => false with "defer" will make all dependencies that are not deferred load in head
| Reported by: |
|
Owned by: | |
|---|---|---|---|
| Milestone: | Awaiting Review | Priority: | normal |
| Severity: | normal | Version: | |
| Component: | Script Loader | Keywords: | reporter-feedback |
| Focuses: | performance | Cc: |
Description
wp_register_script( 'foo', get_template_directory_uri() . '/foo.js', array(), '1.0.0', array( 'in_footer' => true ) ); wp_register_script( 'bar', get_template_directory_uri() . '/bar.js', array( 'foo' ), '1.0.0', array( 'in_footer' => false, 'strategy' => 'defer' ) );
This will output both scripts in the head.
However, this isn't necessary and leads to worse performance.
Because "bar" which isn't loaded in footer, is loaded using the "defer" attribute, the browser would execute it after "foo", even though it's in the HTML before it.
The only exception is browsers that do not support the "defer" attribute (which currently there are none to consider https://caniuse.com/script-defer), where this wouldn't work.
A practical use case is wp-admin: these pages are usually not page cached, and it takes considerable amount of time from the time the header is flushed to the browser to the time PHP generated the page up to the footer and flushed it to the browser.
This time can be used by the browser to download these JS files in the head; the "defer" attribute ensures it will only execute once the whole page has loaded.
Secondly, I suggest that if a script that has footer false with defer and an "after" inline script is added to it, it will not just drop the "defer" but instead convert the footer false to footer true internally (since this was the original intention of the execution point when it was registered)
I think I understand. The current logic is such that if
foois printed in the footer, andbaris printed in the head, ifbardepends onfoothenfoomust be moved to the head so as to ensure the correct load order. But ifbaris hasdeferthen it will always load after blockingfooanyway, so it can remain in the head.Are there any cases you're aware of where this is happening? I wonder if this is an edge case that isn't worth worrying about.
However, if someone were to add the
deferloading strategy tofoo, then at this pointbarwould have to continue to be moved to the head since then they would load in the wrong dependency order after the document has loaded.I'm not sure I understand. If a deferred script has an after inline script, then
deferhas to be removed for safety to ensure that the inline script is able to access whatever globals that the script may be defining.