Skip to content

Instantly share code, notes, and snippets.

@westonruter
Forked from mukeshpanchal27/README.md
Last active August 15, 2024 18:54
Show Gist options
  • Save westonruter/840c12249c8a44a4fc32053d845bcb83 to your computer and use it in GitHub Desktop.
Save westonruter/840c12249c8a44a4fc32053d845bcb83 to your computer and use it in GitHub Desktop.

Usage:

The default repetition count is 1000. You can pass a different iteration

wp eval-file html-api-benchmark.php
wp eval-file html-api-benchmark.php 10000

See PR WordPress/performance#1471

Average time spent for 10000 iterations:
  Regex     - 2020.4088
  TagParser - 17137.1823
TagParser is slower than Regex by 8.48x

This is testing against the latest WP 6.7 nightly (6.7-alpha-58899).

On WordPress 6.6.1 the results are:

Average time spent for 10000 iterations:
  Regex     - 1539.8833
  TagParser - 16220.6597
TagParser is slower than Regex by 10.53x
<?php
namespace AutoSizesBenchmarking;
use WP_HTML_Tag_Processor;
// Setup.
$test_images = array(
// Lazy-loaded responsive image which already has auto added.
'<img src="https://pd.w.org/2024/08/36566abfcb2952e20.99062056-300x225.jpg" srcset="https://pd.w.org/2024/08/36566abfcb2952e20.99062056-300x225.jpg 300w, https://pd.w.org/2024/08/36566abfcb2952e20.99062056-1024x768.jpg 1024w, https://pd.w.org/2024/08/36566abfcb2952e20.99062056-768x576.jpg 768w, https://pd.w.org/2024/08/36566abfcb2952e20.99062056-1536x1152.jpg 1536w, https://pd.w.org/2024/08/36566abfcb2952e20.99062056-2048x1536.jpg 2048w" sizes="auto, (max-width: 650px) 100vw, 650px" loading="lazy">',
// Lazy-loaded responsive image which should get auto added.
'<img src="https://pd.w.org/2024/08/36566abfcb2952e20.99062056-300x225.jpg" srcset="https://pd.w.org/2024/08/36566abfcb2952e20.99062056-300x225.jpg 300w, https://pd.w.org/2024/08/36566abfcb2952e20.99062056-1024x768.jpg 1024w, https://pd.w.org/2024/08/36566abfcb2952e20.99062056-768x576.jpg 768w, https://pd.w.org/2024/08/36566abfcb2952e20.99062056-1536x1152.jpg 1536w, https://pd.w.org/2024/08/36566abfcb2952e20.99062056-2048x1536.jpg 2048w" sizes="(max-width: 650px) 100vw, 650px" loading="lazy">',
// Eager-loaded responsive image with fetchpriority=high that should not get auto added.
'<img src="https://pd.w.org/2024/08/36566abfcb2952e20.99062056-300x225.jpg" srcset="https://pd.w.org/2024/08/36566abfcb2952e20.99062056-300x225.jpg 300w, https://pd.w.org/2024/08/36566abfcb2952e20.99062056-1024x768.jpg 1024w, https://pd.w.org/2024/08/36566abfcb2952e20.99062056-768x576.jpg 768w, https://pd.w.org/2024/08/36566abfcb2952e20.99062056-1536x1152.jpg 1536w, https://pd.w.org/2024/08/36566abfcb2952e20.99062056-2048x1536.jpg 2048w" sizes="(max-width: 650px) 100vw, 650px" fetchpriority="high">',
// Non-responsive image which should not get auto added.
'<img src="https://pd.w.org/2024/08/36566abfcb2952e20.99062056-300x225.jpg">',
);
global $argv;
if ( isset( $argv[3] ) && is_numeric( $argv[3] ) && $argv[3] > 0 ) {
$iterations = (int) $argv[3];
} else {
$iterations = 1000;
}
function auto_sizes_update_content_img_tag_with_regex( $html ): string {
if ( ! is_string( $html ) ) {
$html = '';
}
// Bail early if the image is not lazy-loaded.
if ( false === strpos( $html, 'loading="lazy"' ) ) {
return $html;
}
// Bail early if the image is not responsive.
if ( 1 !== preg_match( '/sizes="([^"]+)"/', $html, $match ) ) {
return $html;
}
// Don't add 'auto' to the sizes attribute if it already exists.
if ( auto_sizes_attribute_includes_valid_auto( $match[1] ) ) {
return $html;
}
$html = str_replace( 'sizes="', 'sizes="auto, ', $html );
return $html;
}
function auto_sizes_update_content_img_tag_with_html_tag_processor( $html ): string {
if ( ! is_string( $html ) ) {
$html = '';
}
$processor = new WP_HTML_Tag_Processor( $html );
// Bail if there is no IMG tag.
if ( ! $processor->next_tag( array( 'tag_name' => 'IMG' ) ) ) {
return $html;
}
// Bail early if the image is not lazy-loaded.
if ( 'lazy' !== $processor->get_attribute( 'loading' ) ) {
return $html;
}
$sizes = $processor->get_attribute( 'sizes' );
// Bail early if the image is not responsive.
if ( ! is_string( $sizes ) ) {
return $html;
}
// Don't add 'auto' to the sizes attribute if it already exists.
if ( auto_sizes_attribute_includes_valid_auto( $sizes ) ) {
return $html;
}
$processor->set_attribute( 'sizes', "AUTO, $sizes" ); // Upper-case AUTO just to make it clear when this version is running.
return $processor->get_updated_html();
}
function auto_sizes_attribute_includes_valid_auto( string $sizes_attr ): bool {
$token = strtok( strtolower( $sizes_attr ), ',' );
return false !== $token && 'auto' === trim( $token, " \t\f\r\n" );
}
// Profiling.
$regex_times = array();
$processor_times = array();
for ( $repetition = 0; $repetition <= $iterations; $repetition++ ) {
foreach ( $test_images as $test_image ) {
$time_start = hrtime( true );
auto_sizes_update_content_img_tag_with_regex( $test_image );
$time_end = hrtime( true );
$regex_times[] = $time_end - $time_start;
$time_start = hrtime( true );
auto_sizes_update_content_img_tag_with_html_tag_processor( $test_image );
$time_end = hrtime( true );
$processor_times[] = $time_end - $time_start;
}
}
$regex_times_avg = array_sum( $regex_times ) / $iterations;
$processor_times_avg = array_sum( $processor_times ) / $iterations;
echo "Average time spent for $iterations iterations:\n";
echo " Regex - $regex_times_avg\n";
echo " TagParser - $processor_times_avg\n";
printf( "TagParser is slower than Regex by %.2fx\n", $processor_times_avg/$regex_times_avg );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment