Spinner:
- article_results.html: replace hidden polling div with a visible
animated spinner banner; CSS spin keyframe added to input.css
Batch commits:
- generate_articles() now commits every 200 articles instead of
holding one giant transaction; articles appear in the admin UI
progressively without waiting for the full run
Performance (pre-compiled Jinja templates):
- Create one Environment + compile url/title/meta/body templates once
before the loop instead of calling _render_pattern() per iteration;
eliminates ~4 × N Environment() constructions and re-parses of the
same template strings (N = articles, typically 500+)
- Reuse url_tmpl for hreflang alt-lang rendering
Scenario override passthrough:
- Pass just-computed scenario data directly to bake_scenario_cards()
via scenario_overrides, avoiding a DB SELECT that reads an uncommitted
row from a potentially separate connection
Timing instrumentation:
- Accumulate time spent in calc / render / bake phases per run
- Log totals at completion: "done — 500 total | calc=1.2s render=4.3s bake=0.1s"
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>