Description
Feature Description
Goal:
Add backwards compatible script enqueue features to WordPress that enable more performant script enqueueing, including support for defer
.
Details
WordPress core, themes and plugins add script tags to the page through a number of mechanisms, for example wp_enqueue_script
, wp_print_script_tag
or by directly outputting their script in a wp_head
action handler.
This Issue focuses primarily on wp_enqueue_script
(the recommended method for adding scripts in WordPress) which currently only lets developers control their script’s dependencies (other previously defined scripts) and whether the script should be enqueued in the header or footer (ref).
Developers can control what order their own scripts are output (the order they are enqueued), but not how they are prioritised in relation to scripts enqueued by other parts of the system (eg other plugins). In addition, wp_enqueue_script
does not currently directly support adding attributes like “defer” to script tags, although wp_print_script_tag
which was added in version 5.7 does support script tag attributes (ticket).
Proposal
Step 1. Add a loading strategy
- Add loading strategy support to
wp_enqueue_script
function (secondarilyadmin_enqueue_script
)- Follow up with work on https://core.trac.wordpress.org/ticket/22249
strategy
could be a new parameter or we could overload "in_footer": using a string for strategy, true for footer and null or false for header.- For
strategy
I propose “block” (equivalent to today’s head scripts) or “defer” (equivalent to today’s footer scripts, but deferred), open to naming suggestions.
- Automatic loading optimizations
- Footer grouping - when a script has
in_footer
set to true, dependent/dependency scripts should also be moved to the footer - When a script uses strategy
defer
, dependent/dependency scripts should also usedefer
- Scripts added with
wp_add_inline_script
hooked on a deferred script should also be deferred.
- Footer grouping - when a script has
- Enable opt out of the new behavior with a single filter (eg
add_filter( ‘wp_optimize_script_loading’, ‘__return_false’ );
)
Step 2. Consume new API in core
- Audit existing front end enqueued scripts for
defer
strategy opportunities (eg. ‘comments’)
Step 3. Future API enhancements
- Consideration for
wp_print_script_tag
,wp_get_inline_script_tag
,wp_print_inline_script_tag
andwp_get_script_tag
or even directly injected scripts and how these might be improved with a strategy, or to encourage/enableldefer
. - Having a strategy attribute is forward compatible, letting us consider additional loading strategies in the future:
- “priority” would use priority hints (or preload plus delayed js injection) to load the script with a high priority in a non blocking way
- “worker” would put a script in a worker using a tool like PartyTown, possibly useful for third party scripts or scripts that don't need much/any DOM access
Related
- Core ticket, summary: https://core.trac.wordpress.org/ticket/12009#comment:75
- Previous exploration: Defer enqueued scripts with an experimental toggle
- Next.js Script component strategy attribute: https://nextjs.org/docs/basic-features/script#strategy
- Browser script research: Resource loading orchestration
I welcome any feedback here about the proposed approach here, then we could split this out into several sub issues for the steps described above.