From 2fae3b5f648224b02c20d7abcc6550f2d4932b41 Mon Sep 17 00:00:00 2001 From: OdWar420 <12932901+OdWar420@users.noreply.github.com> Date: Tue, 9 Jun 2026 22:12:24 +0200 Subject: [PATCH] perf(http): gzip-compress text responses (#3690) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The frontend's text assets shipped uncompressed on every cold load. Add Starlette's GZipMiddleware. Measured on the current assets: - style.css 1,127 KB -> 238 KB (-79%) - index.html 202 KB -> 35 KB (-83%) - chat.js 238 KB -> 60 KB (-75%) minimum_size=1024 skips tiny bodies; Starlette excludes `text/event-stream` by default, so the SSE streams (chat, shell, research, model-probe — all served with media_type="text/event-stream") are never compressed or buffered. Composes cleanly with the existing security-header middleware. No behavioural change. Built by OdWar -- with Claude thinking alongside. --- app.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app.py b/app.py index abd49e26b..cfd73e83f 100644 --- a/app.py +++ b/app.py @@ -47,6 +47,7 @@ from fastapi.responses import JSONResponse, FileResponse, HTMLResponse from fastapi.middleware.cors import CORSMiddleware from fastapi.staticfiles import StaticFiles from starlette.middleware.base import BaseHTTPMiddleware +from starlette.middleware.gzip import GZipMiddleware # Core imports from core.constants import ( @@ -104,6 +105,16 @@ app.add_middleware( ], ) +# ========= RESPONSE COMPRESSION (gzip) ========= +# The frontend's text assets (style.css, index.html, the JS bundles) shipped +# uncompressed on every cold load. gzip cuts CSS/JS/HTML by ~75-85% on the wire +# with no behavioural change. Starlette's GZipMiddleware excludes +# `text/event-stream` by default, so the SSE streams (chat, shell, research, +# model-probe — all served with media_type="text/event-stream") are never +# compressed or buffered; only complete bodies over minimum_size are. The +# security-header middleware composes cleanly on top. +app.add_middleware(GZipMiddleware, minimum_size=1024, compresslevel=6) + # ========= SECURITY HEADERS MIDDLEWARE ========= app.add_middleware(SecurityHeadersMiddleware)