perf(3d): static rollers, lite mode, B receiver bin timing, clean console

This commit is contained in:
root
2026-07-09 18:39:59 +02:00
parent 8e9ae4f62b
commit e89c728dd2
55 changed files with 1409 additions and 334 deletions

View File

@@ -0,0 +1,153 @@
# PERFORMANCE & B RECEIVER FIX REPORT
Дата: 2026-07-09
Ветка: `dan_branch`
Production: https://arhipovdan.ru/
---
## 1. Что тормозило (root cause)
Production audit (`docs/performance_physics_fix_screenshots/before/`):
| Причина | Детали |
|---------|--------|
| **53+ useFrame на роликах** | Каждый `Roller` имел собственный `useFrame` с покадровым вращением → десятки хуков на кадр. |
| **Shadow overhead** | `directionalLight castShadow` + `castShadow/receiveShadow` на mesh при `Canvas shadows={false}` — лишняя работа GPU. |
| **6 belt stripes + тяжёлые эффекты** | PointCloud (12 sphere mesh), ScanLine, MotionTrail, cinematic camera — все на каждом кадре. |
| **До 10 historical STL items** | До 10 одновременных `PhysicalPlaybackItem` с STL/fallback. |
| **STL wireframe overlay** | Ранее per-item `EdgesGeometry` (убрано ранее в `PhysicalPlaybackItem`). |
| **React setPlayback ~20 Hz** | `App.tsx` обновляет playback каждые 50 ms — допустимо, но усиливалось перерисовкой тяжёлой сцены. |
Console (before): **0 errors, 0 spam logs**. Только browser warnings: `THREE.Clock deprecated`, `GPU stall ReadPixels` (Playwright screenshots, не наш код).
---
## 2. Какие логи убраны
`grep` по `src/`: runtime `console.log` **отсутствуют**.
Оставлено (допустимо):
- `console.error` в `ThreeErrorBoundary`, `MainPage`, `ProductDemoSection` — только при падении Canvas.
- `STLModel.tsx` `console.warn` → **только в DEV** (`import.meta.env.DEV`).
Критерий после фикса: **0 errors, 0 spam logs** (`after_console.json`).
---
## 3. Что оптимизировано
| Изменение | Файл |
|-----------|------|
| Ролики **статические** (без useFrame) | `SorterDigitalTwinContinuous.tsx` |
| Убраны `castShadow` / shadow maps | `SorterDigitalTwinContinuous.tsx` |
| Belt stripes: **4 desktop / 3 mobile** | `ConveyorBelt` |
| Ролики: шаг x2 в simplified mode | `ConveyorBelt` |
| `MAX_VISIBLE_ITEMS = 8` | `SorterDigitalTwinContinuous.tsx` |
| PointCloud / ScanLine / MotionTrail / cinematic cam **off в simplified** | `ContinuousScene` |
| `PhysicalPlaybackItem` обёрнут в `React.memo` | `PhysicalPlaybackItem.tsx` |
| STL: shared geometry via `useLoader`, без wireframe overlay | `PhysicalPlaybackItem.tsx` |
| LaserBeam: static, без useFrame | `SorterDigitalTwinContinuous.tsx` |
| Canvas: `shadows={false}`, `dpr` capped, `powerPreference: high-performance` | уже было |
---
## 4. B receiving bin / tray
Добавлена физическая **BReceiverBin** (открытый лоток на полу):
- центр `(4.4, 0, 0)`, размер **1.0 × 0.8 m**, стены **0.4 m**;
- дно на `floorY = 0.08 m` (как C/D cage floor);
- 4 ноги до пола, не висит в воздухе;
- transfer deck на высоте ленты (1.5 → 3.6 m) + **drop chute** в bin;
- зелёный акцент B (`#16a34a`), отличается от C/D.
---
## 5. Как B товар попадает и остаётся в B
**conveyorNetwork path (B):**
```
main_belt → inspection_station → routing_junction → b_transfer → chute_b → b_receiver_floor
```
**physicalItemMotion (исправлен тайминг):**
- `routing` phase (6400–8900 ms): transfer (55%) → chute (45%);
- с **exit** phase (8900 ms+): `surface = b_receiver_floor`, поза внутри bounds;
- B item **не исчезает**, **не на активной ленте** после exit;
- settled фиксирован при увеличении времени.
**Тесты:**
- `B final pose inside b_receiver_floor bounds`
- `settled B NOT on active belt`
- `settled B y < 0.35 m` (ниже ленты 0.7 m)
- `settled at elapsedMs >= 9000`
- C/D containment — без регрессий
---
## 6. C/D не сломаны
Пути C/D без изменений. Тесты `c_cage_floor` / `d_cage_floor` bounds — pass.
Roll-cage с внутренним полом сохранён.
---
## 7. Тесты
`npm run test` → **13 files, 137 tests passed** (добавлен тест B bin floor height).
---
## 8. Screenshots
`docs/performance_physics_fix_screenshots/before/`
`docs/performance_physics_fix_screenshots/after/`
| Файл | Содержание |
|------|------------|
| `01_home_idle.png` | idle |
| `02_play_running_smooth.png` | play running |
| `03_b_item_enters_b_receiver.png` | B routing / chute |
| `04_b_item_settled_in_b_bin.png` | B case exit/clear (bin на полу виден) |
| `05_c_item_settled_in_c_cage.png` | C cage |
| `06_d_item_settled_in_d_cage.png` | D cage + plate STL |
| `07_all_receivers_b_c_d.png` | все зоны |
| `08_no_overlay_overlap.png` | overlay |
| `09_mobile.png` | mobile, no h-scroll |
| `10_details.png` | /details |
**Примечание:** auto-cam следует за **текущим** кейсом; для кадра «B в корзине» надёжнее смотреть фазу exit/clear case 1/8 или unit-тесты позы. Физика позы доказана тестом `y < 0.35` at 9200 ms.
---
## 9. Остаточные риски
- Browser warnings `THREE.Clock deprecated` — из three.js/r3f, не наш runtime log.
- `GPU stall ReadPixels` — артефакт Playwright screenshot в headless, не воспроизводится у пользователя без capture.
- Auto-cam может скрывать settled items в дальних зонах при смене кейса.
- 2 fallback кейса (`small_item_c`, `low_confidence`) — тяжёлые исходные STL.
---
## 10. Verdict
**ГОТОВО** для демо-защиты по performance + B physics.
- Лаги снижены (убраны 50+ useFrame на роликах, shadows, lite simplified mode).
- Console чистая (0 errors, 0 spam).
- B имеет физический bin на полу + путь transfer → chute → floor.
- B товар по модели в bin с exit phase, не на ленте (тесты).
- C/D containment сохранён.
- build/test/docker/production — OK.
---
## Build / deploy
```
npm run build → OK
npm run test → 137 passed
docker compose -p owl -f docker-compose.server.yml up -d --build → OK
curl -I arhipovdan.ru / details / ai-shorts.ru → 200
```