Improve front end performance with just one line of PHP

Jonny Harris avatar
  • While working on WordPress core, I discovered a pretty amazing function: wp_maybe_inline_styles. This function hooks into the style enqueueing process in WordPress. Instead of outputting a <link> tag with an href attribute to a url of a CSS file, which when rendered in the browser requires a blocking HTTP request to get the CSS file and slows down front-end performance, this function inlines the styles. It reads the file into memory and outputs it as an inline <style> tag in the header/footer of your site. This means no external requests, allowing the browser to render your page much faster.

    This functionality was added to support block styles. Many block stylesheets can be extremely small. Some core block stylesheets consist of only a few lines even after minification. If you are already using register_block_type_from_metadata to render your blocks, then you are already opted into this functionality. However, this functionality can be used for any stylesheet you use in WordPress, but you have to opt-in. To opt-in, it is as simple as this:

    wp_style_add_data( $style_handle, 'path', $path );
    

    The $style_handle need to be handle used for the style and $path is the full path to the CSS file.

    It only gets a little bit more complex if you have right-to-left stylesheets as well. But adding support for this is as simple as adding the following lines:

    
    $rtl_file = str_replace( "{$suffix}.css", "-rtl{$suffix}.css", $path );
    
    if ( is_rtl() && file_exists( $rtl_file ) ) {
    	wp_style_add_data( $style_handle, 'path', $rtl_file );
    }

    This is so simple that I added it to my own sites with a commit like this. I have also added it to Jetpack blocks with my pull request here.

    One thing to note is that there is a limit to the size of the CSS that can be output. The code has a limit of 20,000 bytes of CSS. This is to prevent extremely large CSS files, like a 10KB file, from being output inline. This functionality is really designed for smaller CSS files. However, if you know what you are doing, there is a filter to adjust the size limit using a filter called styles_inline_size_limit.

    Why using this functionality? It is possible to do this yourself using file_get_contents and inline styles. Like the following code snippet.

    wp_register_style( $style_handle, false );
    wp_add_inline_style( $style_handle, file_get_contents( $path ) );

    But loading the contents of a CSS file into PHP on every page request is really bad for PHP performance and server response time. What wp_maybe_inline_styles does is only load the CSS into memory if the stylesheet is used on the page. This means page loads like REST API or admin screens will not load the CSS into memory.

    Just for a bit of fun, I turned this functionality off for block styles. Here is the before and after on Lighthouse.

    With inline styles.

    Without inline styles.