Make WordPress Core


Ignore:
Timestamp:
09/03/2025 10:15:31 PM (12 months ago)
Author:
westonruter
Message:

Script Loader: Introduce fetchpriority for Scripts and Script Modules.

  • Allow scripts and script modules to be registered with a fetchpriority of auto (default), high, low:
    • When registering a script, add a fetchpriority arg to go alongside the strategy arg which was added for loading scripts with the defer and async loading strategies. See #12009.
    • For script modules, introduce an $args array parameter with a fetchpriority key to the wp_register_script_module(), and wp_enqueue_script_module() functions (and their respective underlying WP_Script_Modules::register() and WP_Script_Modules::enqueue() methods). This $args parameter corresponds with the same parameter used when registering non-module scripts.
    • Also for script modules, introduce WP_Script_Modules::set_fetchpriority() to override the fetchpriority for what was previously registered.
    • Emit a _doing_it_wrong() warning when an invalid fetchpriority value is used, and when fetchpriority is added to a script alias.
    • Include fetchpriority as an attribute on printed SCRIPT tags as well as on preload LINK tags for static script module dependencies.
  • Use a fetchpriority of low by default for:
    • Script modules used with the Interactivity API. For overriding this default in blocks, see Gutenberg#71366.
    • The comment-reply script.
  • Improve type checks and type hints.

Developed in GitHub PR, with companion for Gutenberg.

Props westonruter, jonsurrell, swissspidy, luisherranz, kraftbj, audrasjb, dennysdionigi.
Fixes #61734.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-script-modules.php

    r60681 r60704  
    4747         *
    4848         * @since 6.5.0
     49         * @since 6.9.0 Added the $args parameter.
    4950         *
    5051         * @param string            $id       The identifier of the script module. Should be unique. It will be used in the
     
    7273         *                                    is set to false, the version number is the currently installed WordPress version.
    7374         *                                    If $version is set to null, no version is added.
    74          */
    75         public function register( string $id, string $src, array $deps = array(), $version = false ) {
     75         * @param array             $args     {
     76         *     Optional. An array of additional args. Default empty array.
     77         *
     78         *     @type 'auto'|'low'|'high' $fetchpriority Fetch priority. Default 'auto'. Optional.
     79         * }
     80         */
     81        public function register( string $id, string $src, array $deps = array(), $version = false, array $args = array() ) {
    7682                if ( ! isset( $this->registered[ $id ] ) ) {
    7783                        $dependencies = array();
    7884                        foreach ( $deps as $dependency ) {
    7985                                if ( is_array( $dependency ) ) {
    80                                         if ( ! isset( $dependency['id'] ) ) {
     86                                        if ( ! isset( $dependency['id'] ) || ! is_string( $dependency['id'] ) ) {
    8187                                                _doing_it_wrong( __METHOD__, __( 'Missing required id key in entry among dependencies array.' ), '6.5.0' );
    8288                                                continue;
     
    96102                        }
    97103
     104                        $fetchpriority = 'auto';
     105                        if ( isset( $args['fetchpriority'] ) ) {
     106                                if ( $this->is_valid_fetchpriority( $args['fetchpriority'] ) ) {
     107                                        $fetchpriority = $args['fetchpriority'];
     108                                } else {
     109                                        _doing_it_wrong(
     110                                                __METHOD__,
     111                                                sprintf(
     112                                                        /* translators: 1: $fetchpriority, 2: $id */
     113                                                        __( 'Invalid fetchpriority `%1$s` defined for `%2$s` during script registration.' ),
     114                                                        is_string( $args['fetchpriority'] ) ? $args['fetchpriority'] : gettype( $args['fetchpriority'] ),
     115                                                        $id
     116                                                ),
     117                                                '6.9.0'
     118                                        );
     119                                }
     120                        }
     121
    98122                        $this->registered[ $id ] = array(
    99                                 'src'          => $src,
    100                                 'version'      => $version,
    101                                 'enqueue'      => isset( $this->enqueued_before_registered[ $id ] ),
    102                                 'dependencies' => $dependencies,
     123                                'src'           => $src,
     124                                'version'       => $version,
     125                                'enqueue'       => isset( $this->enqueued_before_registered[ $id ] ),
     126                                'dependencies'  => $dependencies,
     127                                'fetchpriority' => $fetchpriority,
    103128                        );
    104129                }
     130        }
     131
     132        /**
     133         * Checks if the provided fetchpriority is valid.
     134         *
     135         * @since 6.9.0
     136         *
     137         * @param string|mixed $priority Fetch priority.
     138         * @return bool Whether valid fetchpriority.
     139         */
     140        private function is_valid_fetchpriority( $priority ): bool {
     141                return in_array( $priority, array( 'auto', 'low', 'high' ), true );
     142        }
     143
     144        /**
     145         * Sets the fetch priority for a script module.
     146         *
     147         * @since 6.9.0
     148         *
     149         * @param string              $id       Script module identifier.
     150         * @param 'auto'|'low'|'high' $priority Fetch priority for the script module.
     151         * @return bool Whether setting the fetchpriority was successful.
     152         */
     153        public function set_fetchpriority( string $id, string $priority ): bool {
     154                if ( ! isset( $this->registered[ $id ] ) ) {
     155                        return false;
     156                }
     157
     158                if ( '' === $priority ) {
     159                        $priority = 'auto';
     160                }
     161
     162                if ( ! $this->is_valid_fetchpriority( $priority ) ) {
     163                        _doing_it_wrong(
     164                                __METHOD__,
     165                                /* translators: %s: Invalid fetchpriority. */
     166                                sprintf( __( 'Invalid fetchpriority: %s' ), $priority ),
     167                                '6.9.0'
     168                        );
     169                        return false;
     170                }
     171
     172                $this->registered[ $id ]['fetchpriority'] = $priority;
     173                return true;
    105174        }
    106175
     
    112181         *
    113182         * @since 6.5.0
     183         * @since 6.9.0 Added the $args parameter.
    114184         *
    115185         * @param string            $id       The identifier of the script module. Should be unique. It will be used in the
     
    137207         *                                    is set to false, the version number is the currently installed WordPress version.
    138208         *                                    If $version is set to null, no version is added.
    139          */
    140         public function enqueue( string $id, string $src = '', array $deps = array(), $version = false ) {
     209         * @param array             $args     {
     210         *     Optional. An array of additional args. Default empty array.
     211         *
     212         *     @type 'auto'|'low'|'high' $fetchpriority Fetch priority. Default 'auto'. Optional.
     213         * }
     214         */
     215        public function enqueue( string $id, string $src = '', array $deps = array(), $version = false, array $args = array() ) {
    141216                if ( isset( $this->registered[ $id ] ) ) {
    142217                        $this->registered[ $id ]['enqueue'] = true;
    143218                } elseif ( $src ) {
    144                         $this->register( $id, $src, $deps, $version );
     219                        $this->register( $id, $src, $deps, $version, $args );
    145220                        $this->registered[ $id ]['enqueue'] = true;
    146221                } else {
     
    209284        public function print_enqueued_script_modules() {
    210285                foreach ( $this->get_marked_for_enqueue() as $id => $script_module ) {
    211                         wp_print_script_tag(
    212                                 array(
    213                                         'type' => 'module',
    214                                         'src'  => $this->get_src( $id ),
    215                                         'id'   => $id . '-js-module',
    216                                 )
     286                        $args = array(
     287                                'type' => 'module',
     288                                'src'  => $this->get_src( $id ),
     289                                'id'   => $id . '-js-module',
    217290                        );
     291                        if ( 'auto' !== $script_module['fetchpriority'] ) {
     292                                $args['fetchpriority'] = $script_module['fetchpriority'];
     293                        }
     294                        wp_print_script_tag( $args );
    218295                }
    219296        }
     
    232309                        if ( true !== $script_module['enqueue'] ) {
    233310                                echo sprintf(
    234                                         '<link rel="modulepreload" href="%s" id="%s">',
     311                                        '<link rel="modulepreload" href="%s" id="%s"%s>',
    235312                                        esc_url( $this->get_src( $id ) ),
    236                                         esc_attr( $id . '-js-modulepreload' )
     313                                        esc_attr( $id . '-js-modulepreload' ),
     314                                        'auto' !== $script_module['fetchpriority'] ? sprintf( ' fetchpriority="%s"', esc_attr( $script_module['fetchpriority'] ) ) : ''
    237315                                );
    238316                        }
     
    279357         * @since 6.5.0
    280358         *
    281          * @return array[] Script modules marked for enqueue, keyed by script module identifier.
     359         * @return array<string, array> Script modules marked for enqueue, keyed by script module identifier.
    282360         */
    283361        private function get_marked_for_enqueue(): array {
Note: See TracChangeset for help on using the changeset viewer.