Skip to content

File concatenation and minification

By default, if enqueued, an application’s JavaScript and CSS files are concatenated in order to reduce the number of requests that occur on a single page load. CSS files are minified as well as concatenated, which reduces file size by removing unnecessary white space.

The responses that are generated by VIP sites are served from a global network of edge cache server locations. This allows a majority of a site’s traffic, including concatenated scripts and styles, to be served directly from an edge location closest to a site’s visitors without ever hitting a line of PHP. This results in the low-latency and high-performance impact expected from a CDN.

Limitations

Files that are enqueued from a resource outside of an application’s wpcomvip GitHub repository will not be minified or concatenated. This includes:

Some third-party performance scans may not recognize VIP’s CDN as a result of concatenated files being served from the same domain as the VIP site.

Versioning to bust the cache

By default, the VIP Platform concatenates JavaScript and CSS files that are enqueued in an application’s codebase. The concatenated files are cached with a Cache-Control HTTP header set to cache-control: max-age=31536000 (1 year).

To bust the cache on deployment, the $ver value in the enqueue must be incrementally updated when changes are made to enqueued JavaScript and CSS files. An updated $ver value effectively generates a new and unique static URL for the concatenated assets. The $ver value can be updated in functions such as wp_enqueue_script(), wp_enqueue_style(), wp_register_script(), and wp_register_style().

// When changes are made to js/plugin.js the $ver variable should be incrementally updated.
$ver = '1.1';
wp_enqueue_script( 'plugin_script', plugins_url( 'js/plugin.js', __FILE__ ), array(), $ver );

Because file Input/Output (I/O) operations can be expensive, VIP does not recommend using the function filemtime() to populate a value for $ver on production environments.

Script tag attributes filter

Accepted values: defer | async | nomodule | crossorigin | integrity | type | nonce | referrerpolicy

Script attributes such as async or defer can be added to concatenated scripts with the js_concat_script_attributes filter.

In this example, the attributes async and defer are added to all concatenated scripts:

add_filter( 'js_concat_script_attributes', function( $args, $href, $js_array, $jsconcat ) {

    return stristr( $href, '_static' ) !== false ? [ 'async', 'defer' ] : [];

}, 10, 4 );

Enable or disable concatenation

Available filters can be used to exclude specific JavaScript or CSS files from concatenation bundles. When enabling or disabling concatenation for JavaScript or CSS, consider including is_admin() logic to specify if the filter will be applied to the front end of a site, the WordPress Admin dashboard, or both.

For example, file concatenation in the WP Admin is enabled by default for CSS and disabled for JavaScript. This code example demonstrates how to modify these default settings and disable CSS file concatenation only in WP Admin (leaving it enabled on the front end):

// Disable CSS concatenation for WP Admin.

if ( is_admin() ) {
	add_filter( 'css_do_concat', '__return_false' );
}

js_do_concat filter

Example code to exclude specific JavaScript files from concatenation with the js_do_concat filter:

add_filter( 'js_do_concat', 'my_vip_js_concat_filter', 10, 2 );

// Do not include my-script-handle in concatenated bundles.
function my_vip_js_concat_filter( $do_concat, $handle ) {
    if ( 'my-script-handle' === $handle ) {
		return false;
	}
	return $do_concat;
 }

To disable concatenation for all JavaScript files, set the js_do_concat filter to return __return_false:

// Disable JS concatenation.
add_filter( 'js_do_concat', '__return_false' );

css_do_concat filter

Example code to exclude specific CSS files from concatenation with the css_do_concat filter:

add_filter( 'css_do_concat', 'my_vip_css_concat_filter', 10, 2 );

// Do not include my-custom-css-handle in concatenated CSS bundles.
function my_vip_css_concat_filter( $do_concat, $handle ) {
    if ( 'my-custom-css-handle' === $handle ) {
		return false;
	}
	return $do_concat;
}

To disable concatenation for all CSS files, set the css_do_concat filter to return __return_false:

// Disable CSS concatenation.
add_filter( 'css_do_concat', '__return_false' );

Troubleshooting

In-browser debugging methods

Query parameters can be added to a URL in the browser to disable concatenation and help determine if a JavaScript error or CSS issue is related to concatenation.

Adding these parameters to an affected URL in the browser will load the individual JavaScript or CSS files for the request instead of the static concatenated bundle. These query parameters are only meant to be used for testing in a browser and should not be added to code.

  • JavaScript: concat_js=false
  • CSS: concat_css=false

Updated concatenated assets not loading as expected

It is possible for built assets and concatenation to cause short-term brokenness in CSS and/or JavaScript when combined with full page caching.

Because previously concatenated bundles are cached at the edge, newly deployed changes will usually reference a new bundle, while existing cached pages will reference an old one. If either needs to be reconstructed due to a cache miss, the enqueued files must still be available on the server – the URL contains the filenames (usually compressed).

Because of this, avoid deleting older versions of those built files for at least 30 minutes so they can be used as needed. If 404s occur for previously-good bundles, this is a likely cause – one of the component files is missing. When overwriting these files, an old URL may suddenly contain the new assets even though the page was generated before the deploy.

Last updated: September 09, 2024

Relevant to

  • WordPress