[wp-trac] [WordPress Trac] #12009: Add support for HTML 5 "async" and "defer" attributes

WordPress Trac noreply at wordpress.org
Fri Jun 16 01:22:23 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
-------------------------------------------------+-------------------------

Comment (by joemcgill):

 Replying to [comment:115 azaozz]:

 Since we’re nearing the end of the merge window for 6.3, I want to revisit
 some of the things raised in this conversation and get final clarification
 on a path forward. Let me summarize my current understanding of the main
 concerns you have raised:

 1. Your opinion is that supporting inline after scripts is unnecessary, in
 general
 2. The implementation method in the current PR for delaying inline scripts
 is unsafe
 3. Supporting `async` and `defer` could conflict with future dynamic
 module imports

 First, I’ll restate the reasons that we’ve chosen to keep support for
 inline scripts when added to a script that has an async or defer
 attribute. There are over 5000 cases in
 [https://wpdirectory.net/search/01H2EJ1E82DX0JCAMYSS35GD0T plugins] and
 808 cases in [https://wpdirectory.net/search/01H2EM8SFQAB67C1TSRHZS2AJA
 themes] on the wp.org repos where `wp_add_inline_script()` is used, with
 the vast majority (>90%) of them using the `after` position. Even in core,
 there are
 [https://github.com/search?q=repo%3AWordPress%2FWordPress%20wp_add_inline_script&type=code
 many places] where data from the server is being supplied to an inline
 script in an `after` position. An example is in
 [https://github.com/WordPress/wordpress-
 develop/blob/ba9a2f8b83211fbdee1621fd4f39dcb11908b817/src/wp-admin/site-
 editor.php#L94-L114 site-editor.php], where settings from the server are
 dynamically supplied to the front end to be used after a core script is
 loaded. Without a way to delay those inline scripts until after the handle
 to which they are attached has loaded, those handles will always need to
 be loaded as a blocking script. After inline scripts are very useful
 because they do not require polluting the global namespace with a variable
 defined in the before inline script, and the script itself doesn’t have to
 be updated to read from that global variable: with an inline script,
 existing libraries can be used as-is. Our implementation allows script
 handles with inline scripts attached to be deferred or loaded
 asynchronously without the need to rewrite the inline logic, allowing more
 scripts to adopt `async` or `defer` strategies, including scripts in core
 that are currently blocking but could be delayed in the future (outside
 the scope of this PR, but something that I'd like to see us explore).

 Regarding your concerns about the safety of the implementation, there are
 very important distinctions between scripts that are executed using
 `eval()` and scripts that are dynamically injected into the DOM during
 script execution (i.e., the approach we’re using). Most important is that
 sites implementing a content security policy (CSP) will not execute `eval`
 unless they include the `unsafe-eval` keyword. Dynamic scripts are handled
 completely separately, including external scripts and inline scripts. By
 using the `strict-dynamic` source expression, only trusted scripts are
 allowed to dynamically add scripts to the DOM. This trust is achieved by
 outputting a `nonce-{random}` attribute on the script tag. With
 [https://web.dev/strict-csp/#what-is-a-strict-content-security-policy
 strict CSP], browsers block executing scripts at parse time if they lack a
 valid nonce, and our delayed inline script loader does the exact same
 thing by making sure that inline scripts are only dynamically added if the
 original `script[type=text/plain]` has a valid nonce matching the CSP. In
 summary, dynamically adding scripts to a DOM is quite different and safer
 than running `eval()` on a text string. If you have more specific concerns
 about the security of this approach, please specify so they can be
 addressed.

 Finally, I’ve looked into the dynamic module loading you raised in
 [https://core.trac.wordpress.org/ticket/12009#comment:116 your previous
 comment] and am not seeing any incompatibility with adding support for
 adding `async` and `defer` attributes to scripts. From what I can tell,
 any scripts that are registered as modules in the future would be able to
 be written in a way that includes dynamic imports without ever needing to
 interact with the Script Loader, since all of the logic to dynamically
 import external modules would be handled within the script itself.

 Having said all that, what needs to be determined is whether the support
 for inline scripts needs to be completely removed from the implementation
 for an initial commit, or if there are further modifications that need to
 be made in order to leave that support in place. Additionally, if you have
 any other final changes that you would like to see addressed before
 commit, please list them so we can ensure they are addressed.

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/12009#comment:124>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list