Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Slow generation: HandlebarTemplateEngine rebuilds Handlebars and reparses templates on every render

未关闭
#12,745 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
45/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
冷清
技术栈
java

调研方向

从 HandlebarTemplateEngine.getRendered(...) 开始,检查每次渲染时如何创建 Handlebars 实例、helpers、templates 和 partials。审查提议的 IndentAwareTemplateCache 行为,并验证已编译 templates 的复用,以及在不同 include 缩进下 prettyPrint(true) 输出的正确性。在不改变 public API 或 templates 的情况下保持输出,并实现所述的生成速度提升,即表示完成。

由索引模型根据 Issue 内容生成。

描述

Summary

HandlebarTemplateEngine.getRendered(...) creates a new Handlebars instance and recompiles the template (and every partial it references) on every call. Profiling shows the jknack ANTLR-based lexer accounting for ~65% of CPU during code generation for a typical OpenAPI specification.

How to reproduce

Generate code with the handlebars engine (the default for v3) against any sufficiently large spec. The cost grows roughly with (templates_rendered) × (partials_per_template) because every render repeats the full Handlebars setup + parse.

Profile

Java Flight Recorder captured during a representative warm run shows:

  • ~65% of in-method CPU under org.antlr.v4.runtime.atn.LexerATNSimulator.closure(...) — jknack's parser.
  • Each getRendered allocates a new Handlebars, re-registers all helpers, and reparses the entry template, which in turn re-parses every {{> partial }} it transitively includes.

Why it matters

Generating a server-side stub project with ~75 controllers / ~180 output files takes ~50–60 s on the affected code path. Once compiled templates are cached for the lifetime of a single generation, the same workload completes in ~12 s — a ~4.5× speed-up with no API change and no spec-side change.

Precedent

#12313 / its accompanying fix established the same pattern in another hotspot (AbstractJavaCodegen.toModelName() was called millions of times and was cached for a 3× improvement). The fix proposed here applies the same idea to template parsing.

Caveat / why a naive cache breaks output

jknack's stock ConcurrentMapTemplateCache cannot be used as-is for handlebars partials in prettyPrint(true) mode. Partial.merge wraps the partial's TemplateSource in an anonymous class whose equals/hashCode delegate only to the underlying source (filename + lastModified), but whose content() returns the partial body re-indented by the include site's leading whitespace. The same partial included at two different indents therefore collides on lookup and the first-compiled indent wins for every subsequent include — observable as silently shifted whitespace in generated output. See related jknack issues #401 and #708.

The proposed fix carries a small replacement cache (~95 LOC) keyed on (filename, content), which preserves the speed-up while keeping per-indent renders correct.

Proposed fix

A PR will follow that:

  1. Holds a single Handlebars instance per HandlebarTemplateEngine (and so per generation), registering helpers once.
  2. Caches compiled top-level Templates per templateFile.
  3. Installs an IndentAwareTemplateCache to make handlebars' own partial cache safe under prettyPrint(true).

No public API changes. No template changes. No swagger-codegen-generators change required.

主要语言
Mustache
星标
17.8k
派生
6k
PR 合并指标
30 天内没有已合并 PR

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

swagger-api/swagger-codegen 的其他 Issue

查看 swagger-api/swagger-codegen 的全部 Issue

相似的 Issue

更多 Performance Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。