Batch minfy & gzip new files only with some date tricks

With everybody using grunt.js for linting, css compilation and minification nowadays, I wanted to make a simple experiment and see if I could do the same using a plain batch file – in Windows no less. Turns out some things are very easy and some quite tricky.  While this article is about batch processing of html files, you can apply the same principle for any sort of batch processing in Windows.

I have a website that doesn’t change very often but that needs to be fast. Really fast. I’m using ngnix to serve pre-compressed gzip files for minimum overhead. All files are plain html, js and css.

What I wanted to achieve was that in the case of a change in site, to be able to run a simple batch that would:

  1. minify the changed files
  2. gzip the changed files
  3. upload the changed files to the live server.

The tools I’m using are:

The algorithm of our batch file should be as follows:

  1. collect all the files we want to process
  2. check if there is a compressed version of the file (e.g. for file foo.html, check if there is a file foo.html.gz)
  3. if the gzip file exists and it’s older than the plain file
    1. delete it
    2. minify the plain file
    3. compress the minified file
  4. otherwise, skip deleting the compressed file and just run the minification + compression

Here’s the batch script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
FOR /R ".\myfolder\" %%i IN (*.html) DO (
  IF EXIST %%i.gz (
    FOR %%b IN (%%i.gz) DO (
      IF "%%~ti" GTR "%%~tb" (
        ECHO %%i.gz is older, replacing
        DEL %%i.gz
        java -jar bin\htmlcompressor.jar --simple-doctype --remove-style-attr --remove-link-attr --remove-script-attr --remove-surrounding-spaces max --compress-js --compress-css --js-compressor yui --preserve-php --type html %%i | bin\7z a %%i.gz -si -tgzip -mx9
      )
    )
  ) ELSE (
    ECHO creating %%i.gz
    java -jar bin\htmlcompressor.jar --simple-doctype --remove-style-attr --remove-link-attr --remove-script-attr --remove-surrounding-spaces max --compress-js --compress-css --js-compressor yui --preserve-php --type html %%i | bin\7z a %%i.gz -si -tgzip -mx9
  )
)

Step by step, FOR /R ".\myfolder\" %%i IN (*.html) DO loops recursively through all *.html files in myfolder and assigns the file name to variable %%i. IF EXIST %%i.gz is self-explanatory. The next FOR %%b IN (%%i.gz) essentially creates a new file variable %%b with “.gz” appended to the original variable.

Next we test to see which fie is newer – the plain one or the .gz one (IF "%%~ti" GTR "%%~tb"). Here we hit a problem. %~t means date-time (see batch parameters) so we are comparing the datetime of the plain file with the datetime of the compressed file. The problem is the comparison is done as a string, not as a datetime object. I’ve seen many attempts to fix this problem, but the solutions are usually locale-dependent, assuming mm/dd/yy format.

The only way to fix this is via a registry hack: first we save the original date format, then we set the format to “yyyymmdd HHmmss”, we run the previous code and finally we switch back to the original format.

Here’s the full code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@ECHO OFF
 
REG COPY "HKCU\Control Panel\International" "HKCU\Control Panel\International-Temp" /f >nul
REG ADD "HKCU\Control Panel\International" /v sShortDate /d "yyyyMMdd" /f >nul
REG ADD "HKCU\Control Panel\International" /v sTimeFormat /d "HHmmss" /f >nul
 
FOR /R ".\sparkchess\" %%i IN (*.html) DO (
  IF EXIST %%i.gz (
    FOR %%b IN (%%i.gz) DO (
      IF "%%~ti" GTR "%%~tb" (
        ECHO %%i.gz is older, replacing
        DEL %%i.gz
        java -jar bin\htmlcompressor.jar --simple-doctype --remove-style-attr --remove-link-attr --remove-script-attr --remove-surrounding-spaces max --compress-js --compress-css --js-compressor yui --preserve-php --type html %%i | bin\7z a %%i.gz -si -tgzip -mx9
      )
    )
  ) ELSE (
    ECHO creating %%i.gz
    java -jar bin\htmlcompressor.jar --simple-doctype --remove-style-attr --remove-link-attr --remove-script-attr --remove-surrounding-spaces max --compress-js --compress-css --js-compressor yui --preserve-php --type html %%i | bin\7z a %%i.gz -si -tgzip -mx9 >nul
  )
)
 
REG COPY "HKCU\Control Panel\International-Temp" "HKCU\Control Panel\International" /f >nul

Works like a charm.

The same principle can be applied to all file types.

So, is it worth the effort? Let’s look at WebPageTest.org:

Page speed result

0.8 seconds and straight ‘A’s to load 1MB, including webfonts and some large images – not bad at all.

1 reply
  1. Jaki
    Jaki says:

    Thanks Armand. I am very much looking for the solution to gzip. Thanks for helping me out. Great Great!! Keep it bro.

Comments are closed.