Script Loader: Optimize performance of _wp_normalize_relative_css_links() by more than 2x.

* Replace `preg_match_all()` and its secondary `str_replace()` call with `preg_replace_callback()`.
* Fix case where paths beginning with `http` and `https` (but not `http:` and `https:`) were erroneously not counted as relative.
* Improve code style and readability by consolidating conditions and returning once.
* Use `str_starts_with()` consistently instead of `strpos()`.

Follow-up to [52036], [52695], and [52754].

Fixes #58069.
See #54243.


git-svn-id: https://develop.svn.wordpress.org/trunk@55658 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Weston Ruter 2023-04-19 01:24:40 +00:00
parent 19bd759db5
commit 8465dec59a
2 changed files with 34 additions and 33 deletions

View File

@ -2939,41 +2939,34 @@ function wp_maybe_inline_styles() {
* @return string The CSS with URLs made relative to the WordPress installation.
*/
function _wp_normalize_relative_css_links( $css, $stylesheet_url ) {
$has_src_results = preg_match_all( '#url\s*\(\s*[\'"]?\s*([^\'"\)]+)#', $css, $src_results );
if ( $has_src_results ) {
// Loop through the URLs to find relative ones.
foreach ( $src_results[1] as $src_index => $src_result ) {
// Skip if this is an absolute URL.
if ( 0 === strpos( $src_result, 'http' ) || 0 === strpos( $src_result, '//' ) ) {
continue;
return preg_replace_callback(
'#(url\s*\(\s*[\'"]?\s*)([^\'"\)]+)#',
static function ( $matches ) use ( $stylesheet_url ) {
list( , $prefix, $url ) = $matches;
if ( ! (
str_starts_with( $url, 'http:' )
||
str_starts_with( $url, 'https:' )
||
str_starts_with( $url, '//' )
||
str_starts_with( $url, '#' )
||
str_starts_with( $url, 'data:' )
) ) {
// Build the absolute URL.
$absolute_url = dirname( $stylesheet_url ) . '/' . $url;
$absolute_url = str_replace( '/./', '/', $absolute_url );
// Convert to URL related to the site root.
$url = wp_make_link_relative( $absolute_url );
}
// Skip if the URL is an HTML ID.
if ( str_starts_with( $src_result, '#' ) ) {
continue;
}
// Skip if the URL is a data URI.
if ( str_starts_with( $src_result, 'data:' ) ) {
continue;
}
// Build the absolute URL.
$absolute_url = dirname( $stylesheet_url ) . '/' . $src_result;
$absolute_url = str_replace( '/./', '/', $absolute_url );
// Convert to URL related to the site root.
$relative_url = wp_make_link_relative( $absolute_url );
// Replace the URL in the CSS.
$css = str_replace(
$src_results[0][ $src_index ],
str_replace( $src_result, $relative_url, $src_results[0][ $src_index ] ),
$css
);
}
}
return $css;
return $prefix . $url;
},
$css
);
}
/**

View File

@ -240,6 +240,14 @@ class Tests_Dependencies_Styles extends WP_UnitTestCase {
'css' => 'img {mask-image: url(\'data:image/svg+xml;utf8,<svg></svg>\');}',
'expected' => 'img {mask-image: url(\'data:image/svg+xml;utf8,<svg></svg>\');}',
),
'URLs with path beginning with http' => array(
'css' => 'p {background:url( "http-is-awesome.png" );}',
'expected' => 'p {background:url( "/wp-content/themes/test/http-is-awesome.png" );}',
),
'URLs with path beginning with https' => array(
'css' => 'p {background:url( "https-is-more-awesome.png" );}',
'expected' => 'p {background:url( "/wp-content/themes/test/https-is-more-awesome.png" );}',
),
);
}