From 8ae650bf728cf0afad7e1964b6bb95dcfc7f9dde Mon Sep 17 00:00:00 2001 From: thelovekesh Date: Sun, 25 Aug 2024 13:01:44 +0530 Subject: [PATCH 01/13] Update wwo script loading strategy --- plugins/web-worker-offloading/hooks.php | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/plugins/web-worker-offloading/hooks.php b/plugins/web-worker-offloading/hooks.php index 77989c00b4..877fda376f 100644 --- a/plugins/web-worker-offloading/hooks.php +++ b/plugins/web-worker-offloading/hooks.php @@ -80,13 +80,10 @@ function wwo_init(): void { * @return string[] Array of script handles. */ function wwo_update_script_strategy( $script_handles ): array { - $script_handles = array_intersect( (array) $script_handles, array_keys( wp_scripts()->registered ) ); foreach ( $script_handles as $handle ) { - if ( in_array( 'web-worker-offloading', wp_scripts()->registered[ $handle ]->deps, true ) ) { - if ( false === wp_scripts()->get_data( $handle, 'strategy' ) ) { - wp_script_add_data( $handle, 'strategy', 'async' ); // The 'defer' strategy would work as well. - wp_script_add_data( $handle, 'wwo_strategy_added', true ); - } + if ( (bool) wp_scripts()->get_data( $handle, 'worker' ) && false === wp_scripts()->get_data( $handle, 'strategy' ) ) { + wp_script_add_data( $handle, 'strategy', 'async' ); // The 'defer' strategy would work as well. + wp_script_add_data( $handle, 'wwo_strategy_added', true ); } } @@ -106,8 +103,7 @@ function wwo_update_script_strategy( $script_handles ): array { function wwo_update_script_type( $tag, string $handle ) { if ( is_string( $tag ) && - array_key_exists( $handle, wp_scripts()->registered ) && - in_array( 'web-worker-offloading', wp_scripts()->registered[ $handle ]->deps, true ) + (bool) wp_scripts()->get_data( $handle, 'worker' ) ) { $html_processor = new WP_HTML_Tag_Processor( $tag ); From 1a0d378d0cac49997686dcc3882e32e2a5212922 Mon Sep 17 00:00:00 2001 From: thelovekesh Date: Sun, 25 Aug 2024 14:17:12 +0530 Subject: [PATCH 02/13] Add function to add web-worker-offloading script as dep if worker is added to script data --- plugins/web-worker-offloading/hooks.php | 28 +++++++++++++------------ 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/plugins/web-worker-offloading/hooks.php b/plugins/web-worker-offloading/hooks.php index 877fda376f..ee58d58035 100644 --- a/plugins/web-worker-offloading/hooks.php +++ b/plugins/web-worker-offloading/hooks.php @@ -68,28 +68,30 @@ function wwo_init(): void { add_action( 'wp_enqueue_scripts', 'wwo_init' ); /** - * Marks scripts with `web-worker-offloading` dependency as async. + * Adds `web-worker-offloading` as dependency to scripts with `worker` data. Also, marks their strategy as `async`. * * This is needed because scripts offloaded to a worker thread can be considered async. However, they may include `before` and `after` inline * scripts that need sequential execution. Once marked as async, `filter_eligible_strategies()` determines if the * script is eligible for async execution. If so, it will be offloaded to the worker thread. * - * @since 0.1.0 - * - * @param string[]|mixed $script_handles Array of script handles. - * @return string[] Array of script handles. + * @since n.e.x.t */ -function wwo_update_script_strategy( $script_handles ): array { - foreach ( $script_handles as $handle ) { - if ( (bool) wp_scripts()->get_data( $handle, 'worker' ) && false === wp_scripts()->get_data( $handle, 'strategy' ) ) { - wp_script_add_data( $handle, 'strategy', 'async' ); // The 'defer' strategy would work as well. - wp_script_add_data( $handle, 'wwo_strategy_added', true ); +function wwo_add_dependency_to_worker_scripts(): void { + foreach ( wp_scripts()->registered as $dep ) { + if ( + (bool) wp_scripts()->get_data( $dep->handle, 'worker') && + ! in_array( 'web-worker-offloading', wp_scripts()->registered[ $dep->handle ]->deps, true ) + ) { + wp_scripts()->registered[ $dep->handle ]->deps[] = 'web-worker-offloading'; + + if ( false === wp_scripts()->get_data( $dep->handle, 'strategy' ) ) { + wp_script_add_data( $dep->handle, 'strategy', 'async' ); // The 'defer' strategy would work as well. + wp_script_add_data( $dep->handle, 'wwo_strategy_added', true ); + } } } - - return $script_handles; } -add_filter( 'print_scripts_array', 'wwo_update_script_strategy' ); +add_action( 'wp_print_scripts', 'wwo_add_dependency_to_worker_scripts' ); /** * Updates script type for handles having `web-worker-offloading` as dependency. From 32c938f9e3e517da9886203070d9049bc96ab61d Mon Sep 17 00:00:00 2001 From: thelovekesh Date: Sun, 25 Aug 2024 14:17:40 +0530 Subject: [PATCH 03/13] Update test cases for updating wwo script type --- .../tests/test-web-worker-offloading.php | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/plugins/web-worker-offloading/tests/test-web-worker-offloading.php b/plugins/web-worker-offloading/tests/test-web-worker-offloading.php index f587a5495a..c196f74733 100644 --- a/plugins/web-worker-offloading/tests/test-web-worker-offloading.php +++ b/plugins/web-worker-offloading/tests/test-web-worker-offloading.php @@ -107,64 +107,72 @@ public static function data_update_script_types(): array { ), 'add-script-for-web-worker-offloading' => array( 'set_up' => static function (): void { - wp_enqueue_script( 'foo', 'https://example.com/foo.js', array( 'web-worker-offloading' ), '1.0.0', true ); + wp_enqueue_script( 'foo', 'https://example.com/foo.js', array(), '1.0.0', true ); + wp_script_add_data( 'foo', 'worker', true ); }, 'expected' => '{{ wwo_config }}{{ wwo_inline_script }}', 'doing_it_wrong' => false, ), 'add-defer-script-for-web-worker-offloading' => array( 'set_up' => static function (): void { - wp_enqueue_script( 'foo', 'https://example.com/foo.js', array( 'web-worker-offloading' ), '1.0.0', array( 'strategy' => 'defer' ) ); + wp_enqueue_script( 'foo', 'https://example.com/foo.js', array(), '1.0.0', array( 'strategy' => 'defer' ) ); + wp_script_add_data( 'foo', 'worker', true ); }, 'expected' => '{{ wwo_config }}{{ wwo_inline_script }}', 'doing_it_wrong' => false, ), 'add-async-script-for-web-worker-offloading' => array( 'set_up' => static function (): void { - wp_enqueue_script( 'foo', 'https://example.com/foo.js', array( 'web-worker-offloading' ), '1.0.0', array( 'strategy' => 'async' ) ); + wp_enqueue_script( 'foo', 'https://example.com/foo.js', array(), '1.0.0', array( 'strategy' => 'async' ) ); + wp_script_add_data( 'foo', 'worker', true ); }, 'expected' => '{{ wwo_config }}{{ wwo_inline_script }}', 'doing_it_wrong' => false, ), 'add-script-for-web-worker-offloading-with-before-data' => array( 'set_up' => static function (): void { - wp_enqueue_script( 'foo', 'https://example.com/foo.js', array( 'web-worker-offloading' ), '1.0.0', true ); + wp_enqueue_script( 'foo', 'https://example.com/foo.js', array(), '1.0.0', true ); wp_add_inline_script( 'foo', 'console.log("Hello, World!");', 'before' ); + wp_script_add_data( 'foo', 'worker', true ); }, 'expected' => '{{ wwo_config }}{{ wwo_inline_script }}', 'doing_it_wrong' => false, ), 'add-script-for-web-worker-offloading-with-after-data' => array( 'set_up' => static function (): void { - wp_enqueue_script( 'foo', 'https://example.com/foo.js', array( 'web-worker-offloading' ), '1.0.0', true ); + wp_enqueue_script( 'foo', 'https://example.com/foo.js', array(), '1.0.0', true ); wp_add_inline_script( 'foo', 'console.log("Hello, World!");', 'after' ); + wp_script_add_data( 'foo', 'worker', true ); }, 'expected' => '{{ wwo_config }}{{ wwo_inline_script }}', 'doing_it_wrong' => true, ), 'add-script-for-web-worker-offloading-with-before-and-after-data' => array( 'set_up' => static function (): void { - wp_enqueue_script( 'foo', 'https://example.com/foo.js', array( 'web-worker-offloading' ), '1.0.0', true ); + wp_enqueue_script( 'foo', 'https://example.com/foo.js', array(), '1.0.0', true ); wp_add_inline_script( 'foo', 'console.log("Hello, World!");', 'before' ); wp_add_inline_script( 'foo', 'console.log("Hello, World!");', 'after' ); + wp_script_add_data( 'foo', 'worker', true ); }, 'expected' => '{{ wwo_config }}{{ wwo_inline_script }}', 'doing_it_wrong' => true, ), 'add-async-script-for-web-worker-offloading-with-before-and-after-data' => array( 'set_up' => static function (): void { - wp_enqueue_script( 'foo', 'https://example.com/foo.js', array( 'web-worker-offloading' ), '1.0.0', array( 'strategy' => 'async' ) ); + wp_enqueue_script( 'foo', 'https://example.com/foo.js', array(), '1.0.0', array( 'strategy' => 'async' ) ); wp_add_inline_script( 'foo', 'console.log("Hello, World!");', 'before' ); wp_add_inline_script( 'foo', 'console.log("Hello, World!");', 'after' ); + wp_script_add_data( 'foo', 'worker', true ); }, 'expected' => '{{ wwo_config }}{{ wwo_inline_script }}', 'doing_it_wrong' => true, ), 'add-defer-script-for-web-worker-offloading-with-before-and-after-data' => array( 'set_up' => static function (): void { - wp_enqueue_script( 'foo', 'https://example.com/foo.js', array( 'web-worker-offloading' ), '1.0.0', array( 'strategy' => 'defer' ) ); + wp_enqueue_script( 'foo', 'https://example.com/foo.js', array(), '1.0.0', array( 'strategy' => 'defer' ) ); wp_add_inline_script( 'foo', 'console.log("Hello, World!");', 'before' ); wp_add_inline_script( 'foo', 'console.log("Hello, World!");', 'after' ); + wp_script_add_data( 'foo', 'worker', true ); }, 'expected' => '{{ wwo_config }}{{ wwo_inline_script }}', 'doing_it_wrong' => true, From 1ff2525310990c6340dad6de52cdca74a2aeeeeb Mon Sep 17 00:00:00 2001 From: thelovekesh Date: Sun, 25 Aug 2024 14:21:33 +0530 Subject: [PATCH 04/13] Update function name for updating worker data scripts deps --- plugins/web-worker-offloading/hooks.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/web-worker-offloading/hooks.php b/plugins/web-worker-offloading/hooks.php index ee58d58035..6da5ee0f27 100644 --- a/plugins/web-worker-offloading/hooks.php +++ b/plugins/web-worker-offloading/hooks.php @@ -76,7 +76,7 @@ function wwo_init(): void { * * @since n.e.x.t */ -function wwo_add_dependency_to_worker_scripts(): void { +function wwo_update_worker_scripts_deps_and_strategy(): void { foreach ( wp_scripts()->registered as $dep ) { if ( (bool) wp_scripts()->get_data( $dep->handle, 'worker') && @@ -91,7 +91,7 @@ function wwo_add_dependency_to_worker_scripts(): void { } } } -add_action( 'wp_print_scripts', 'wwo_add_dependency_to_worker_scripts' ); +add_action( 'wp_print_scripts', 'wwo_update_worker_scripts_deps_and_strategy' ); /** * Updates script type for handles having `web-worker-offloading` as dependency. From a9cf46c2b8d2309429b6731f25549b4db215ac07 Mon Sep 17 00:00:00 2001 From: thelovekesh Date: Sun, 25 Aug 2024 14:23:11 +0530 Subject: [PATCH 05/13] Update covers tag --- .../web-worker-offloading/tests/test-web-worker-offloading.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/web-worker-offloading/tests/test-web-worker-offloading.php b/plugins/web-worker-offloading/tests/test-web-worker-offloading.php index c196f74733..b634354d80 100644 --- a/plugins/web-worker-offloading/tests/test-web-worker-offloading.php +++ b/plugins/web-worker-offloading/tests/test-web-worker-offloading.php @@ -184,7 +184,7 @@ public static function data_update_script_types(): array { * Test `wwo_update_script_type`. * * @covers ::wwo_update_script_type - * @covers ::wwo_update_script_strategy + * @covers ::wwo_update_worker_scripts_deps_and_strategy * * @dataProvider data_update_script_types * From a75c06278a4165052a7e8fc5e4e3f3c5479c23c0 Mon Sep 17 00:00:00 2001 From: thelovekesh Date: Sun, 25 Aug 2024 14:32:26 +0530 Subject: [PATCH 06/13] Fix spacing --- plugins/web-worker-offloading/hooks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/web-worker-offloading/hooks.php b/plugins/web-worker-offloading/hooks.php index 6da5ee0f27..f9ca9bf68d 100644 --- a/plugins/web-worker-offloading/hooks.php +++ b/plugins/web-worker-offloading/hooks.php @@ -79,7 +79,7 @@ function wwo_init(): void { function wwo_update_worker_scripts_deps_and_strategy(): void { foreach ( wp_scripts()->registered as $dep ) { if ( - (bool) wp_scripts()->get_data( $dep->handle, 'worker') && + (bool) wp_scripts()->get_data( $dep->handle, 'worker' ) && ! in_array( 'web-worker-offloading', wp_scripts()->registered[ $dep->handle ]->deps, true ) ) { wp_scripts()->registered[ $dep->handle ]->deps[] = 'web-worker-offloading'; From 6c255e72e0a55a057610d55cdb390d31e373f645 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 26 Sep 2024 14:25:23 -0700 Subject: [PATCH 07/13] Use wp_default_scripts instead of wp_enqueue_scripts for script registration --- plugins/web-worker-offloading/hooks.php | 14 ++++++++------ .../tests/test-web-worker-offloading.php | 11 ++++------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/plugins/web-worker-offloading/hooks.php b/plugins/web-worker-offloading/hooks.php index f9ca9bf68d..2f98c060ef 100644 --- a/plugins/web-worker-offloading/hooks.php +++ b/plugins/web-worker-offloading/hooks.php @@ -36,17 +36,19 @@ function wwo_get_configuration(): array { } /** - * Initializes Web Worker Offloading. + * Registers defaults scripts for Web Worker Offloading. * * @since 0.1.0 + * + * @param WP_Scripts $scripts WP_Scripts instance. */ -function wwo_init(): void { +function wwo_register_default_scripts( WP_Scripts $scripts ): void { $partytown_js = file_get_contents( __DIR__ . '/build/partytown.js' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- It's a local filesystem path not a remote request. if ( false === $partytown_js ) { return; } - wp_register_script( + $scripts->add( 'web-worker-offloading', '', array(), @@ -54,7 +56,7 @@ function wwo_init(): void { array( 'in_footer' => false ) ); - wp_add_inline_script( + $scripts->add_inline_script( 'web-worker-offloading', sprintf( 'window.partytown = %s;', @@ -63,9 +65,9 @@ function wwo_init(): void { 'before' ); - wp_add_inline_script( 'web-worker-offloading', $partytown_js ); + $scripts->add_inline_script( 'web-worker-offloading', $partytown_js ); } -add_action( 'wp_enqueue_scripts', 'wwo_init' ); +add_action( 'wp_default_scripts', 'wwo_register_default_scripts' ); /** * Adds `web-worker-offloading` as dependency to scripts with `worker` data. Also, marks their strategy as `async`. diff --git a/plugins/web-worker-offloading/tests/test-web-worker-offloading.php b/plugins/web-worker-offloading/tests/test-web-worker-offloading.php index b634354d80..40e0cff2d2 100644 --- a/plugins/web-worker-offloading/tests/test-web-worker-offloading.php +++ b/plugins/web-worker-offloading/tests/test-web-worker-offloading.php @@ -60,13 +60,13 @@ static function ( $config ) { } /** - * @covers ::wwo_init + * @covers ::wwo_register_default_scripts */ - public function test_wwo_init(): void { - $this->assertEquals( 10, has_action( 'wp_enqueue_scripts', 'wwo_init' ) ); + public function test_wwo_register_default_scripts(): void { + $this->assertEquals( 10, has_action( 'wp_default_scripts', 'wwo_register_default_scripts' ) ); // Register scripts. - wwo_init(); + wp_scripts(); $wp_content_dir = WP_CONTENT_DIR; $partytown_config = wwo_get_configuration(); @@ -193,9 +193,6 @@ public static function data_update_script_types(): array { * @param bool $doing_it_wrong Whether to expect a `_doing_it_wrong` notice. */ public function test_update_script_types( Closure $set_up, string $expected, bool $doing_it_wrong ): void { - // Setup. - wwo_init(); - $wwo_config_data = wp_scripts()->get_inline_script_data( 'web-worker-offloading', 'before' ); $wwo_inline_script_data = wp_scripts()->get_inline_script_data( 'web-worker-offloading', 'after' ); From 34405c2cd1fb1f545af9c0f16580fcd817032908 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 26 Sep 2024 14:29:27 -0700 Subject: [PATCH 08/13] Remove unrelated assertions from testing wwo_register_default_scripts --- .../tests/test-web-worker-offloading.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/plugins/web-worker-offloading/tests/test-web-worker-offloading.php b/plugins/web-worker-offloading/tests/test-web-worker-offloading.php index 40e0cff2d2..f97c8f3d60 100644 --- a/plugins/web-worker-offloading/tests/test-web-worker-offloading.php +++ b/plugins/web-worker-offloading/tests/test-web-worker-offloading.php @@ -83,12 +83,6 @@ public function test_wwo_register_default_scripts(): void { ); $this->assertEquals( file_get_contents( $partytown_lib . 'partytown.js' ), $after_data ); $this->assertTrue( wp_script_is( 'web-worker-offloading', 'registered' ) ); - - // Ensure that Partytown is enqueued when a script depends on it. - wp_enqueue_script( 'partytown-test', 'https://example.com/test.js', array( 'web-worker-offloading' ) ); - - $this->assertTrue( wp_script_is( 'web-worker-offloading', 'enqueued' ) ); - $this->assertTrue( wp_script_is( 'partytown-test', 'enqueued' ) ); } /** From 0c2d7b23b70b4ede5abc30ff54e922e3594ba97d Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 26 Sep 2024 15:09:00 -0700 Subject: [PATCH 09/13] Use print_scripts_array filter instead of wp_print_scripts action --- plugins/web-worker-offloading/hooks.php | 37 ++++++----- .../tests/test-web-worker-offloading.php | 63 ++++++++++++++----- 2 files changed, 70 insertions(+), 30 deletions(-) diff --git a/plugins/web-worker-offloading/hooks.php b/plugins/web-worker-offloading/hooks.php index 2f98c060ef..b41cbf837b 100644 --- a/plugins/web-worker-offloading/hooks.php +++ b/plugins/web-worker-offloading/hooks.php @@ -70,30 +70,35 @@ function wwo_register_default_scripts( WP_Scripts $scripts ): void { add_action( 'wp_default_scripts', 'wwo_register_default_scripts' ); /** - * Adds `web-worker-offloading` as dependency to scripts with `worker` data. Also, marks their strategy as `async`. + * Prepends web-worker-offloading to the list of scripts to print if one of the queued scripts is offloaded to a worker. * - * This is needed because scripts offloaded to a worker thread can be considered async. However, they may include `before` and `after` inline - * scripts that need sequential execution. Once marked as async, `filter_eligible_strategies()` determines if the - * script is eligible for async execution. If so, it will be offloaded to the worker thread. + * This also marks their strategy as `async`. This is needed because scripts offloaded to a worker thread can be + * considered async. However, they may include `before` and `after` inline scripts that need sequential execution. Once + * marked as async, `filter_eligible_strategies()` determines if the script is eligible for async execution. If so, it + * will be offloaded to the worker thread. * - * @since n.e.x.t + * @since 0.1.0 + * + * @param string[]|mixed $to_do An array of enqueued script dependency handles. + * @return string[] Script handles. */ -function wwo_update_worker_scripts_deps_and_strategy(): void { - foreach ( wp_scripts()->registered as $dep ) { - if ( - (bool) wp_scripts()->get_data( $dep->handle, 'worker' ) && - ! in_array( 'web-worker-offloading', wp_scripts()->registered[ $dep->handle ]->deps, true ) - ) { - wp_scripts()->registered[ $dep->handle ]->deps[] = 'web-worker-offloading'; +function wwo_filter_print_scripts_array( $to_do ): array { + $scripts = wp_scripts(); + foreach ( (array) $to_do as $handle ) { + if ( true === $scripts->get_data( $handle, 'worker' ) ) { + $scripts->set_group( 'web-worker-offloading', false, 0 ); // Try to print in the head. + array_unshift( $to_do, 'web-worker-offloading' ); - if ( false === wp_scripts()->get_data( $dep->handle, 'strategy' ) ) { - wp_script_add_data( $dep->handle, 'strategy', 'async' ); // The 'defer' strategy would work as well. - wp_script_add_data( $dep->handle, 'wwo_strategy_added', true ); + // TODO: This should be reconsidered because scripts needing to be offloaded will often have after scripts. See . + if ( false === wp_scripts()->get_data( $handle, 'strategy' ) ) { + wp_script_add_data( $handle, 'strategy', 'async' ); // The 'defer' strategy would work as well. + wp_script_add_data( $handle, 'wwo_strategy_added', true ); } } } + return $to_do; } -add_action( 'wp_print_scripts', 'wwo_update_worker_scripts_deps_and_strategy' ); +add_filter( 'print_scripts_array', 'wwo_filter_print_scripts_array' ); /** * Updates script type for handles having `web-worker-offloading` as dependency. diff --git a/plugins/web-worker-offloading/tests/test-web-worker-offloading.php b/plugins/web-worker-offloading/tests/test-web-worker-offloading.php index f97c8f3d60..b2e614151d 100644 --- a/plugins/web-worker-offloading/tests/test-web-worker-offloading.php +++ b/plugins/web-worker-offloading/tests/test-web-worker-offloading.php @@ -178,7 +178,7 @@ public static function data_update_script_types(): array { * Test `wwo_update_script_type`. * * @covers ::wwo_update_script_type - * @covers ::wwo_update_worker_scripts_deps_and_strategy + * @covers ::wwo_filter_print_scripts_array * * @dataProvider data_update_script_types * @@ -187,19 +187,7 @@ public static function data_update_script_types(): array { * @param bool $doing_it_wrong Whether to expect a `_doing_it_wrong` notice. */ public function test_update_script_types( Closure $set_up, string $expected, bool $doing_it_wrong ): void { - $wwo_config_data = wp_scripts()->get_inline_script_data( 'web-worker-offloading', 'before' ); - $wwo_inline_script_data = wp_scripts()->get_inline_script_data( 'web-worker-offloading', 'after' ); - - $expected = str_replace( - '{{ wwo_config }}', - wp_get_inline_script_tag( $wwo_config_data, array( 'id' => 'web-worker-offloading-js-before' ) ), - $expected - ); - $expected = str_replace( - '{{ wwo_inline_script }}', - wp_get_inline_script_tag( $wwo_inline_script_data, array( 'id' => 'web-worker-offloading-js-after' ) ), - $expected - ); + $expected = $this->replace_placeholders( $expected ); if ( $doing_it_wrong ) { $this->setExpectedIncorrectUsage( 'wwo_update_script_type' ); @@ -214,6 +202,53 @@ public function test_update_script_types( Closure $set_up, string $expected, boo $this->assertEquals( $expected, $actual ); } + + /** + * Test head and footer scripts. + * + * @covers ::wwo_update_script_type + * @covers ::wwo_filter_print_scripts_array + */ + public function test_head_and_footer_scripts(): void { + wp_enqueue_script( 'foo', 'https://example.com/foo.js', array(), '1.0.0', false ); + wp_script_add_data( 'foo', 'worker', true ); + + $this->assertEquals( + $this->replace_placeholders( '{{ wwo_config }}{{ wwo_inline_script }}' ), + trim( get_echo( 'wp_print_head_scripts' ) ) + ); + + wp_enqueue_script( 'bar', 'https://example.com/bar.js', array(), '1.0.0', true ); + wp_script_add_data( 'bar', 'worker', true ); + + $this->assertEquals( + $this->replace_placeholders( '' ), + trim( get_echo( 'wp_print_footer_scripts' ) ) + ); + } + + /** + * Replace placeholders. + * + * @param string $template Template. + * @return string Template with placeholders replaced. + */ + private function replace_placeholders( string $template ): string { + $wwo_config_data = wp_scripts()->get_inline_script_data( 'web-worker-offloading', 'before' ); + $wwo_inline_script_data = wp_scripts()->get_inline_script_data( 'web-worker-offloading', 'after' ); + + $template = str_replace( + '{{ wwo_config }}', + wp_get_inline_script_tag( $wwo_config_data, array( 'id' => 'web-worker-offloading-js-before' ) ), + $template + ); + return str_replace( + '{{ wwo_inline_script }}', + wp_get_inline_script_tag( $wwo_inline_script_data, array( 'id' => 'web-worker-offloading-js-after' ) ), + $template + ); + } + /** * Reset WP_Scripts and WP_Styles. */ From 6fb6553ba3c214482fd8e4001e4168c86af8c420 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 26 Sep 2024 15:14:35 -0700 Subject: [PATCH 10/13] Add tests for offloading script in head, footer, and both --- .../tests/test-web-worker-offloading.php | 47 ++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/plugins/web-worker-offloading/tests/test-web-worker-offloading.php b/plugins/web-worker-offloading/tests/test-web-worker-offloading.php index b2e614151d..8202e69e1a 100644 --- a/plugins/web-worker-offloading/tests/test-web-worker-offloading.php +++ b/plugins/web-worker-offloading/tests/test-web-worker-offloading.php @@ -202,7 +202,6 @@ public function test_update_script_types( Closure $set_up, string $expected, boo $this->assertEquals( $expected, $actual ); } - /** * Test head and footer scripts. * @@ -227,6 +226,52 @@ public function test_head_and_footer_scripts(): void { ); } + /** + * Test only head script. + * + * @covers ::wwo_update_script_type + * @covers ::wwo_filter_print_scripts_array + */ + public function test_only_head_script(): void { + wp_enqueue_script( 'foo', 'https://example.com/foo.js', array(), '1.0.0', false ); + wp_script_add_data( 'foo', 'worker', true ); + + $this->assertEquals( + $this->replace_placeholders( '{{ wwo_config }}{{ wwo_inline_script }}' ), + trim( get_echo( 'wp_print_head_scripts' ) ) + ); + + wp_enqueue_script( 'bar', 'https://example.com/bar.js', array(), '1.0.0', true ); + + $this->assertEquals( + $this->replace_placeholders( '' ), + trim( get_echo( 'wp_print_footer_scripts' ) ) + ); + } + + /** + * Test only footer script. + * + * @covers ::wwo_update_script_type + * @covers ::wwo_filter_print_scripts_array + */ + public function test_only_footer_script(): void { + wp_enqueue_script( 'foo', 'https://example.com/foo.js', array(), '1.0.0', false ); + + $this->assertEquals( + $this->replace_placeholders( '' ), + trim( get_echo( 'wp_print_head_scripts' ) ) + ); + + wp_enqueue_script( 'bar', 'https://example.com/bar.js', array(), '1.0.0', true ); + wp_script_add_data( 'bar', 'worker', true ); + + $this->assertEquals( + $this->replace_placeholders( '{{ wwo_config }}{{ wwo_inline_script }}' ), + trim( get_echo( 'wp_print_footer_scripts' ) ) + ); + } + /** * Replace placeholders. * From bc843d58fc2a09269b997779a7a0ade481614177 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 26 Sep 2024 15:17:09 -0700 Subject: [PATCH 11/13] Account for truthy value for worker data key --- plugins/web-worker-offloading/hooks.php | 2 +- .../web-worker-offloading/tests/test-web-worker-offloading.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/web-worker-offloading/hooks.php b/plugins/web-worker-offloading/hooks.php index b41cbf837b..146b900497 100644 --- a/plugins/web-worker-offloading/hooks.php +++ b/plugins/web-worker-offloading/hooks.php @@ -85,7 +85,7 @@ function wwo_register_default_scripts( WP_Scripts $scripts ): void { function wwo_filter_print_scripts_array( $to_do ): array { $scripts = wp_scripts(); foreach ( (array) $to_do as $handle ) { - if ( true === $scripts->get_data( $handle, 'worker' ) ) { + if ( true === (bool) $scripts->get_data( $handle, 'worker' ) ) { $scripts->set_group( 'web-worker-offloading', false, 0 ); // Try to print in the head. array_unshift( $to_do, 'web-worker-offloading' ); diff --git a/plugins/web-worker-offloading/tests/test-web-worker-offloading.php b/plugins/web-worker-offloading/tests/test-web-worker-offloading.php index 8202e69e1a..e13598d03b 100644 --- a/plugins/web-worker-offloading/tests/test-web-worker-offloading.php +++ b/plugins/web-worker-offloading/tests/test-web-worker-offloading.php @@ -110,7 +110,7 @@ public static function data_update_script_types(): array { 'add-defer-script-for-web-worker-offloading' => array( 'set_up' => static function (): void { wp_enqueue_script( 'foo', 'https://example.com/foo.js', array(), '1.0.0', array( 'strategy' => 'defer' ) ); - wp_script_add_data( 'foo', 'worker', true ); + wp_script_add_data( 'foo', 'worker', 1 ); }, 'expected' => '{{ wwo_config }}{{ wwo_inline_script }}', 'doing_it_wrong' => false, From 98929371d6fb6675123e883915c39a9e1ec4fa50 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 26 Sep 2024 15:27:04 -0700 Subject: [PATCH 12/13] Update readme --- plugins/web-worker-offloading/readme.txt | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/plugins/web-worker-offloading/readme.txt b/plugins/web-worker-offloading/readme.txt index e1fb6f3fe3..774ff9139d 100644 --- a/plugins/web-worker-offloading/readme.txt +++ b/plugins/web-worker-offloading/readme.txt @@ -13,4 +13,15 @@ Offload JavaScript execution to a Web Worker. This plugin offloads JavaScript execution to a Web Worker, improving performance by freeing up the main thread. -In order to opt-in a script to be loaded in a worker, simply add the `web-worker-offloading` script as a dependency. +In order to opt-in a script to be loaded in a worker, simply add `worker` script data to a registered script. For example, +if you have a script registered with the handle of `foo`, opt-in to offload it to a web worker by doing: + +` +wp_script_add_data( 'foo', 'worker', true ); +` + +== Frequently Asked Questions == + += Why are my offloaded scripts not working and I see a 404 error in the console for `partytown-sandbox-sw.html`? = + +If you find that your offloaded scripts aren't working while also seeing a 404 error in the console for a file at `/wp-content/plugins/web-worker-offloading/build/partytown-sandbox-sw.html?1727389399791` then it's likely you have Chrome DevTools open with the "Bypass for Network" toggle enabled in the Application panel. From bfb9e116a6c33cffbe729d5593e07448502ec1f2 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Fri, 27 Sep 2024 09:59:15 -0700 Subject: [PATCH 13/13] Revert param name change --- plugins/web-worker-offloading/hooks.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/web-worker-offloading/hooks.php b/plugins/web-worker-offloading/hooks.php index 146b900497..d6ae5d9be4 100644 --- a/plugins/web-worker-offloading/hooks.php +++ b/plugins/web-worker-offloading/hooks.php @@ -79,15 +79,15 @@ function wwo_register_default_scripts( WP_Scripts $scripts ): void { * * @since 0.1.0 * - * @param string[]|mixed $to_do An array of enqueued script dependency handles. + * @param string[]|mixed $script_handles An array of enqueued script dependency handles. * @return string[] Script handles. */ -function wwo_filter_print_scripts_array( $to_do ): array { +function wwo_filter_print_scripts_array( $script_handles ): array { $scripts = wp_scripts(); - foreach ( (array) $to_do as $handle ) { + foreach ( (array) $script_handles as $handle ) { if ( true === (bool) $scripts->get_data( $handle, 'worker' ) ) { $scripts->set_group( 'web-worker-offloading', false, 0 ); // Try to print in the head. - array_unshift( $to_do, 'web-worker-offloading' ); + array_unshift( $script_handles, 'web-worker-offloading' ); // TODO: This should be reconsidered because scripts needing to be offloaded will often have after scripts. See . if ( false === wp_scripts()->get_data( $handle, 'strategy' ) ) { @@ -96,7 +96,7 @@ function wwo_filter_print_scripts_array( $to_do ): array { } } } - return $to_do; + return $script_handles; } add_filter( 'print_scripts_array', 'wwo_filter_print_scripts_array' );