Handlebars-Net / Handlebars.Net

A real .NET Handlebars engine
MIT License
1.24k stars 214 forks source link

Memory allocation with every compiled template (to support l10n of templates) #513

Closed oformaniuk closed 2 years ago

oformaniuk commented 2 years ago

Discussed in https://github.com/Handlebars-Net/Handlebars.Net/discussions/493

Originally posted by **wdolek** January 31, 2022 We are using Handlebars for rendering localized templates. Having naive implementation of compiling each localized template separately we are getting to ~300MiB of compiled templates in memory. Template compiled `N` times, each time with different "static" text: ```html

Hello {{name}}

``` --- We have decided to _fix_ this by compiling template once and just vary localized text in it. Unfortunately even that localized text may contain Handlebars syntax, so we thought we can: - compile template itself - compile dictionary values separately, having "helper" which will inject it accordingly ... but this doesn't scale, because no matter how small compiled template is, it has over 30KiB. We tried adding those dictionary entries as partial templates using `Handlebars.RegisterTemplate` - but there was no difference. When checked implementation it was obvious why - using partial template is the same as compiling it, but just registering it inside Handlebars Environment. ```csharp hb.RegisterTemplate("tpl1-dict-greetings-en", "Hello {{name}}"); hb.RegisterTemplate("tpl1-dict-greetings-fr", "Bonjour {{name}}"); // ... ``` ```html

{{> (append 'tpl1-dict-greetings-' culture) }}

``` --- To the main point, we can see that every time we compile template, there's `HandlebarsConfigurationAdapter configuration` associated to it. This object takes ~25KiB and for every compiled template it is new instance (pointing to different place in memory) of seemingly same configuration object. Now, having several thousand of small templates we need to compile we are again getting to tens or hundreds of MiBs allocated. Is there any way how to achieve: - localized templates, where translations may use Handlebars as well? - minimize memory footprint, optimize presence of `HandlebarsConfigurationAdapter` in every compiled template?