perf(browser): block image/media/font resources in camoufox fetch (~10x smaller pages, faster via proxy) #1761

Merged
lekss361 merged 1 commit from perf/camoufox-block-resources into main 2026-06-18 15:18:29 +00:00
Owner

Проблема

Браузерные фетчи (avito + domclick + cian/yandex browser-пути) медленные через mobile-прокси: SERP-страница 1.5-2 МБ, в основном картинки/медиа/шрифты, а нужные данные — в __initialData__/HTML (парсятся из page.content()). Тяжёлая страница долго качается через bandwidth-ограниченный прокси (главный боттлнек avito: 20-90с/стр под нагрузкой).

Решение — resource-blocking в camoufox

page.route("**/*", ...)route.abort() для image/media/font; всё остальное (document/script/stylesheet/xhr/fetch) проходит continue_(). Страница ~1.5-2 МБ → ~200 КБ (×10) → быстрее через прокси (бьёт в bandwidth-боттлнек).

Stealth сохранён — блокируем только презентационное (картинки/видео/шрифты); CSS/JS/XHR/document оставляем → client-hydration avito работает + браузер выглядит нормально для DataDome (не «голый» без ресурсов).

Глобально для всех браузерных поставщиков — применяется в per-page fetch-пути (_fetch_once + _fetch_once_pool per-source pool), независимо от source. curl_cffi-источники (cian/yandex gate) не затронуты (рендера нет).

ENV-флаги (в docstring server.py)

  • BROWSER_BLOCK_RESOURCES — default true (новый _parse_bool). Откат без редеплоя: false в .env.runtime.
  • BROWSER_BLOCKED_RESOURCE_TYPES — default image,media,font (CSV→frozenset).

Изменения

  • tradein-mvp/browser/server.py_apply_resource_block(page) (route-handler с try/except→fallback continue, no-op при флаге off); вызов после new_page() до goto в обоих fetch-путях. /login не тронут (нужен полный рендер). Goto/wait/content/stealth/proxy/семафор/recycle без изменений.
  • test_server_resource_block.py (нов, 8 тестов) + test_server_smoke.py (no-op route в _FakePage).

Тесты

pytest test_server_resource_block.py test_server_smoke.py25 passed (8 новых + 17 существующих; мокают route/request — реальный camoufox не поднимается). Ruff clean.

Деплой

build-browser job в deploy-tradein.yml (path tradein-mvp/browser/**) пересоберёт ghcr.io/.../tradein-browser + перезапустит контейнер. Dockerfile COPY server.py — тесты в образ не попадают (dev-only).

Прод-смоук после merge

avito SERP с блокировкой → подтвердить полная выдача (~50 карточек, не shell) + размер страницы ~200КБ + не блок (DataDome/гидрация целы — зависят от script/xhr, оставлены). Замерить latency/стр до/после.

## Проблема Браузерные фетчи (avito + domclick + cian/yandex browser-пути) медленные через mobile-прокси: SERP-страница **1.5-2 МБ, в основном картинки/медиа/шрифты**, а нужные данные — в `__initialData__`/HTML (парсятся из `page.content()`). Тяжёлая страница долго качается через bandwidth-ограниченный прокси (главный боттлнек avito: 20-90с/стр под нагрузкой). ## Решение — resource-blocking в camoufox `page.route("**/*", ...)` → `route.abort()` для `image`/`media`/`font`; всё остальное (`document`/`script`/`stylesheet`/`xhr`/`fetch`) проходит `continue_()`. Страница **~1.5-2 МБ → ~200 КБ (×10)** → быстрее через прокси (бьёт в bandwidth-боттлнек). **Stealth сохранён** — блокируем только презентационное (картинки/видео/шрифты); CSS/JS/XHR/document оставляем → client-hydration avito работает + браузер выглядит нормально для DataDome (не «голый» без ресурсов). **Глобально для всех браузерных поставщиков** — применяется в per-page fetch-пути (`_fetch_once` + `_fetch_once_pool` per-source pool), независимо от source. curl_cffi-источники (cian/yandex gate) не затронуты (рендера нет). ## ENV-флаги (в docstring server.py) - `BROWSER_BLOCK_RESOURCES` — default `true` (новый `_parse_bool`). Откат без редеплоя: `false` в `.env.runtime`. - `BROWSER_BLOCKED_RESOURCE_TYPES` — default `image,media,font` (CSV→frozenset). ## Изменения - `tradein-mvp/browser/server.py` — `_apply_resource_block(page)` (route-handler с try/except→fallback continue, no-op при флаге off); вызов после `new_page()` до `goto` в обоих fetch-путях. `/login` не тронут (нужен полный рендер). Goto/wait/content/stealth/proxy/семафор/recycle без изменений. - `test_server_resource_block.py` (нов, 8 тестов) + `test_server_smoke.py` (no-op `route` в `_FakePage`). ## Тесты `pytest test_server_resource_block.py test_server_smoke.py` → **25 passed** (8 новых + 17 существующих; мокают route/request — реальный camoufox не поднимается). Ruff clean. ## Деплой `build-browser` job в `deploy-tradein.yml` (path `tradein-mvp/browser/**`) пересоберёт `ghcr.io/.../tradein-browser` + перезапустит контейнер. Dockerfile `COPY server.py` — тесты в образ не попадают (dev-only). ## Прод-смоук после merge avito SERP с блокировкой → подтвердить **полная выдача (~50 карточек, не shell)** + размер страницы ~200КБ + не блок (DataDome/гидрация целы — зависят от script/xhr, оставлены). Замерить latency/стр до/после.
lekss361 added 1 commit 2026-06-18 15:18:08 +00:00
perf(browser): block image/media/font resources in camoufox fetch (~10x smaller pages, faster via proxy)
All checks were successful
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI / changes (pull_request) Successful in 6s
1533baad97
lekss361 added the
enhancement
scope/backend
scrapers
status/review
labels 2026-06-18 15:18:21 +00:00
lekss361 merged commit 8a7538ab13 into main 2026-06-18 15:18:29 +00:00
lekss361 deleted branch perf/camoufox-block-resources 2026-06-18 15:18:29 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#1761
No description provided.