-
Notifications
You must be signed in to change notification settings - Fork 94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve performance capabilities of core script enqueueing #168
Comments
Where will the deferred script be loaded? In the footer or in the header? If in the footer, then how can I load it in the header if I need to? Maybe we should leave the current wp_enqueue_script( 'header-script', '.../header.js', array( '...' ), '1.0', false );
wp_enqueue_script( 'footer-script', '.../footer.js', array( '...' ), '1.0', true );
wp_defer_script( 'header-script' ); Also, does it really make sense to defer scripts loaded in the footer? Correct me if I am wrong, but the idea of deferred scripts is in the fact that they are loaded asynchronously and executed once the document parsing is over which usually happens right after loading footer scripts. |
For backward compatibility introduce a new array parameter with |
Another alternative using an existing function: wp_script_add_data( 'header-script', 'strategy', 'defer' ); |
Relying on additional function (like |
reading up on inline scripts that appear after a script that uses the defer strategy, we should able to handle those with |
You can't take an existing script block of unknown code and put a type="module" on it and expect it to "just work". For instance,
Also, (and I apologize if this is the wrong venue to bring this up) I would like to make the suggestion that any efforts to get an async and/or defer attribute incorporated into the WP script enqueuing APIs should take a back-seat priority to getting support for the nonce attribute within the WP script enqueuing APIs. If both could get done together, that would be fine but the nonce attribute doesn't even seem to be on the agenda here and defer introduces some systemic problems with respect to inline dependencies and dependents which to my mind should decouple and de-prioritize it from generalized and very necessary API changes needed for simpler attributes like the CSP |
@Kevin-Hamilton thanks for raising this, is there an existing ticket about the CSP nonce attribute? I know there were numerous work streams for CSP that have stalled so I assume those cover this. This is a security measure, correct?
Good points to raise and perhaps indicates we can't automate the deferal of scripts with inlined dependents. The goal isn't to automate defer entirely but rather to provide a 1p API for defer that helps work thru some of the dependency issues. |
@adamsilverstein - regarding CSP nonce, yes it is a security measure. For a deeper dive on the topic, I recommend this video: https://www.youtube.com/watch?v=_L06HetskC4. Regarding existing tickets - I believe you were owner of the ticket that resulted in the 4 new API functions added to WP 5.7: https://make.wordpress.org/core/2021/02/23/introducing-script-attributes-related-functions-in-wordpress-5-7/. Unfortunately, these are woefully inadequate as they don't do anything for scripts that are part of the enqueue APIs. For example, wp_add_inline_script and wp_localize_script will both output script tags to the browser without any filters available for the security-conscious programmer to intercept that output and modify the attributes of the script tag. This is a big problem problem because those functions are very widely used. See: https://wpdirectory.net/search/01GDC5GQSKYCVK6SE517N97E5E and https://wpdirectory.net/search/01GBM897NXNDXBYVQSNVNW0B22. Compare that to the only 371 instances of those new API functions being implemented so far in the last 18 months since WP 5.7 was released: https://wpdirectory.net/search/01GBM7K6GGNRE5AA2BG8VPVHQP. Here is one open ticket on this issue: https://core.trac.wordpress.org/ticket/54214 but it doesn't cover the wp_localize_script use case. I guess there could have been other tickets in recent years that have been closed as duplicates of https://core.trac.wordpress.org/ticket/12009 or https://core.trac.wordpress.org/ticket/22249. I fear that focusing on the generic solution that can cover all script attributes including async and defer has come at an opportunity cost for particular attributes like nonce which do not have the edge cases that defer has. Meanwhile, there are plugins like this one which people might install to become "CSP compliant", but is actually useless for protecting against a stored or reflected XSS attack because it is just using a regex against buffered output to put the nonce on every tag, ignorant of whether that script was added by core/plugin/theme, or by attacker! I apologize for dumping all this information at your feet, and I know the core performance team is not the appropriate place for the discussion, but to my surprise there doesn't even seem to be a dedicated core security team at make.wordpress.org: https://make.wordpress.org/, nor a dedicated security channel in Slack. |
@Kevin-Hamilton I agree we should word to land nonce support in |
This has been implemented for WordPress 6.3 in https://core.trac.wordpress.org/ticket/12009, hence marking this as completed. 🎉 Also see #755. |
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 awp_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, althoughwp_print_script_tag
which was added in version 5.7 does support script tag attributes (ticket).Proposal
Step 1. Add a loading strategy
wp_enqueue_script
function (secondarilyadmin_enqueue_script
)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.strategy
I propose “block” (equivalent to today’s head scripts) or “defer” (equivalent to today’s footer scripts, but deferred), open to naming suggestions.in_footer
set to true, dependent/dependency scripts should also be moved to the footerdefer
, dependent/dependency scripts should also usedefer
wp_add_inline_script
hooked on a deferred script should also be deferred.add_filter( ‘wp_optimize_script_loading’, ‘__return_false’ );
)Step 2. Consume new API in core
defer
strategy opportunities (eg. ‘comments’)Step 3. Future API enhancements
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
.Related
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.
The text was updated successfully, but these errors were encountered: