Slow generation: HandlebarTemplateEngine rebuilds Handlebars and reparses templates on every render
还没有人认领这个 Issue。
评估
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 新手友好度
- 45/100
- Issue 类型
- 缺陷
- 描述清晰度
- 基本清楚
- 活跃度
- 冷清
- 技术栈
- java
- 领域
- performance, tooling
调研方向
从 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
getRenderedallocates a newHandlebars, 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:
- Holds a single
Handlebarsinstance perHandlebarTemplateEngine(and so per generation), registering helpers once. - Caches compiled top-level
Templates pertemplateFile. - Installs an
IndentAwareTemplateCacheto make handlebars' own partial cache safe underprettyPrint(true).
No public API changes. No template changes. No swagger-codegen-generators change required.
- 主要语言
- Mustache
- 星标
- 17.8k
- 派生
- 6k
- PR 合并指标
- 30 天内没有已合并 PR
环境准备
- 提供 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
swagger-api/swagger-codegen 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 78/100
swagger-api/swagger-codegen#12755 ·
-
难度 2/5 1-3 小时 新手友好度 62/100
swagger-api/swagger-codegen#12445 ·
-
security vulnerability
难度 1/5 1 小时以内 新手友好度 62/100
swagger-api/swagger-codegen#11942 ·
-
[JAVA] Non compilable enums generated with property errorOnUnknownEnum=true可能已有人在做 @HiagoW 于 1464 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 68/100
swagger-api/swagger-codegen#11812 · 1 个 reaction ·
-
security vulnerability
难度 2/5 1-3 小时 新手友好度 65/100
swagger-api/swagger-codegen#11594 ·
查看 swagger-api/swagger-codegen 的全部 Issue
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 82/100
motiondivision/motion#3955 ·
维护者通常 1 天内回复
-
bug P3
难度 2/5 1-3 小时 新手友好度 72/100
maniator/verticopolis#1095 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 82/100
维护者通常 2 天内回复
-
难度 2/5 1-3 小时 新手友好度 88/100
维护者通常 2 天内回复
-
good first issue gpu serve
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 1 天内回复