flask默认不压缩响应,需安装flask-compress并调用compress().init_app(app)启用;它自动处理200响应、vary头、content-encoding跳过及流式响应,推荐配置compress_min_size和compress_mimetypes以覆盖js/css等类型。

Flask 默认不开启任何响应压缩,必须显式集成扩展才能生效;自己手写中间件容易漏掉状态码判断、缓存头处理或流式响应支持,不推荐。
装 flask-compress 并初始化 app
这是最稳妥的方式,flask-compress 已处理好常见边界:只对 200 响应压缩、自动设置 Vary: Accept-Encoding、跳过已带 Content-Encoding 的响应、兼容 streaming response。
- 安装:
pip install flask-compress - 初始化(通常在创建
app实例后):from flask_compress import Compress compress = Compress() compress.init_app(app)
- 别写
Compress(app)—— 这种写法在某些 Flask 版本里会跳过配置加载,导致压缩不生效
调整压缩阈值和 MIME 类型白名单
默认只压缩 ≥500 字节、且 Content-Type 在白名单内的响应,小 JSON 或 HTML 片段可能被跳过。
- 降低阈值(比如压所有 ≥100 字节的响应):
app.config['COMPRESS_MIN_SIZE'] = 100 - 加 JS 支持:
app.config['COMPRESS_MIMETYPES'] = ['text/html', 'application/json', 'application/javascript', 'text/css'] - 注意:不要把
application/octet-stream或图片字体类型加进去——这些本身已是压缩格式,再 gzip 可能反而变大
验证是否真生效,而不是“看起来开了”
光看代码没用,得实测响应头。常见假象是 Nginx 已开 gzip on,但 Flask 层也开了,结果双压浪费 CPU 且可能出错。
- 用 curl 检查:
curl -H "Accept-Encoding: gzip" -I http://localhost:5000/api/data,确认返回头含Content-Encoding: gzip - 如果返回了但体积没变小,大概率是响应体太小(
- 若用 Nginx 反向代理,务必关掉 Flask 的压缩,只留 Nginx 层做——它用 C 实现,更高效,还支持连接复用优化
别踩 streaming response 的坑
对生成器视图(@app.route('/stream') 返回 yield)启用压缩时,flask-compress 默认会缓存整个响应体再压缩,吃内存且破坏流式语义。
- 解决办法:设
app.config['COMPRESS_STREAM'] = False(禁用流式压缩),或干脆避开对这类接口启用压缩 - 手动压缩 streaming response 需用
zlib.compressobj()分块处理,复杂度高,一般没必要 - 异步视图(
async def)里调zlib.compress()是同步阻塞操作,会卡住事件循环——除非你确定数据极小
真正难的不是“怎么开”,而是判断“该不该开”:静态资源交给 CDN 或 Nginx,API 响应看体积和频率,小而快的接口压了反而拖慢延迟。压缩永远是权衡,不是开关一按就万事大吉。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











