[wp-trac] [WordPress Trac] #12009: Add support for HTML 5 "async" and "defer" attributes
WordPress Trac
noreply at wordpress.org
Mon May 29 09:37:18 UTC 2023
#12009: Add support for HTML 5 "async" and "defer" attributes
-------------------------------------------------+-------------------------
Reporter: Otto42 | Owner: 10upsimon
Type: enhancement | Status: assigned
Priority: high | Milestone: 6.3
Component: Script Loader | Version: 4.6
Severity: normal | Resolution:
Keywords: has-patch has-unit-tests 2nd- | Focuses:
opinion | performance
-------------------------------------------------+-------------------------
Changes (by azaozz):
* keywords: has-patch has-unit-tests => has-patch has-unit-tests 2nd-
opinion
Comment:
Replying to [comment:113 joemcgill]:
> > However imho a bigger concern is the proposed JS that handles "scripts
after". Cloning a node and injecting it in the DOM as `text/javascript` is
pretty much as bad as running that node's content with `eval()`.
>
> I’m in total agreement with your concerns here. When testing this
approach with Content-Security-Policy, @westonruter
[https://github.com/WordPress/wordpress-
develop/pull/4391#issuecomment-1536869109 discovered] that it had a
security vulnerability related to...
Yea, this looks a bit better but is still "not-a-good-idea". The problem
is with the content of a `type="text/template"` node being run with JS
`exec()`. As mentioned many times in many places, this is generally a bad
idea. So unless that script is outputted (printed) as
`type="text/javascript"` (or the `type` attribute omitted) I don't think
it would be a good addition to core.
However the above is not the only reason to remove that code. There are
other reasons:
1. This is not used in core. Adding untested and unconfirmed API methods
to core is a bit red flag. The "unconfirmed" part refers to usability,
i.e. if that method is not used in core, would it at least be useful to at
least 10% of the plugins that use Script Loader? As far as I see this is a
"NO".
> This goes back to why inline scripts were introduced in the first place.
There needs to be a way to pass dynamic data from PHP back to static JS
scripts that can execute either before or after a registered script.
2. This is not exactly true :)
What you're saying is true for "before" scripts, but not for "after"
scripts. There is actually very little need for "after" scripts, so this
feature of Script Loader has always been on the border of being quite
useless. I.e. nearly all cases where an "after" script is used can be
handled by using a "before" script. There are only few rare exceptions
(which frankly do not warrant the existence of the convenience method for
adding of "after" scripts, but that's a different question of a "bad API
decision" that was made some time ago) .
> {{{#!php
> wp_register_script(
> 'foo',
> plugin_dir_url( __FILE__ ) . 'foo.js',
> array(),
> '0.1',
> array( 'strategy' => 'defer' )
> );
> wp_add_inline_script(
> 'foo',
> sprintf( 'Foo.init( %s )', wp_json_encode( getFooData() ) ),
> 'after'
> );
> }}}
This example is "the incorrect way to output data for scripts in
WordPress" :) The "correct" way (using a "before" script) can be seen in
many places in Script Loader:
- https://core.trac.wordpress.org/browser/tags/6.2.2/src/wp-includes
/script-loader.php#L885
- https://core.trac.wordpress.org/browser/tags/6.2.2/src/wp-includes
/script-loader.php#L920
- https://core.trac.wordpress.org/browser/tags/6.2.2/src/wp-includes
/script-loader.php#L981
- https://core.trac.wordpress.org/browser/tags/6.2.2/src/wp-includes
/script-loader.php#L1001
- https://core.trac.wordpress.org/browser/tags/6.2.2/src/wp-includes
/script-loader.php#L1021
and many many more. (Note that `$scripts->localize()` adds a "before"
script.)
> Additionally, we are attempting to create safe upgrade paths for scripts
that are currently blocking to be converted to a defer or async loading
strategy. We've designed the API changes to ensure that inline scripts
added to a handle continue to be executed in the intended order when the
loading strategy changes. This removes an important backward
compatibility concern...
Yea, this is a lofty goal but unfortunately there is no 100% backwards
compatibility. Since the loading order of "async" scripts is undetermined,
they are not backwards compatible when used as dependency.
Yea, I know this was discussed above and the decision was to "leave it to
the plugins to decide what to do about it". Not having support for "script
after" is inline with that decision.
So the TL;DR: for "script after" support for "async" and "defer" scripts:
1. Doesn't use a good, safe methods in JS.
2. Currently very rarely used (for "blocking" scripts). Most uses are not
warranted.
3. Not used in core (and seems it will never be used).
In these terms I'm starting to get curious why this strong push to add
that to core? :)
If there is really such a big desire, a better option would be to make a
canonical plugin that implements it, imho. That way all developers that
really want to use such code can have access to a standard way of handling
it (can even copy the plugin's code, etc.). It will be really interesting
to see usage stats for such plugin before considering such additions to
core.
Re-adding the "2nd opinion" label as I think there are many unanswered
questions here.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/12009#comment:115>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list