bigywater.tech
Flask · 163

模板渲染耗时

模板渲染慢在哪?第一次请求为什么慢?render_template_string 能不能用在热点路径?include 和 macro 有多大代价?这篇逐项量出来。

约 31 倍
render_template_string 相对文件模板的耗时(小模板)
2.5 → 1.4 ms
1000 项列表第一次渲染与之后的耗时
约 2.6 倍
循环里每项 include 相对直接写的耗时

编译与缓存

实测 · 本机执行输出
  第一次(含编译)2.51 ms | 之后的渲染中位数 1.36 ms | 编译约占 1.15 ms

上一篇:Flask Profiler;下一篇:JSON 序列化性能。

render_template_string

实测 · 本机执行输出
  渲染 1 项的小模板:文件模板 11 µs | render_template_string 343 µs(约 31 倍)

不同写法的耗时

实测 · 本机执行输出
  直接循环(自动转义)                1.36 ms
  |safe 跳过转义                1.61 ms
  每项 {% include %}          3.58 ms
  每项调用 macro                2.85 ms

自动重新加载

实测 · 本机执行输出
  auto_reload=False    小模板渲染 12 µs
  auto_reload=True     小模板渲染 14 µs

模板信号

实测 · 本机执行输出
  list_include.html    渲染 2 次,单次 0.95 ms
  (信号只在顶层 render_template 触发一次;include 进来的 row.html 不单独触发,它的耗时包含在 list_include.html 里)

分步演示

模板渲染耗时
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Python 3.14.7 / Flask 3.1.3 / Werkzeug 3.1.9 / Jinja2 3.1.6 / SQLAlchemy 2.1.1 / gunicorn 26.2.0(都装在自己的虚拟环境里);大多数实验用 Flask 的 test_client(直接调用 WSGI 应用,不经过网络),需要真实 HTTP 时另起 gunicorn 或开发服务器(端口 9600 以上,本机 127.0.0.1);计时用 time.perf_counter,数字每次运行会有小幅抖动
    • 没有验证:Jinja2 的字节码缓存(bytecode_cache)、模板继承层数对耗时的影响、真实页面(很多变量与过滤器)的整体占比、异步渲染(enable_async)、缓存渲染结果的片段缓存做法
    京ICP备2026067502号-1京公网安备11010502063487号