How to minify CSS and JavaScript in WordPress, and when it is worth doing
Minifying strips comments and spacing from CSS and JavaScript files so they download smaller. Switch it on in an optimization plugin, one setting at a time, on a staging copy. WordPress already ships its own files minified, so measure what is left to gain first.
- By
- WP Ministry
- Published
In short
- Minifying removes comments and spacing from a file. Compressing packs it for the trip. Combining joins several files into one. They are three separate settings.
- WordPress loads minified versions of its own files, and a file with .min in its name is already done. The gain is whatever is left.
- Lighthouse lists the files that are not minified and estimates the saving in kibibytes. Read that list before you install anything.
- Combining files was a fix for HTTP/1. On HTTP/2 and later it is not needed in the same way, and it changes the order code runs in, which is what breaks pages.
- Switch on one setting at a time on a staging copy, clear the cache, and check logged out in a private window with the console open.
- To undo, switch the setting off and clear the caches. The plugin's minified copies sit in its own folder, apart from the originals.
Minifying a CSS or JavaScript file removes what a browser does not need in order to run it: comments, spaces and line breaks, and in JavaScript the long names of variables. The file does the same job and is smaller to download. In WordPress you switch it on with a setting in an optimization plugin, or you minify the files of a theme you build yourself before you upload them.
The gain can be small. WordPress already loads minified versions of its own files, and a file that a theme or plugin ships minified has little left to remove. So measure what is left to gain, switch on one setting at a time on a staging copy, and keep the setting only if the figures move.
Minify, compress and combine are three different things
| Setting | What it does | What changes for the visitor |
|---|---|---|
| Minify | Rewrites each file without comments and spacing | The same number of files, each one smaller |
| Compress | The server packs a file with gzip or Brotli as it sends it, and the browser unpacks it | The same files, smaller on the wire |
| Combine | Joins several files into one. Also called concatenating or aggregating | Fewer files to request, with no fewer bytes |
Here is the same rule before and after minifying.
/* Site header */
.site-header {
background-color: #ffffff;
padding: 20px 0;
}Minifying and compressing work together: web.dev describes minifying as an addition to compression, which compression does not make pointless. So a server that already sends gzip or Brotli is not a reason to skip it. Compression is a separate setting from the ones on this page: how to enable gzip and Brotli compression in WordPress covers it. A file that holds up the first paint is a third matter, covered in how to fix render-blocking CSS and JavaScript in WordPress.
Combining is the one to be careful with. It makes nothing smaller, it changes the order in which code arrives, and it is behind most of the breakage described below.
What is already minified
- WordPress's own files. WordPress loads the
.min.jsand.min.cssversions of the scripts and stylesheets inwp-includesandwp-admin. The full versions load when theSCRIPT_DEBUGconstant is switched on. - Files a theme or plugin ships minified. WP Rocket's documentation says it leaves out file names that contain
.min, because they are already minified. Bunny's says the same of*.min.jsand*.min.css.
What is left is the CSS and JavaScript that a theme or plugin ships as written.
Find out what there is to gain
Run PageSpeed Insights, at pagespeed.web.dev, on a page that matters. Its lab test is run by Lighthouse, which has two audits for this, named Minify CSS and Minify JavaScript. Each lists the files it found that are not minified, with the potential saving for each in kibibytes (KiB).
Read the list with two things in mind.
- The figure is an estimate. For CSS, Lighthouse works it out from the comments and whitespace it finds in the file. Chrome's documentation calls it conservative: a real minifier may save more.
- The figure is a size, not a time. A smaller file downloads sooner. How much sooner the page appears is something you measure afterwards.
If neither audit lists a file, there is nothing here to gain, and you can stop. If they list files, write the figures down. Then open your browser's developer tools, choose the network panel, reload the page, and note the totals at the bottom: how much was transferred, and the size of the files once unpacked.
Three ways to minify
A setting in an optimization plugin
Several of the plugins in WordPress caching plugins compared have minify settings, and that page covers how to choose one. Autoptimize, in the WordPress.org plugin directory, does this job without being a page cache: its listing says it can aggregate, minify and cache scripts and styles.
The plugin does not edit your theme's or plugins' files. It writes minified copies into a folder of its own and points the page at those.
| Plugin | Minify | Combine | Leave a file out |
|---|---|---|---|
| WP Rocket | "Minify CSS files" and "Minify JavaScript files" on the File Optimization tab. Its documentation says both are on by default | "Combine JavaScript files". Switched off automatically while its delay setting for JavaScript is on | The "Excluded CSS Files" box, and a matching box for JavaScript, on the same tab |
| LiteSpeed Cache | "CSS Minify" and "JS Minify" under Page Optimization. Off by default | "CSS Combine" and "JS Combine". Off by default | "CSS Excludes" and "JS Excludes" on the Tuning tabs, one file per line, as a full address or part of one |
| Autoptimize | Its CSS and JavaScript optimization settings | Aggregating. Off on new installations | A comma-separated list of words that pick out the files to skip |
Use one tool for this. Autoptimize's listing says not to run another minify plugin beside it, and to switch off the same feature in your caching plugin.
At the CDN
Check the date of any tutorial that tells you to switch on Auto Minify at Cloudflare. Cloudflare has deprecated that feature, and its list of deprecations dates this to August 5, 2024.
Bunny Optimizer has separate switches for CSS and JavaScript minification. Its documentation says to switch them off if your files are already minified, because processing them again adds delay with no meaningful saving. So minify in one place: the plugin or the CDN, not both. How to set up a CDN for WordPress covers the CDN itself.
A build step, for a theme you develop yourself
If you write the theme, minify its files before they reach the server. Chrome's documentation suggests a build process for this where possible. WordPress's own build tool, @wordpress/scripts, has a build command that its documentation describes as producing code ready for production and optimized for performance.
Keep both versions of each file and load the minified one unless SCRIPT_DEBUG is on, as WordPress does with its own files.
add_action( 'wp_enqueue_scripts', function () {
$suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
wp_enqueue_style(
'example-theme',
get_theme_file_uri( 'assets/css/main' . $suffix . '.css' ),
array(),
'1.2.0'
);
} );Think twice before combining files
Combining was a fix for a limit of HTTP/1. A browser on HTTP/1 opens only a few connections to a site at once (MDN gives six as the common figure), so a page with many small files had them waiting for a free connection.
HTTP/2 removed that limit. MDN describes it as a multiplexed protocol: requests are made in parallel over the same connection. Two plugin makers say what follows:
- WP Rocket's documentation calls combining a best practice on HTTP/1 "but not necessarily when using HTTP/2".
- Autoptimize's listing says that because of HTTP/2, new installations no longer aggregate CSS and JavaScript files. It adds that joining files can still make sense on some sites, and that the answer is to test.
Combining also has costs of its own. Ilya Grigorik's High Performance Browser Networking lists three. A bundle may carry code the page does not use. One changed byte makes every visitor download the whole bundle again. And a browser may not be able to use any of it until all of it has arrived.
To see which protocol your site uses, open the network panel, right-click the header of the list of requests and show the Protocol column. h2 is HTTP/2 and h3 is HTTP/3. On either, leave combining off unless a measurement on your own pages shows that it helps.
What breaks, and why
WP Rocket's documentation calls minifying a practice with low chances of breaking a site. Changing the order of code is another matter.
- A missing semicolon. JavaScript lets an author leave out the semicolon at the end of a line. MDN warns that a following line that starts with
(may then be read as part of the line before it, as a function call. Joined end to start, two files that each worked alone can make one file with an error in it. - Load order. A browser runs ordinary scripts in the order they appear on the page. WP Rocket's documentation says its combined file is placed just before the closing
bodytag, so a script that used to run in the head of the page now runs at the end. - Inline scripts that expect a file. A plugin may print a few lines of script into the page that use a library loaded earlier. Autoptimize leaves WordPress's
jquery.min.jsalone for this reason: its listing says many plugins add inline JavaScript that relies on jQuery being there. When this goes wrong, the console shows an error such asjQuery is not defined. - CSS order. When two rules of equal weight set the same property, the one that comes last is applied. If a combined stylesheet lands before or after a file that was left out of it, a different rule can come last, and spacing, colors or a menu look wrong.
In its notes on WP Rocket, WooCommerce's documentation recommends avoiding JavaScript minification. On a store, check the cart and the checkout after every change.
Switch it on safely
Step 1: Write down what you will check
List the pages that matter: the home page, a post, a page with a form, and on a store the cart and the checkout. For each, note what has to work: the menu on a phone, a slider, sending the form.
Step 2: Switch on CSS minify alone
Leave every other optimization setting as it is. Save.
Step 3: Clear the caches
Clear the plugin's cache so that it builds fresh files. If a page cache or a CDN sits in front of the site, clear that too.
Step 4: Check logged out, with the console open
Open a private window, so that you see the site as a visitor does. Open the browser's developer tools, choose the console, and load each page on your list. Look at the layout, try each thing you noted, and watch for red errors in the console.
Step 5: Switch on JavaScript minify alone, and check again
Clear the caches and repeat the same checks. If something breaks now, you know which setting did it. If you decide to try combining, give it a round of its own in the same way.
Step 6: Measure again
Run the same test on the same pages and compare with the figures you wrote down.
Leave out a file that breaks
When one setting breaks the page, find the file and exclude it.
- Start with the console. An error there names the file it came from.
- Look at the page without the plugin's work. WP Rocket bypasses itself when you add
?nowprocketto a page's address, and LiteSpeed Cache shows the page before optimization with/?LSCWP_CTRL=before_optm. The page then loads the original files, so you can read their real addresses in the network panel. - If the console does not name it, narrow it down. WP Rocket's and LiteSpeed's documentation describe the same method. Put every CSS or JavaScript file in the exclusion box, then take them out one at a time, clearing the cache and checking after each. The file whose removal breaks the page goes back in the box and stays there. How to find and fix a WordPress plugin conflict uses the same kind of search on plugins.
- For
jQuery is not defined, the author of Autoptimize says to excludewp-includes/js/jquery/jquery.min.js.
If you end up excluding most of the files, switch the setting off. It is saving little by then.
How to undo it
Switch the setting off, then clear the caches. Nothing has to be restored, because the originals were never changed. The minified copies are in the plugin's own folder: wp-content/cache/min/ for WP Rocket and wp-content/cache/autoptimize/ for Autoptimize.
- WP Rocket deletes its minified files when you switch off the minify settings or clear its cache.
- LiteSpeed Cache has a button under Toolbox, on the Purge tab, labeled "Purge All - CSS/JS", which removes the minified and combined files.
- Autoptimize warns that after its cache is cleared, no page cache should still hold pages that point at the removed files. Clear your page cache as well.
If the CDN was doing the minifying, switch it off there and purge the CDN's cache.
How to tell whether it was worth doing
- The audits. Run the lab test again. The files you minified should be gone from both lists.
- The bytes. In the network panel, the amount transferred for the same page should be lower than the figure you wrote down.
- The page. Compare Largest Contentful Paint for the same pages, before and after. How to improve WordPress Core Web Vitals explains the figure, and why a lab result and real visitors' data can differ.
If the bytes fell and nothing else moved, the setting is doing no harm and little good. Keep it if it needed no exclusions, and switch it off if it needed several. The other causes of a slow site are in how to speed up WordPress, in the order that pays off. If you would rather hand the job over, our speed optimization service is a one-time job: you name the pages, and we measure them before the work and again after it.
Common questions
How do I see the full version of one of WordPress's own files?
Add define( 'SCRIPT_DEBUG', true ); to wp-config.php, above the line that says to stop editing. WordPress then loads the full versions of its scripts and stylesheets in place of the .min ones. Do this on a staging copy, and remove the line when you are done.
Does WordPress combine files itself?
In the dashboard, yes. WordPress's documentation says the JavaScript files of administration screens are joined into one address to make those screens faster. If JavaScript fails on an administration screen, it suggests adding define( 'CONCATENATE_SCRIPTS', false ); to wp-config.php to switch that off.
I switched minify off and the page is still broken. Why?
A cache is probably still serving a stored page that points at the minified files, which may no longer exist. Clear the page cache and the CDN's cache, then reload in a private window.

