javascript minifiers
JSqueeze Rodrigo54 PHPClasses package/9865 JShrink PHPWee MatthiasMullie Google Closure Compiler
html minifierscss minifiers
javascript css html minifier evaluation
First written: Aug-2023
last changed Mar-2024

JavaScript Code Minifiers Comparison Test

Also see: Methodfish's MFMinify

As part of a recent project, we needed to investigate Javascript and CSS code minifiers so that the download speeds and sizes were as optimal as possible, but also for security purposes, and to remove undesirable blocks of code and to obfuscated as much as possible. It was also a requirement that the minifiers only run if the code was new (testing the dates of the previously minified versions against that of the latest source), and most importantly can be run from within a standard PHP developer/code environment (i.e. not a webpage outputting minified code on post).

Most simple minifiers are capable to removing comments and white space, but fewer would rename variables in JavaScript blocks. This led onto a more in-depth scan across the opensource market for possible candidates.

One thing to add here is that for JavaScript libraries - do you want the function names obfuscated or not, and if you do then you need to consider the wider problem of HTML that contains calls to JavaScript functions (i.e. through onClick='...' type controls, as well as any ajax responses). This complexity is likely to be beyond any of these minify packages as the HTML would need to be parsed and adjusted to reference the obfuscated function names; but these classes would be part of the kernel of the minification process.

CSS and HTML were arguably a little easier and needed little effort, but there are some things that need to be considered.

The results are quantitative, but also subjective and you should therefore consider which tool works best for your own specific needs.

ClassLine-
comments
Block-
comments
Important-
comments
var
shrinking
const
shrinking
let
shrinking
Code
shrinking
Small-Test-
speed**
Small-Test
Result size
Mid-sized Test
Result size
X-Large Test
Result size
JSqueezecheckcheck check check1 close close check0.00863 54.4% 39.8% 34.2%
Rodrigo54 check check check check close close close0.00058 69.0% 50.2% 43.4%
PHPClasses/9865 check check close check close close close0.00680 58.7% 51.0% 42.5%
JShrinkcheckcheck check check close close close0.00533 63.4% 50.8% 42.4%
PHPWeecheckcheck check check close close close0.02207 62.7% 50.8% 42.4%
MatthiasMulliecheck checkcheck checkclosecloseclose0.0038161.7%50.2%41.9%
Google Closure Compiler2 3check checkcheckcheckcheckcheckcheck1.7050047.0%36.2%33.9%
** This will change and was simply a snapshot of the basic [small code] test run at one time.
1 Only works on variables inside functions.
2 Requires Java package installation, or use hosted https API service
3 Tests using SIMPLE_OPTIMIZATION mode

Scroll down, or click on the links in the table above to jump to the live-demo of each class involved.

One other known minifier also exists, namely Uglify-JS but as this required npm for installation it was ruled out of the evaluation. However, doing some basic tests online using Skalma.github.io (which if I am right is using UglifyJS 3), then a basic test results in mostly ok code, although I did notice single quotes are being changed to double in the My favorite animal is the ${myPet} basic test. Additional testing is recommended.

JSqueeze

(v2.0.5 (2016))https://github.com/tchwork/jsqueeze

The first thing to say here is that the repository is now archived since Nov 2022, but I believe this is probably still the best solution out there - if you can live with the downsides. It is also important to point out that there is no published reason why this class was archived, so we don't know what the full scale of the downsides are.

The class will do all the main points (comment removal, whitespace removal), as well as merging variable declarations, and the best part - minifying internal function variable names.

Deployment is very simple - use composor (or simply place the JSqueeze.php file into your path), and include the use PatchworkJSqueeze; and require_once 'JSqueeze.php'; commands.

Licence is "This library is free software; you can redistribute it and/or modify it under the terms of the (at your option): Apache License v2.0 (see provided LICENCE.ASL20 file), or GNU General Public License v2.0 (see provided LICENCE.GPLv2 file)."

Code implementation is very simple:

jsqueeze-js.php :: JSqueeze
use Patchwork\JSqueeze;
jsqueeze-js.php
require_once 'JSqueeze.php';
$jz = new JSqueeze();

$minifiedCode = $jz->squeeze(
    $js,
    true,   // $singleLine
    true,  // $keepImportantComments
    true    // $specialVarRx
);
The code includes the following notes:add

