Removing whitespace from HTML output and inlining above-the-fold CSS are two of the highest-ROI performance techniques for WordPress — they reduce Time to First Byte payload and eliminate render-blocking stylesheets in a single request.
Problem: WordPress loads full stylesheets on every page even when only a small portion of CSS is needed for the initial viewport — delaying the First Contentful Paint and causing layout shifts.
Solution: Extract critical CSS for above-the-fold content with the critical npm package, inline it in <style> tags via wp_add_inline_style(), and load the full stylesheet asynchronously with rel="preload" + onload. Automate regeneration in your build pipeline after any CSS change.
The examples below implement an output-buffer HTML minifier as a WordPress plugin, and show how to extract and inline critical CSS while deferring the full stylesheet.
// Minimal HTML minifier via output buffering
// Place in mu-plugins/html-minify.php
add_action( 'template_redirect', function() {
if ( is_admin() || wp_doing_ajax() || is_feed() ) return;
ob_start( 'myplugin_minify_html' );
} );
function myplugin_minify_html( string $html ): string {
// Skip if the page contains a <pre> or <textarea> (preserve formatting)
if ( preg_match( '/<(pre|textarea)[^>]*>/i', $html ) ) return $html;
$search = [
'/\>[^\S ]+/s', // strip whitespace after tags
'/[^\S ]+\</s', // strip whitespace before tags
'/(\s)+/s', // collapse multiple spaces to one
'/<!--(?!\[if).*?-->/s', // remove HTML comments (keep IE conditionals)
];
$replace = [ '>', '<', '\1', '' ];
return preg_replace( $search, $replace, $html );
}
Defer non-critical stylesheets and inline critical CSS:
// 1. Inline critical CSS in <head>
add_action( 'wp_head', function() {
$critical_css_file = get_template_directory() . '/assets/critical.css';
if ( file_exists( $critical_css_file ) ) {
echo '<style id="critical-css">' . file_get_contents( $critical_css_file ) . '</style>';
}
}, 1 );
// 2. Convert render-blocking stylesheets to deferred loading
add_filter( 'style_loader_tag', function( $tag, $handle, $href, $media ) {
$defer_handles = [ 'my-theme-style', 'woocommerce-general' ];
if ( ! in_array( $handle, $defer_handles, true ) ) return $tag;
// Load asynchronously, swap media to 'all' on load
return sprintf(
'<link rel="preload" as="style" href="%s" onload="this.onload=null;this.rel='stylesheet'">' .
'<noscript><link rel="stylesheet" href="%s"></noscript>',
esc_url( $href ),
esc_url( $href )
);
}, 10, 4 );
// 3. Add dns-prefetch / preconnect for external resources
add_action( 'wp_head', function() {
echo '<link rel="preconnect" href="https://fonts.googleapis.com" crossorigin>';
echo '<link rel="dns-prefetch" href="//fonts.gstatic.com">';
}, 0 );
NOTE: Generate the critical.css file with Critical (Node.js) or the online Critical CSS Generator, then automate regeneration in your CI pipeline whenever theme CSS changes.