From b57233d62ba1163c3b1b3273c29f322f1bd5a8da Mon Sep 17 00:00:00 2001 From: Matt Robinson Date: Sun, 12 Nov 2023 11:48:19 +0000 Subject: [PATCH] WP-r55888: Script Loader: Improve performance of inlined styles (#272) * WP-r55888: Script Loader: Improve performance of wp_maybe_inline_styles function. The `wp_maybe_inline_styles` function is called twice on the average page load. On it's second run however, it did not check to see if the style had already been processed on the first run. This resulted in calling `filesize` and `get_file_contents` unnecessarily, which was bad for performance. Now, the loop around the queued styles, checks to see if the source is set to false, meaning it has already been processed. This change also replaces calls to `filesize` with the core function `wp_filesize`, which improves extensibility. WP:Props spacedmonkey, flixos90, peterwilsoncc, joemcgill. Fixes https://core.trac.wordpress.org/ticket/58394. Conflicts: - tests/phpunit/tests/dependencies/styles.php --- Merges https://core.trac.wordpress.org/changeset/55888 / WordPress/wordpress-develop@582ddb82f4 to ClassicPress. * Fix merge conflicts and use css file from repo * WP-r55909: Script Loader: Add a check to see in style is registered in wp_maybe_inline_styles. Add a check in `wp_maybe_inline_styles` to check that style is registered before processing items in queue. It is possible that developers may have called `wp_deregister_style`, unregistering style but the style still be in the queue to be processed. Without this check, typing to access the `src` property would result in a notice error. Follow on from https://core.trac.wordpress.org/changeset/55888. WP:Props spacedmonkey, flixos90, dd32, kebbet. See https://core.trac.wordpress.org/ticket/58394. --- Merges https://core.trac.wordpress.org/changeset/55909 / WordPress/wordpress-develop@559e6cecf4 to ClassicPress. * Use smaller src css for testing purposes --------- Co-authored-by: Jonny Harris --- src/wp-includes/script-loader.php | 17 ++- tests/phpunit/tests/dependencies/styles.php | 115 ++++++++++++++++++++ 2 files changed, 128 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php index 3d0083f2ba..680417061a 100644 --- a/src/wp-includes/script-loader.php +++ b/src/wp-includes/script-loader.php @@ -2145,12 +2145,21 @@ function wp_maybe_inline_styles() { // Build an array of styles that have a path defined. foreach ( $wp_styles->queue as $handle ) { - if ( wp_styles()->get_data( $handle, 'path' ) && file_exists( $wp_styles->registered[ $handle ]->extra['path'] ) ) { + if ( ! isset( $wp_styles->registered[ $handle ] ) ) { + continue; + } + $src = $wp_styles->registered[ $handle ]->src; + $path = $wp_styles->get_data( $handle, 'path' ); + if ( $path && $src ) { + $size = wp_filesize( $path ); + if ( ! $size ) { + continue; + } $styles[] = array( 'handle' => $handle, - 'src' => $wp_styles->registered[ $handle ]->src, - 'path' => $wp_styles->registered[ $handle ]->extra['path'], - 'size' => filesize( $wp_styles->registered[ $handle ]->extra['path'] ), + 'src' => $src, + 'path' => $path, + 'size' => $size, ); } } diff --git a/tests/phpunit/tests/dependencies/styles.php b/tests/phpunit/tests/dependencies/styles.php index d86fcff061..6c88b0e205 100644 --- a/tests/phpunit/tests/dependencies/styles.php +++ b/tests/phpunit/tests/dependencies/styles.php @@ -519,4 +519,119 @@ public function data_styles_with_media() { ), ); } + + /** + * @ticket 58394 + * + * @covers ::wp_maybe_inline_styles + */ + public function test_wp_maybe_inline_styles() { + wp_register_style( 'test-handle', '/' . WPINC . '/css/wp-pointer.css' ); + wp_style_add_data( 'test-handle', 'path', ABSPATH . WPINC . '/css/wp-pointer.css' ); + + wp_enqueue_style( 'test-handle' ); + + wp_maybe_inline_styles(); + + $this->assertFalse( $GLOBALS['wp_styles']->registered['test-handle']->src, 'Source of style should be reset to false' ); + + $css = file_get_contents( ABSPATH . WPINC . '/css/wp-pointer.css' ); + $this->assertSameSets( $GLOBALS['wp_styles']->registered['test-handle']->extra['after'], array( $css ), 'Source of style should set to after property' ); + } + + /** + * @ticket 58394 + * + * @covers ::wp_maybe_inline_styles + */ + public function test_wp_maybe_inline_styles_dequeue_styles() { + $filter = new MockAction(); + add_filter( 'pre_wp_filesize', array( $filter, 'filter' ) ); + wp_register_style( 'test-handle', '/' . WPINC . '/css/wp-pointer.css' ); + wp_style_add_data( 'test-handle', 'path', ABSPATH . WPINC . '/css/wp-pointer.css' ); + + wp_enqueue_style( 'test-handle' ); + + wp_deregister_style( 'test-handle' ); + + wp_maybe_inline_styles(); + + $this->assertSame( 0, $filter->get_call_count() ); + } + + /** + * wp_filesize should be only be called once, as on the second run of wp_maybe_inline_styles, + * src will be set to false and filesize will not be requested. + * + * @ticket 58394 + * + * @covers ::wp_maybe_inline_styles + */ + public function test_wp_maybe_inline_styles_multiple_runs() { + $filter = new MockAction(); + add_filter( 'pre_wp_filesize', array( $filter, 'filter' ) ); + wp_register_style( 'test-handle', '/' . WPINC . '/css/wp-pointer.css' ); + wp_style_add_data( 'test-handle', 'path', ABSPATH . WPINC . '/css/wp-pointer.css' ); + + wp_enqueue_style( 'test-handle' ); + + wp_maybe_inline_styles(); + wp_maybe_inline_styles(); + + $this->assertSame( 1, $filter->get_call_count() ); + } + + /** + * @ticket 58394 + * + * @covers ::wp_maybe_inline_styles + */ + public function test_test_wp_maybe_inline_styles_missing_file() { + $filter = new MockAction(); + add_filter( 'pre_wp_filesize', array( $filter, 'filter' ) ); + $url = '/' . WPINC . '/css/invalid.css'; + wp_register_style( 'test-handle', $url ); + wp_style_add_data( 'test-handle', 'path', ABSPATH . WPINC . '/css/invalid.css' ); + + wp_enqueue_style( 'test-handle' ); + + wp_maybe_inline_styles(); + + $this->assertSame( $GLOBALS['wp_styles']->registered['test-handle']->src, $url, 'Source should not change' ); + $this->assertArrayNotHasKey( 'after', $GLOBALS['wp_styles']->registered['test-handle']->extra, 'Source of style not should set to after property' ); + $this->assertSame( 1, $filter->get_call_count(), 'wp_filesize should only be called once' ); + } + + /** + * @ticket 58394 + * + * @covers ::wp_maybe_inline_styles + */ + public function test_wp_maybe_inline_styles_no_src() { + wp_register_style( 'test-handle', false ); + wp_style_add_data( 'test-handle', 'path', ABSPATH . WPINC . '/css/wp-pointer.css' ); + + wp_enqueue_style( 'test-handle' ); + + wp_maybe_inline_styles(); + + $this->assertFalse( $GLOBALS['wp_styles']->registered['test-handle']->src, 'Source of style should remain false' ); + $this->assertArrayNotHasKey( 'after', $GLOBALS['wp_styles']->registered['test-handle']->extra, 'Source of style not should set to after property' ); + } + + /** + * @ticket 58394 + * + * @covers ::wp_maybe_inline_styles + */ + public function test_wp_maybe_inline_styles_no_path() { + $url = '/' . WPINC . '/css/wp-pointer.css'; + wp_register_style( 'test-handle', $url ); + + wp_enqueue_style( 'test-handle' ); + + wp_maybe_inline_styles(); + + $this->assertSame( $GLOBALS['wp_styles']->registered['test-handle']->src, $url ); + } }