koajs / koa-hbs

Handlebars templates for Koa.js
MIT License
159 stars 43 forks source link

Templates and partials are not cached #84

Open Gotterbild opened 5 years ago

Gotterbild commented 5 years ago

I'm not sure if koa-hbs package is maintaned, but I'll give it a shot.

From the presence of disableCache in docs, it looks like all views and partials are cached. But from mye experiments it looks like it is not true.

I want to implement HTML minification. To achieve this task, I've created a Handlebars helper that runs html-minifier over passed content.

const htmlMinifier = require('html-minifier')

hbs.registerHelper('minify', (context, options) => {
  const minified = htmlMinifier.minify(options.fn(context), {
    collapseWhitespace: true,
    removeComments: true,
    removeEmptyAttributes: false, // some <img> tags require alt=""
    minifyCSS: true,
    minifyJS: {
      compress: false, // disable compress to only delete whitespace
      mangle: true, // process whitespace
      warnings: true,
    },
  })
  return new hbs.SafeString(minified)
})

Then I've wrapped this helper over one of my templates that is pulled into the {{{body}}} of default layout. Wrapping code is inside of the template file, not in default layout file.

{{#minify this}}
  {{!-- template code --}}
{{/minify}}

I look into the code and it is minified successfully.

However, when I've started to test how this implementation affects performance, I found out that it causes significant performance issues.

I've double checked and I have disableCache: false. Without minification average request time is about 7.134ms. With minification average request time is about 86.812ms, which is about 10 times slower.

I've experimented with minifying smaller pieces of code and it affects timings a lot. Bigger piece of code I minify, bigger request time I get. So, for me it is clear that caching is not working as expected.

Looks like caching is working as when I enable minification, it doesn't affect resulting code until I change disableCache to true and refresh page in browser. Then I see that code is minified and return disableCache to false.

But average request number still grows, so it leads me to thoughts that resulting HTML is taken from cache, while templates are still rendered every time in background.

CDaxi commented 5 years ago

In my opinion, there is a misunderstanding on your side. The disableCache flag switches the compile process from hbs files to template function on or off. It is no html cache. If you want to cache your rendered html, you can use a middleware to check if the hgml is already rendered and stored in memcached, redis or something else. When your middleware finds a cached html, you can send it immediatly, otherwise load your data and put the data into ctx.render which calls the cached hbs functions.