Status: needs-triage
Context
PageSpeed Insights (via Google Search Console, 2026-07-17) flagged "Çok büyük
ağ yükleri" on both desktop (~6.9 MB total) and mobile (~10.1 MB total) for
https://eventradar.dev/. The large payload is almost entirely event
thumbnail images pulled directly from source platforms and rendered
unmodified in EventCard (frontend/src/components/EventCard.jsx):
cdn.prod.website-files.com — two PNGs at 2.0 MB and 1.35 MB
api.ibb.gov.tr — up to four PNGs, largest at 0.9-2.3 MB
learn.pupilica.com — several images 300-480 KB each
framerusercontent.com, S3 buckets — additional 100 KB-1 MB images
These are event.image_url values scraped as-is from each source
(app/scrapers/*.py) and stored in the events.image_url column
(app/models/event.py). The frontend already displays them at a fixed
200px-tall card thumbnail (.event-image in frontend/src/index.css) with
loading="lazy", but the full multi-megabyte original is still downloaded —
lazy-loading only delays the request, it doesn't shrink it.
Why this is a separate issue
Fixing this requires either:
- An image proxy/resizing service (e.g. an on-the-fly resize endpoint in the
FastAPI backend, or a CDN-level image transform) that re-encodes source
images to a card-appropriate size before serving them, or
- Downloading and caching a resized copy at scrape time in
app/scrapers/*.py / app/services/scraper_service.py.
Both are a real backend/infra design decision (storage, cache invalidation,
handling source images disappearing) — out of scope for the nginx/CSS/CLS
fixes already shipped in fix/google-search-console.
Suggested approach (not decided)
- Add a lightweight resize step in the scraper pipeline that downloads
image_url, re-encodes to e.g. 400x200 WebP, and stores it (S3/local
volume) behind the app's own domain — this also removes the current
dependency on third-party hosts staying up.
- Alternatively, front
image_url with a resize proxy
(/api/img?url=...&w=400&h=200) that streams a transformed image with
caching headers.
Acceptance criteria
Status: needs-triage
Context
PageSpeed Insights (via Google Search Console, 2026-07-17) flagged "Çok büyük
ağ yükleri" on both desktop (~6.9 MB total) and mobile (~10.1 MB total) for
https://eventradar.dev/. The large payload is almost entirely eventthumbnail images pulled directly from source platforms and rendered
unmodified in
EventCard(frontend/src/components/EventCard.jsx):cdn.prod.website-files.com— two PNGs at 2.0 MB and 1.35 MBapi.ibb.gov.tr— up to four PNGs, largest at 0.9-2.3 MBlearn.pupilica.com— several images 300-480 KB eachframerusercontent.com, S3 buckets — additional 100 KB-1 MB imagesThese are
event.image_urlvalues scraped as-is from each source(
app/scrapers/*.py) and stored in theevents.image_urlcolumn(
app/models/event.py). The frontend already displays them at a fixed200px-tall card thumbnail (
.event-imageinfrontend/src/index.css) withloading="lazy", but the full multi-megabyte original is still downloaded —lazy-loading only delays the request, it doesn't shrink it.
Why this is a separate issue
Fixing this requires either:
FastAPI backend, or a CDN-level image transform) that re-encodes source
images to a card-appropriate size before serving them, or
app/scrapers/*.py/app/services/scraper_service.py.Both are a real backend/infra design decision (storage, cache invalidation,
handling source images disappearing) — out of scope for the nginx/CSS/CLS
fixes already shipped in
fix/google-search-console.Suggested approach (not decided)
image_url, re-encodes to e.g. 400x200 WebP, and stores it (S3/localvolume) behind the app's own domain — this also removes the current
dependency on third-party hosts staying up.
image_urlwith a resize proxy(
/api/img?url=...&w=400&h=200) that streams a transformed image withcaching headers.
Acceptance criteria
size proportionate to their 400x200 display box (not multi-MB
originals).
PageSpeed Insights run (large network payload audit).
/placeholder-image-colored.webp(existingonErrorbehavior inEventCard.jsxmust keep working).