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`)
|
### 2. 🗜️ Сжатие статического трафика (`GZipMiddleware`)
|
||||||
- [ ] Подключить `GZipMiddleware(minimum_size=1000)` в [`app/main.py`](file:///home/ai-projects/services/study.qpid.pro/app/main.py).
|
- [x] Подключить `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 КБ).
|
- [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 КБ).
|
||||||
- [ ] Проверить заголовки `Content-Encoding: gzip` в ответах.
|
- [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 import FastAPI, Depends, HTTPException, Request, Response, status, Query
|
||||||
from fastapi.responses import HTMLResponse, StreamingResponse, JSONResponse
|
from fastapi.responses import HTMLResponse, StreamingResponse, JSONResponse
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
|
from fastapi.middleware.gzip import GZipMiddleware
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
import httpx
|
import httpx
|
||||||
|
|
||||||
@@ -44,6 +45,9 @@ app = FastAPI(
|
|||||||
lifespan=lifespan,
|
lifespan=lifespan,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# GZip Compression Middleware (compresses responses >= 1000 bytes)
|
||||||
|
app.add_middleware(GZipMiddleware, minimum_size=1000)
|
||||||
|
|
||||||
# Mount static files
|
# Mount static files
|
||||||
app.mount("/static", StaticFiles(directory=str(config.BASE_DIR / "app" / "static")), name="static")
|
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)
|
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