Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion modules/site-health/audit-enqueued-assets/helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,32 @@ function perflab_aea_get_total_size_bytes_enqueued_styles() {

/**
* Convert full URL paths to absolute paths.
* Covers Standard WP configuration, wp-content outside WP directories and subdirectories.
* Ex: https://example.com/content/themes/, https://example.com/wp/wp-includes/
*
* @since 1.0.0
*
* @param string $resource_url URl resource link.
* @return string Returns absolute path to the resource.
*/
function perflab_aea_get_path_from_resource_url( $resource_url ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Im noticing quite a few varying function namespaces - maybe this function should be called perflab_get_path_from_resource_url?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hello, @dainemawer all functions are prepending "perflab_aea", what are the function namespaces varying? maybe I'm missing some

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the approach of having module specific namespaces (all of them starting with perflab_ though due to the overall plugin) is a solid approach, which avoids us running into accidental conflicts between individual modules.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@manuelRod I was thinking more globally across the plugin - I've noticed other functions are all prefixed with perflab_ but not necessarily perflab_aea - that being said it sounds like @felixarntz is good with this approach - Im not swayed either way - just wanted to call it out for consistency reasons :)

return ABSPATH . wp_make_link_relative( $resource_url );
if ( ! $resource_url ) {
return '';
}

// Different content folder ex. /content/.
if ( 0 === strpos( $resource_url, content_url() ) ) {
return WP_CONTENT_DIR . substr( $resource_url, strlen( content_url() ) );
}

// wp-content in a subdirectory. ex. /blog/wp-content/.
$site_url = untrailingslashit( site_url() );
if ( 0 === strpos( $resource_url, $site_url ) ) {
return untrailingslashit( ABSPATH ) . substr( $resource_url, strlen( $site_url ) );
}

// Standard wp-content configuration.
return untrailingslashit( ABSPATH ) . wp_make_link_relative( $resource_url );
}

/**
Expand Down
74 changes: 56 additions & 18 deletions modules/site-health/audit-enqueued-assets/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
require_once __DIR__ . '/helper.php';

/**
* Audit enqueued scripts in is_front_page(). Ignore /wp-includes scripts.
* Audit enqueued and printed scripts in is_front_page(). Ignore /wp-includes scripts.
*
* It will save information in a transient for 12 hours.
*
Expand All @@ -25,22 +25,39 @@ function perflab_aea_audit_enqueued_scripts() {
global $wp_scripts;
$enqueued_scripts = array();

foreach ( $wp_scripts->queue as $handle ) {
$src = $wp_scripts->registered[ $handle ]->src;
if ( $src && ! strpos( $src, 'wp-includes' ) ) {
$enqueued_scripts[] = array(
'src' => $src,
'size' => perflab_aea_get_resource_file_size( perflab_aea_get_path_from_resource_url( $src ) ),
);
foreach ( $wp_scripts->done as $handle ) {
$script = $wp_scripts->registered[ $handle ];

if ( ! $script->src || false !== strpos( $script->src, 'wp-includes' ) ) {
continue;
}

// Add any extra data (inlined) that was passed with the script.
$inline_size = 0;
if ( ! empty( $script->extra ) && ! empty( $script->extra['after'] ) ) {
foreach ( $script->extra['after'] as $extra ) {
$inline_size += ( is_string( $extra ) ) ? mb_strlen( $extra, '8bit' ) : 0;
}
}

$path = perflab_aea_get_path_from_resource_url( $script->src );
if ( ! $path ) {
continue;
}

$enqueued_scripts[] = array(
'src' => $script->src,
'size' => perflab_aea_get_resource_file_size( $path ) + $inline_size,
);

}
set_transient( 'aea_enqueued_front_page_scripts', $enqueued_scripts, 12 * HOUR_IN_SECONDS );
}
}
add_action( 'wp_print_scripts', 'perflab_aea_audit_enqueued_scripts' );
add_action( 'wp_footer', 'perflab_aea_audit_enqueued_scripts', PHP_INT_MAX );

/**
* Audit enqueued styles in the frontend. Ignore /wp-includes styles.
* Audit enqueued and printed styles in the frontend. Ignore /wp-includes styles.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would we ignore wp-includes? Gutenberg for instance adds a couple of stylesheets that arent exactly optimized. My opinion is that we should give the user the full picture, even if it means flagging WP for enqueuing unnecessary stylesheets.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dainemawer those assets are included by default by wp, and this module focus on an overall overview of external assets being enqueued (plugins, theme), I think it would make more noise to include wp-includes, since most of the consumers won't be techies and won't know how to react on it.
I agree that going forward and as we iterate over this module, we can show more useful information, at that point, we can add more info (like wp-includes) and tips on how to improve it, but for now, I would just ignore them.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thats a fair statement, thanks @manuelRod !

*
* It will save information in a transient for 12 hours.
*
Expand All @@ -50,19 +67,40 @@ function perflab_aea_audit_enqueued_styles() {
if ( ! is_admin() && is_front_page() && current_user_can( 'view_site_health_checks' ) && false === get_transient( 'aea_enqueued_front_page_styles' ) ) {
global $wp_styles;
$enqueued_styles = array();
foreach ( $wp_styles->queue as $handle ) {
$src = $wp_styles->registered[ $handle ]->src;
if ( $src && ! strpos( $src, 'wp-includes' ) ) {
$enqueued_styles[] = array(
'src' => $src,
'size' => perflab_aea_get_resource_file_size( perflab_aea_get_path_from_resource_url( $src ) ),
);
foreach ( $wp_styles->done as $handle ) {
$style = $wp_styles->registered[ $handle ];

if ( ! $style->src || false !== strpos( $style->src, 'wp-includes' ) ) {
continue;
}

// Check if we already have the style's path ( part of a refactor for block styles from 5.9 ).
if ( ! empty( $style->extra ) && ! empty( $style->extra['path'] ) ) {
$path = $style->extra['path'];
} else { // Fallback to getting the path from the style's src.
$path = perflab_aea_get_path_from_resource_url( $style->src );
if ( ! $path ) {
continue;
}
}

// Add any extra data (inlined) that was passed with the style.
$inline_size = 0;
if ( ! empty( $style->extra ) && ! empty( $style->extra['after'] ) ) {
foreach ( $style->extra['after'] as $extra ) {
$inline_size += ( is_string( $extra ) ) ? mb_strlen( $extra, '8bit' ) : 0;
}
}

$enqueued_styles[] = array(
'src' => $style->src,
'size' => perflab_aea_get_resource_file_size( $path ) + $inline_size,
);
}
set_transient( 'aea_enqueued_front_page_styles', $enqueued_styles, 12 * HOUR_IN_SECONDS );
}
}
add_action( 'wp_print_styles', 'perflab_aea_audit_enqueued_styles' );
add_action( 'wp_footer', 'perflab_aea_audit_enqueued_styles', PHP_INT_MAX );

/**
* Adds tests to site health.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,41 @@ public function test_perflab_aea_get_total_size_bytes_enqueued_styles() {
* Tests perflab_aea_get_path_from_resource_url() functionality.
*/
public function test_perflab_aea_get_path_from_resource_url() {
$test_url = 'https://example.com/wp-content/themes/test-theme/style.css';
$expected_path = ABSPATH . '/wp-content/themes/test-theme/style.css';
$test_url = site_url() . '/wp-content/themes/test-theme/style.css';
$expected_path = ABSPATH . 'wp-content/themes/test-theme/style.css';
$this->assertSame( $expected_path, perflab_aea_get_path_from_resource_url( $test_url ) );
}

/**
* Tests perflab_aea_get_path_from_resource_url() functionality when wp-content in subdirectory.
*/
public function test_perflab_aea_get_path_from_resource_url_subdirectory() {
$test_url = site_url() . '/wp/wp-content/themes/test-theme/style.css';
$expected_path = ABSPATH . 'wp/wp-content/themes/test-theme/style.css';
$this->assertSame( $expected_path, perflab_aea_get_path_from_resource_url( $test_url ) );
}

/**
* Tests perflab_aea_get_path_from_resource_url() functionality empty $url.
*/
public function test_perflab_aea_get_path_from_resource_url_empty_url() {
$test_url = false;
$expected_path = '';
$this->assertSame( $expected_path, perflab_aea_get_path_from_resource_url( $test_url ) );
}

/**
* Tests perflab_aea_get_path_from_resource_url() functionality when wp-content outside wp directory.
*/
public function test_perflab_aea_get_path_from_resource_url_outside_wp_setup() {
$test_url = site_url() . '/content/themes/test-theme/style.css';
$expected_path = WP_CONTENT_DIR . '/themes/test-theme/style.css';
add_filter(
'content_url',
function( $url ) {
return site_url() . '/content';
}
);
$this->assertSame( $expected_path, perflab_aea_get_path_from_resource_url( $test_url ) );
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ public function test_perflab_aea_audit_enqueued_scripts() {
wp_enqueue_script( 'script3', 'example3.com', array() );
wp_dequeue_script( 'script3' );

$inline_script = 'console.log("after");';
wp_add_inline_script( 'script1', $inline_script );

get_echo( 'wp_print_scripts' );
perflab_aea_audit_enqueued_scripts();
$transient = get_transient( 'aea_enqueued_front_page_scripts' );
$this->assertNotEmpty( $transient );
Expand All @@ -68,7 +72,7 @@ public function test_perflab_aea_audit_enqueued_scripts() {
array(
array(
'src' => 'example1.com',
'size' => 0,
'size' => 0 + mb_strlen( $inline_script, '8bit' ),
),
),
$transient
Expand All @@ -87,6 +91,9 @@ public function test_perflab_aea_audit_enqueued_styles_transient_already_set() {
$this->current_user_can_view_site_health_checks_cap();

Audit_Assets_Transients_Set::set_style_transient_with_data( 3 );

// Avoids echoing styles.
get_echo( 'wp_print_styles' );
perflab_aea_audit_enqueued_styles();
$transient = get_transient( 'aea_enqueued_front_page_styles' );
$this->assertIsArray( $transient );
Expand Down Expand Up @@ -126,6 +133,13 @@ public function test_perflab_aea_audit_enqueued_styles() {
wp_enqueue_style( 'style3', 'example3.com', array() );
wp_dequeue_style( 'style3' );

// Adding inline style to style1.
$style = ".test {\n";
$style .= "\tbackground: red;\n";
$style .= '}';
wp_add_inline_style( 'style1', $style );
get_echo( 'wp_print_styles' );

perflab_aea_audit_enqueued_styles();
$transient = get_transient( 'aea_enqueued_front_page_styles' );
$this->assertNotEmpty( $transient );
Expand All @@ -134,7 +148,7 @@ public function test_perflab_aea_audit_enqueued_styles() {
array(
array(
'src' => 'example1.com',
'size' => 0,
'size' => 0 + mb_strlen( $style, '8bit' ),
),
),
$transient
Expand Down