Cómo bajé el build de Hugo a la mitad (y recuperé los tags)

· hugo, blog, performance

Mi blog tiene 1194 archivos Markdown, 20 MB de contenido y 595 tags. hugo tardaba ~50 s. Ahora el build usa ~27 s de CPU y, con el navegador cerrado, termina en ~25–30 s.

Medir antes de tocar

time hugo --quiet --renderToMemory
hugo --renderToMemory --templateMetrics

--renderToMemory compila sin escribir public/. --templateMetrics muestra qué template consume el tiempo. Ojo con time: si real es mucho mayor que user+sys, el problema es la carga de la máquina (navegador, etc.), no Hugo.

Qué encontré

  • rss.xml: 25 s acumulados, con un feed de 13 s. El RSS por defecto recorre todos los posts y calcula .Summary de cada uno.
  • list.html: 10 s por las 595 páginas de tag.
  • single.html: el resto, sobre todo por 4 posts gigantes (2.4 MB, 2.3 MB, 1.1 MB, 0.9 MB).

1. RSS liviano (sin contenido)

Reemplacé layouts/_default/rss.xml por uno que lista solo los últimos 20, sin .Summary:

{{ range first 20 .Pages }}
<item>
  <title>{{ .Title }}</title>
  <link>{{ .Permalink }}</link>
  <pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" }}</pubDate>
  <guid>{{ .Permalink }}</guid>
</item>
{{ end }}

También desactivé el RSS por tag en config.toml, que generaba 595 feeds inútiles:

[outputs]
  home = ["HTML", "RSS"]
  section = ["HTML", "RSS"]
  taxonomy = ["HTML"]
  term = ["HTML"]
  page = ["HTML"]

2. Theme minimalista

Saqué Bulma y el navbar con imagen. Ahora hay un baseof.html de una columna, un index.html con lista y paginación, y un CSS de ~2 KB. El ancho es 100%, la letra es un poco más grande y el resaltado de código sigue con Chroma/Monokai.

La paginación quedó en 250 posts por página (pagination.pagerSize = 250), o sea 5 páginas.

3. Tags: páginas sí, feeds no

Los tags son útiles, así que las páginas /tags/... siguen existiendo. Lo que saqué es el RSS de cada tag. En cada post los tags enlazan a su página:

{{ with .Params.tags }}
  <span class="tags"> · {{ range $i, $tag := . }}{{ if $i }}, {{ end }}<a href="/tags/{{ $tag | urlize }}/">{{ $tag }}</a>{{ end }}</span>
{{ end }}

Uso .Params.tags + urlize en vez de .GetTerms: .GetTerms obligaba a resolver las taxonomías en cada página y casi duplicaba el tiempo de single.html.

Resultado

CPU del build:   ~27 s (user+sys)
con navegador cerrado: ~25–30 s
con Chromium/Falkon abiertos: 50 s o más

La diferencia entre real y user+sys es contención de CPU. Si el build se siente lento, cerrá el navegador antes de correr add_commit_push.sh.

Si querés exprimirlo más

Los 4 posts gigantes siguen dominando single.html. Si no los necesitás como páginas, movelos fuera de content/ o marcalos con:

_build:
  render: never
  list: never

Para volver al RSS completo, borrá layouts/_default/rss.xml.