Pros

  • Very easy deployment.
  • Good level of minification, with value-added adjustments to shrink the js more for phrases such as 'true' and 'false' and Array and Object, etc.
  • Can be set to keep important comments.
  • Minifies function variables well.
  • Obvious options through method parameters.
  • Handles .replace(/'/g....

Cons

  • repository is now archived since Nov 2022
  • Not supported - no way to raise issues ... you have to run your own private version and you need to be comfortable with regex patterns.
  • CPU hit due to additional effort needed on variable naming changers.
  • let or const declarations are not handled.
  • Globals variables are not touched (although Features point 3 says that they should be).
  • Not clear what $specialVarRx does.
  • Changes double quotes to single quotes - which can result in problems if the JS is within onClick='...' calls.
  • Drupal has reportedly had an issue requesting it stopped using it (in favour of MatthiasMullie) (October 2021) as it does not support template literals (e.g. ${myPet}) (click here to see the issue) - although looking at the live example demo with the latest code I do not see this failure, perhaps due to a later fix.

Rodrigo54

https://gist.github.com/Rodrigo54/

Code implementation is very simple:

rodrigo54-js.php :: Rodrigo54
require_once 'rodrigo54-minifier.php'; // or whatever filename you chose
$jz = new Rodrigo54();

$minifiedCode = $jz->minify_js($js);
// or $minifiedCode = $jz->minify_css($css);
// or $minifiedCode = $jz->minify_html($html);
Pros

  • Very easy deployment (note I decided to clipboard the raw-code into a Rodrigo54 class so that I could use it as an external class in my packages).
  • Very simple and easy to understand code involving a set of regex's.
  • Handles HTML and CSS as well as JavaScript.
  • It will remove some comments from JavaScript.
  • Removes some redundant spaces (but leaves others in still).
  • Handles important comments (no option to turn this off).

Cons

  • Variable names are not minified.
  • No version number in the code or download, so you don't know if you're using older code.
  • Fails on some // comment situations.
  • Fails on .replace(/'/

PHPClasses package/9865

https://www.phpclasses.org

Code implementation is very simple:

phpclasses-js.php :: PHPClasses
require_once 'phpclasses9865/JavascriptMinifier.phpclass'; //
$minifier        =  new  JavascriptMinifier () ;
$minifiedCode    =  $minifier->Minify( $js ) ;
// or $minifiedCode    =  $minifier->MinifyFrom( $filename ) ;
I'm not a fan of this one mainly due to the complexity of the code verses what it delivers, and the confusion of documentation that PHPClasses.org provides.

The output comes in multiple lines.

Pros

  • It will remove comments from JavaScript.
  • Removes some redundant spaces (but leaves others in still).
  • Handles .replace(/'/

Cons

  • Download requires a PHPClasses.org login before you can evaluate the solution.
  • PHPClasses documentation and download area is a disaster and difficult to navigate.
  • Strange use of .phpclass files (something I'm not familiar with).
  • Documentation.
  • Output is multiple lines.
  • Removes important comments (no obvious way to disable this).
  • No version number in the code or download, so you don't know if you're using older code.
  • Not clear if any fixes have been applied to this code since first posting.

JShrink

(v1.4.0)

https://github.com/tedious/JShrink

Code implementation is very simple:

jshrink-js.php :: JShrink
include('JShrink/Minifier.php');

if ( true ) {
    // Basic (default) usage.
    $minifiedCode = \JShrink\Minifier::minify($js);
}
else {
    // Disable YUI style comment preservation.
    $minifiedCode = \JShrink\Minifier::minify($js, array('flaggedComments' => false));
}
Installation is officially through Composer, but simply downloading the Minifier.php file will suffice.

Pros

  • Easy deployment
  • Removes Comments
  • Handles .replace(/'/

Cons

  • Multi-line output

PHPWee

https://searchturbine.com/php/phpwee

Runs against HTML, CSS and JS.

Code implementation is very simple:

phpwee-js.php :: JShrink
require_once ("PHPWee/phpwee.php");

$minifiedCode = PHPWee\Minify::js($js);
Pros

  • Removes comments.

Cons

  • Deployment is not so easy (no documentation).
  • No version management - we don't know what version we're looking at.
  • Deprecation warnings detected in error.log suggesting the code is not being maintained.
  • Downloaded files contain a bug (phpwee.php line #1 is missing <?php - see StackExchange issue raised 2017 and still not fixed Jan-2023).
  • No documentation.
  • Multi-line output.

MatthiasMullie

https://github.com/matthiasmullie/minify

This extension reduces the page size by removing unused white-spaces and comments in the HTML output.

Code implementation is very simple:

matthiasmullie-js.php :: JShrink
use MatthiasMullie\Minify;
matthiasmullie-js.php :: JShrink
require_once 'MatthiasMullie/src/Minify.php';
require_once 'MatthiasMullie/src/CSS.php';
require_once 'MatthiasMullie/src/JS.php';
require_once 'MatthiasMullie/src/Exception.php';
require_once 'MatthiasMullie/src/Exceptions/BasicException.php';
require_once 'MatthiasMullie/src/Exceptions/FileImportException.php';
require_once 'MatthiasMullie/src/Exceptions/IOException.php';
require_once 'path-converter/src/ConverterInterface.php';
require_once 'path-converter/src/Converter.php';

$minifier = new Minify\JS();
$minifier->add($js);

// or ....

//$sourcePath1 = '/path/to/second/source/css/file1.js';
//$minifier->add($sourcePath1);
//$sourcePath2 = '/path/to/second/source/css/file2.js';
//$minifier->add($sourcePath2);


// save minified file to disk
//$minifiedPath = '/path/to/minified/js/file.min.js';
//$minifier->minify($minifiedPath);

// or just output the content
$minifiedCode = $minifier->minify();
Pros

  • Removes comments

Cons

  • Deployment isn't as easy as the other classes.
  • Multi-line output.

Google Closure Compiler

https://developers.google.com/closure/compiler/docs/gettingstarted_api

Not a package that actually fits this discussions criteria, as it's a hosted or self-install java package, but worth a mention. The service receives javascript and compiles the code to produce the minified result, with three options - WHITESPACE ONLY, SIMPLE_OPTIMIZATIONS and ADVANCED_OPTIMIZATIONS. The package is open source and source code is available on github.

See Google for a detail on the optimizations.

Although the hosted solution is slowed through the http overhead, it is available as a self-install java package if you have access to your servers, which may be able to work around this, that said, you should be looking to optimize code within a dev environment in order to test before deployment - so runtime should not be a key factor.

Pros

  • Very thorough compression (probably the best I've seen)
  • Smallest results in the review
  • Checks for invalid code before minifying

Cons

  • You would need to create a container package to run the code
  • Slow - although may be acceptable for .js libraries, it may be difficult for just in time code blocks returned by pages
  • No obfuscation

Click here to see the html/javascript used to generate this demo.

For the official Google version use https://closure-compiler.appspot.com/home


link Click to view a demo

square