feat(perf): enable GZipMiddleware reducing static transfer size by 81.7%
This commit is contained in:
1 parent
1ee39d66bd
commit
25576de87a
3 files changed
+29
-3
No files matched your search
@@ -40,9 +40,10 @@
|
||||
---
|
||||
|
||||
### 2. 🗜️ Сжатие статического трафика (`GZipMiddleware`)
|
||||
- [ ] Подключить `GZipMiddleware(minimum_size=1000)` в [`app/main.py`](file:///home/ai-projects/services/study.qpid.pro/app/main.py).
|
||||
- [ ] Сократить объём передаваемых файлов `app.js` (95 КБ), `index.html` (56 КБ) и `style.css` (25 КБ) на 70–75% (суммарно со 176 КБ до ~40 КБ).
|
||||
- [ ] Проверить заголовки `Content-Encoding: gzip` в ответах.
|
||||
- [x] Подключить `GZipMiddleware(minimum_size=1000)` в [`app/main.py`](file:///home/ai-projects/services/study.qpid.pro/app/main.py).
|
||||
- [x] Сократить объём передаваемых файлов `app.js` (111.8 КБ -> 21.5 КБ), `index.html` (55.2 КБ -> 10.3 КБ) и `style.css` (58.2 КБ -> 9.4 КБ) на 81.7% (суммарно с 225.2 КБ до 41.2 КБ).
|
||||
- [x] Проверить заголовки `Content-Encoding: gzip` в ответах и добавить регрессионный тест в `tests/test_api.py`.
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ from datetime import datetime, timezone, date
|
||||
from fastapi import FastAPI, Depends, HTTPException, Request, Response, status, Query
|
||||
from fastapi.responses import HTMLResponse, StreamingResponse, JSONResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from fastapi.middleware.gzip import GZipMiddleware
|
||||
from pydantic import BaseModel, Field
|
||||
import httpx
|
||||
|
||||
@@ -44,6 +45,9 @@ app = FastAPI(
|
||||
lifespan=lifespan,
|
||||
)
|
||||
|
||||
# GZip Compression Middleware (compresses responses >= 1000 bytes)
|
||||
app.add_middleware(GZipMiddleware, minimum_size=1000)
|
||||
|
||||
# Mount static files
|
||||
app.mount("/static", StaticFiles(directory=str(config.BASE_DIR / "app" / "static")), name="static")
|
||||
|
||||
|
||||
@@ -788,5 +788,26 @@ def test_srs_queue_and_quiz_tag_filtering():
|
||||
assert not any(q["card"]["id"] == c2["id"] for q in quiz_items)
|
||||
|
||||
|
||||
def test_gzip_compression():
|
||||
# 1. Assets >= 1000 bytes receive GZip encoding when requested
|
||||
resp_js = client.get("/static/js/app.js", headers={"Accept-Encoding": "gzip"})
|
||||
assert resp_js.status_code == 200
|
||||
assert resp_js.headers.get("content-encoding") == "gzip"
|
||||
|
||||
resp_css = client.get("/static/css/style.css", headers={"Accept-Encoding": "gzip"})
|
||||
assert resp_css.status_code == 200
|
||||
assert resp_css.headers.get("content-encoding") == "gzip"
|
||||
|
||||
resp_html = client.get("/", headers={"Accept-Encoding": "gzip"})
|
||||
assert resp_html.status_code == 200
|
||||
assert resp_html.headers.get("content-encoding") == "gzip"
|
||||
|
||||
# 2. Assets < 1000 bytes are not compressed (respecting minimum_size=1000)
|
||||
resp_manifest = client.get("/manifest.json", headers={"Accept-Encoding": "gzip"})
|
||||
assert resp_manifest.status_code == 200
|
||||
assert resp_manifest.headers.get("content-encoding") is None
|
||||
|
||||
# 3. Requests without gzip Accept-Encoding do not receive gzip
|
||||
resp_raw = client.get("/static/js/app.js", headers={"Accept-Encoding": "identity"})
|
||||
assert resp_raw.status_code == 200
|
||||
assert resp_raw.headers.get("content-encoding") is None
|
||||
Reference in new issue
Block a user