This forum has moved, please join us on github discussions. We will keep these old posts available for reference. Thank you!

HTML minification for production

Hello,

Is there any standard option to minify HTML in Apostrophe CMS?

The recommended minification option:

apostrophe-assets: {
  minify: true
}

works for JavaScript and CSS only.

The HTML code sent by the server to the browser is not optimized at all.

How do you usually solve this problem in your production environment?

I came up with the following solution. It may not be perfect in terms of performance (or maybe it is), but it is the best working method I found up to this moment.

First I tried to add express middleware (express-minify-html) but with no success (I tried several ways including various middleware options, but the minification just didn’t happen).

Then I decided to use html-minifier package directly, so I created lib/modules/apostrophe-templates/index.js, added 'apostrophe-templates': { minify: true } to data/local.js and then overrode renderBody method like this:

const minify = require('html-minifier').minify;
const minifyOptions = {
  collapseWhitespace: true,
  conservativeCollapse: true,
  preserveLineBreaks: true
};

module.exports = {
  construct: function (self, options) {
    if (options.minify) {
      const superRenderBody = self.renderBody;
      self.renderBody = function (req, type, s, data, module) {
        const body = superRenderBody(req, type, s, data, module);
        return self.renderDepth === 0 ? minify(body, minifyOptions) : body;
      };
    }
  }
};

This method works!

This is my intuition speaking and not something I have researched heavily, but I would honestly assume that you will get better response time for the average visitor by simply enabling gzip in nginx (or whichever software you’re using as the public facing web server) than trying to make use of an HTML minifier.

Other than enabling gzip, my primary concern would be TTFB, and in my experience Apostrophe is very good in that arena.

I updated my solution above – now it minifies HTML code only once per request (when self.renderDepth === 0) and just removes the extra spaces mostly.

I tested it, and it appears that it slows down the Apostrophe CMS only by ~20ms, I mean TTFB increase, e.g. from 85ms to 105ms in my local environment (where these are no network or other delays).

Very interesting conversation. Your solution is a good implementation, but I think that if it expands TTFB by 20ms, then it’s probably not worth it because it’s typical to enable gzip transfer encoding at the proxy server level and that is going to squeeze out all those bytes anyway.

Another approach to HTML minification could be to minify Nunjucks templates in loader, see nunjucks-minify-loaders for example.

The best option I think would be to minify Nunjucks templates during deploy process – this is a way to avoid on-the-fly minification with the resulting performance penalties.

P.S. I agree that HTML minification may not play a significant role in website performance (or may even slow it down a little bit), but to have nice and neat HTML code seems right to me :slight_smile: