Duplicate entries in templateMetrics

Trying to help bring this up if it’s a bug. I really appreciate @moorereason’s work to improve metrics and everyone’s work on making Hugo better.

I’ve noticed that template metrics in recent versions includes lines both with the extension (e.g. partials/example.html) and without (e.g. partials/example). I’m assuming that this isn’t the expected behavior.

Is anyone else seeing this? If so I can open an issue.

When did this started?

This doesn’t happen on older versions. So I suspect it started with the addition of “cached count” from PR 8376 from Feb 16, 2022 as the last true edit to the file was Mar 12, 2020. (see /metrics/metrics.go)


When running hugo --templateMetrics --templateMetricsHints below are examples of some of the files this is happening to but it seems to be everything for me.

On 0.93.0+extended darwin/amd64 (via brew) and v0.94.0-DEV+extended darwin/amd64 (via brew --HEAD).

 cumulative       average       maximum      cache  percent  cached  total  
       duration      duration      duration  potential   cached   count  count  template
     ----------      --------      --------  ---------  -------  ------  -----  --------
2.264709287s    5.405034ms   124.084329ms         95      100     419    419  partials/site/javascript-head
2.1610551s        61.744431ms  123.511292ms        0        0       0     35  partials/site/javascript-head.html
   7.269484328s   403.86024ms  454.054488ms          0        0       0     18  partials/site/cart-js.html
   6.814583337s  194.702381ms  454.057211ms        100      100      35     35  partials/site/cart-js

On v0.92.2+extended darwin/arm64 (via MacPorts) partials only show up once.

      cache     cumulative       average       maximum         
  potential       duration      duration      duration  count  template
      -----     ----------      --------      --------  -----  --------
74  2.395185227s   66.532922ms  137.267246ms     36  partials/site/javascript-head.html
100  1.331203262s   73.955736ms   82.234703ms     18  partials/site/cart-js.html

Also, I was thinking of trying to update the docs for the new feature but wasn’t confident on defining the terms: Build Performance | Hugo

I am unable to reproduce this with v0.93.1-E9669FED+extended linux/amd64. I’ve tried calling the partial from multiple templates, with and without the extension, on a multilingual site, using multiple output formats, etc.

Can you provide a minimal example to reproduce the problem?

I’m able to reproduce it from this barebones repo. To borrow from @n1xx1, this repo from issue #9588 shows a duplicate: GitHub - n1xx1/hugo-0.93.0-deadlock-repro

After --HEAD at 883e71c

Before v0.92.2

(Before v0.92.2 Extended)

Are you not seeing it on v0.93.1-E9669FED+extended linux/amd64?

Thanks for the repo; that had the piece I was missing.

Given these templates:

├── bar.html
└── foo.html

and these calls within baseof.html:

{{ partial "foo" . }}
{{ partial "foo.html" . }}

{{ partialCached "bar" . }}
{{ partialCached "bar.html" . }}

this is the final column in the console output:


When calling the partial function, duplicate entries are not created regardless of whether or not you specify the template’s extension when making the call.

The problem is limited to the partialCached function, and only occurs when you are inconsistent when specifying the template name.

When the extension isn’t specified we fallback to .html. Perhaps, with partialCached, we’re capturing the template name before the fallback has occurred.

The fallback to .html allows us to be a bit lazy. Instead, as a best practice, we should provide a fully qualified name.

EDIT: As I think more about this, I wish the partial function did the same thing so that I would know when I’m being lazy.

1 Like

Awesome research @jmooring !

We pretty much exclusively use partialCached so it didn’t occur to me that partial is handled differently.

For the original caching/metrics question… Adding the extension does fix it but does this mean that when you don’t use the extension with partialCached, aka, {{ partialCached "bar" . }} instead of with the extension aka {{ partialCached "bar.html" . }} that templateMetrics reporting considers them separately or that it’s not caching properly?

Also, for what it’s worth. in the test repo there isn’t inconsistent usage when specifying the template name but it’s still happening.

Is it a requirement to include the extension when using partial and partialCached?
I also never thought about or noticed that the docs use the extension when using partial or partialCached. Is it an incorrect usage to not include the .html extension?

This post from 2017 suggests that not including the extension with any partial call is incorrect:

Thanks in advance! I’m betting every larger Hugo site relies on partialCached and --templateMetrics so hopefully your efforts also help many other users/sites!

I do not know the answer to that. Maybe the cache key is derived from the first argument to the partialCached function, instead of the filename to which it resolves. Perhaps @bep or @moorereason can provide a definitive answer.

I see that now.

The first call is simple:

layouts/_default/baseof.html --> {{ partialCached "renderPage" . . }}

The other calls are not simple, for example:

content/a.md --> {{< include "/b" >}} --> {{ .Render "include" }} --> {{ partialCached "renderPage" . . }}

There’s nothing wrong with this (other than not specifying a fully qualified file name), but I wonder if different “pipelines” handle things differently.

I would like to say “Yes” but eliminating the fallback would break a lot of sites.

Another good reason to include the extension is to avoid collisions with partials that are defined inline (i.e., within another partial), presuming the inline partial definition does not include an extension. The partial namespace is global; you can access an inline partial from anywhere.

If I’m working on the docs and I see an example where the extension isn’t included, I usually change it, but it doesn’t always get my attention.

1 Like

Create an issue and we (or I) will fix it.

1 Like

I’ve created an issue:

1 Like

See recent issue comment:

I have added a comment as well, as I was unaware that best practice was to use .html and in fact (don’t remember why) thought that it was preferred to omit the the .html for partial calls and would like to see the non-best practice WARN or something obvious like that.


1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.