From the documentation:
The
tplfunction allows developers to evaluate strings as templates inside a template. This is useful to pass a template string as a value to a chart or render external configuration files. Syntax:{{ tpl TEMPLATE_STRING VALUES }}
When writing generic Helm charts or libraries, calls to tpl are often overused, and for a good reason: they give lots of flexibility, and allow chart users to avoid repetition in the values.yaml file.
The tpl function is however costly, and slow, and this is why it should be called only when necessary.
`tpl` function not performant
#8002
I have a scenario of having one umbrella chart with many sub-charts as dependencies. When I have the templates folder in umbrella chart, helm lint takes more time like almost 30 to 40 minutes. When this folder is not there, helm lint returns very fast. Can I know the reason.running in debug mode not giving any logs. It is helm v3.
How to limit calls while keeping the flexibility ? My solution is to wrap all calls to tpl using the following helper function:
{{- define "bettertpl" -}}
{{- $tpl := .value -}}
{{- /* handle cases where .value is a yaml object */ -}}
{{- if not (typeIs "string" $tpl) -}}
{{- $tpl = toYaml $tpl -}}
{{- end -}}
{{- /* only call tpl if there is at least one template expression */ -}}
{{- if contains "{{" $tpl -}}
{{- tpl $tpl .context }}
{{- else -}}
{{- $tpl -}}
{{- end -}}
{{- end -}}
As the code should make it clear, bettertpl adds two features to the regular tpl:
- it allows to template anything (not just string), as
dict,list, etc. will be converted to string first, and - it only calls the slow
tplwhen needed: if the string doesn't contain at least one{{ ... }}, we know we can just print it as is.
Usage:
before: {{ tpl .Values.foo . }}
after: {{ include "bettertpl" (dict "value" .Values.foo "context" .) }}
Note that I use named arguments for better readability. You can get rid of them and use lists instead: In the template above, change You find it too verbose ?
{{ include "bettertpl" (list .Values.foo .) }}
.value → first . and .context → index . 2 to read from list arguments instead.
Is it worth it ? As an example, I recently migrated a gitops repository with an umbrella chart of around 20 sub-charts. After a refactoring allowing me to use only one base chart for all, my helm template went from <1s to more than 15 seconds...
I was able to take it down to 4 seconds by limiting the calls to tpl with this simple trick, which is quite an improvement.
Top comments (1)
Great geometry dash spam article, thanks for sharing. Let me ask you another question: if I need to use tpl to handle dynamic configuration from values.yaml, is there an optimal way to reduce the number of tpl calls while still maintaining flexibility? I'm using Helm v3 with many subcharts so I'm quite concerned about performance.