Overview
This post outlines a proposal to add a script loading strategy enhancement Enhancements are simple improvements to WordPress, such as the addition of a hook, a new feature, or an improvement to an existing feature. to core Core is the set of software required to run WordPress. The Core Development Team builds WordPress.’s existing Scripts API An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways..
The underlying goal of this effort is to make it easier for WordPress plugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party and theme developers and core to use “modern” loading approaches for JavaScript JavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a user’s browser. https://www.javascript.com/. (like defer
and async
), which will help WordPress sites load faster and operate more smoothly, giving users a better experience.
Why add a loading strategy?
Data from the Web Almanac project (query) indicates that render blocking JavaScript is a significant problem on the web, with 77% of mobile pages having render-blocking scripts in the document <head>
. This query shows that approximately 40% of WordPress sites stand to benefit from deferring additional scripts. Adding defer
or async
to script tags enables script loading without “blocking” the rest of the page load, resulting in more responsive sites overall better user experience.
Currently WordPress core as well as plugins and themes register scripts with the wp_enqueue_script
and/or wp_register_script
functions. Although these functions include the ability to control the placement of the script (with the in_footer
parameter), they don’t include support for adding modern attributes such as defer
or async
to script tags.
To add async
or defer
today, developers must resort to less flexible and more fragile approaches, such as directly filtering the tags at the point of output (using the script_loader_tag
filter Filters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output.), or handling the tag A directory in Subversion. WordPress uses tags to store a single snapshot of a version (3.6, 3.6.1, etc.), the common convention of tags in version control systems. (Not to be confused with post tags.) output directly using wp_print_script_tag
and the wp_script_attributes
filter.
Using the first approach and directly filtering the tag can easily break: for example if two plugins both try to filter a tag, or if a tag has unexpected attributes already (eg. adding defer
to a tag that already has async
). Using the the second approach developers must carefully handle dependencies and output manually – things that that the Scripts API usually helps take care of.
How the loading strategy works
Developers specify a loading strategy when registering or enqueueing a script. For example, a defer
strategy can be specified when the script isn’t required immediately during the page load cycle. WordPress will then determine which scripts can actually use a strategy based on logic for each strategy. For example, to ensure that scripts are executed in the order they are enqueued, defer
can only be used on a script if every script that depends on that script can also be deferred. Inline script tags added with wp_add_inline_script
would also be considered to ensure proper execution order.
The implementation would come with several initial built-in loading strategies: defer
, async
, and the default blocking
behavior.
Out of scope for this feature
The loading strategy does not enable direct control of script
tag attributes. This idea was originally proposed 10 years ago in #22249 and several approaches were considered on that ticket Created for both bug reports and feature development on the bug tracker. including a script attribute filter. This proposal takes a step back and aims to solve the script loading strategy aspect more comprehensively and directly while avoiding exposing the potential complications of direct attribute control.
It is worth noting that it is already possible to control attributes on wp_enqueue_script
tags directly using the script_loader_tag
filter. However, this is a bit of a “brute force” approach which is limited and fragile because it doesn’t consider dependencies and multiple plugins can take conflicting actions on the same tag.
What are potential concerns with this feature?
One big concern with adding this feature to the WordPress Script API is potentially introducing a breaking change. wp_enqueue_script
is a fundamental API in WordPress core, and any breaking changes could have widespread implications. Possible breakage is a possible reason that adding custom attributes as proposed in #22249 was never added to core.
This new proposal aims to ensure that there is 100% backwards compatibility, resulting in zero risk of breakage. The loading strategy will ensure that all existing uses continue to function as expected; for example, passing the boolean in_footer
attribute will still control script placement. In addition, it will ensure that scripts continue to be executed in the order they are enqueued – as described above in the “How the loading strategy works” section.
Conclusion and Next Steps
Giving developers the ability to specify a loading strategy will enable them to use more advanced JavaScript loading methods while still ensuring that enqueued scripts are executed in the correct order. A “strategy” approach is also forward thinking: as the web evolves, new strategies can be developed and made available to WordPress developers. After gathering feedback, we will proceed to discussing the implementation approach and, ultimately, proposing a patch A special text file that describes changes to code, by identifying the files and lines which are added, removed, and altered. It may also be referred to as a diff. A patch can be applied to a codebase for testing..
Have you tried using defer
or async
with WordPress (or do you already)? How do you think this enhancement would change that? Please leave your feedback about this proposal in the comments below and if you can, join us at our weekly performance team chats, where we are likely to discuss this proposal in the future.
Thanks to @flixos90, @tweetythierry and @mxbclang for help writing and reviewing this post and for the many contributors who have added to the discussion around this enhancement already.
#core, #feature-projects, #javascript, #performance, #proposal