---
title: "Оптимизация производительности"
description: "Производительность во время деплоя и выполнения для Ring Platform — кеширование React 19, инвалидирование списков, Web Vitals и подводные камни в продакшене"
locale: "ru"
---
# Оптимизация производительности

> **Info**
> Воспользуйтесь фильтрами **Founder** / **Developer** в боковой панели документации. Эта страница замещает устаревшие вымышленные сведения (например, `$2.8M дохода`, выдуманные примеры отчетности, фиктивные SLA Lighthouse). Описанные паттерны подтверждены в файлах `next.config.mjs`, `lib/cached-data.ts`, `components/providers/web-vitals-provider.tsx`, `features/analytics/lib/analytics-db.ts` и опыте продакшн-Docker.

Платформа Ring ориентирована на **быструю первую отрисовку** (по умолчанию серверные компоненты React 19), **актуальные списки маркетплейса** (теги кеша + синхронизация после мутаций) и **измеряемый UX** (сбор Core Web Vitals). Производительность — это задача деплоя: ограничения по времени сборки, ловушки SSR и инвалидирование кеша, а не только косметика фронтенда.

## Стек производительности (подтверждено)

| Слой                 | Механизм                                               | Где используется                                   |
|----------------------|-------------------------------------------------------|----------------------------------------------------|
| **Фреймворк**        | Next.js 16 App Router, `cacheComponents: true`         | `next.config.mjs`                                  |
| **Кеш списков**      | `unstable_cache` + `revalidateTag`                    | `lib/cached-data.ts`                               |
| **Дедупликация чтения** | `React.cache()` для server reads                   | `lib/services/firebase-service-manager.ts`, actions |
| **Read-after-write** | 30 сек. in-process кеш сущностей                      | `DatabaseService` `EntityCache`                    |
| **Тяжелый UI-клиент**| `dynamic(..., { ssr: false })`                        | `components/docs/mdx-heavy-components.tsx`          |
| **Блоки кода Docs**  | Серверный Shiki (`highlightCodeToHtml`)               | `components/docs/code.tsx`                         |
| **Изображения**      | `next/image` WebP/AVIF                                | `next.config.mjs` → `images.formats`               |
| **UX-метрики**       | `useReportWebVitals` → POST `/api/analytics/web-vitals` | `components/providers/web-vitals-provider.tsx`, `features/analytics/lib/analytics-db.ts` |
| **Hints ресурсов**   | `prefetchDNS` / `preinit` скрипты                     | `contexts/app-context.tsx`                         |

### For founders

## Почему производительность критична для вашего клона

Медленные страницы **opportunity** и **store** прямо влияют на конверсию: пользователи бросают покупки, продавцы видят пустые дашборды, а уведомления AI выглядят «запаздывающими», даже если данные корректны.

### Что может оптимизировать фаундер без кода

  
- **[Сначала измеряйте](/docs/deployment/monitoring.md)** — Админ → **Аналитика** показывает медианы Web Vitals и ошибки клиента — зафиксируйте текущий уровень до смены бренда или добавления тяжёлых медиа.

  
- **[Дисциплина изображений](/docs/features/store.md)** — Продуктовые и сущностные изображения — только через Blob/CDN-URL и `next/image`. Оверсайз PNG-герои — частая причина LCP-регрессий в новых клонах.

  
- **[Актуальность списков](/docs/architecture/discovery-mutation-sync.md)** — После публикации товаров продавцами кеш должен инвалидироваться. Если списки выглядят устаревшими — чините синхронизацию до масштабирования.

  
- **[Сокращение локалей](/docs/features/locale-system.md)** — Меньше активных локалей (`NEXT_PUBLIC_SUPPORTED_LOCALES`) = меньше сборки и статических параметров на деплой.

### Цели Web Vitals (пороговые значения Google)

| Метрика | Хорошо (≤) | Плохо (>) |
|---------|-------------|-----------|
| **LCP** | 2.5s        | 4s        |
| **INP** | 200мс       | 500мс     |
| **CLS** | 0.1         | 0.25      |
| **TTFB**| 800мс       | 1.8s      |
| **FCP** | 1.8s        | 3s        |
| **FID** | 100мс       | 300мс     |

Значения берутся из `ratingForMetric` в `features/analytics/lib/analytics-db.ts`. Клиент сообщает рейтинг каждой метрики из `next/web-vitals`, буферизует и отправляет одним POST за debounce в `/api/analytics/web-vitals`.

> **Tip**
> Рассматривайте производительность как **критерий релиза** при запуске клона: запустите Lighthouse на `/`, `/opportunities` и `/store` после деплоя и сравните c Admin-аналитикой через неделю.

### For developers

## Кеширование и актуальность данных

```mermaid
sequenceDiagram
    participant Page as RSC list page
    participant UC as unstable_cache
    participant DB as DatabaseService
    participant Mut as create/update service
    participant Sync as sync*Discovery
    Page->>UC: getCachedOpportunitiesForRole
    UC->>DB: query (on miss)
    Mut->>DB: write
    Mut->>Sync: revalidateTag + revalidatePath
    Sync->>UC: tags busted — next request refetches
```

### Ролевой кеш списков

{`export const getCachedOpportunitiesForRole = (roleKey: UserRolesArray) =>
  unstable_cache(
    async (limit = 20, startAfter?: string) =>
      getOpportunitiesForRole({ userRole: roleKey, limit, startAfter }),
    ['opportunities-list', roleKey],
    { tags: ['opportunities-list', \`opportunities-role-\${roleKey}\`] },
  )

export function invalidateOpportunitiesCache(roleKeys: string[] = []) {
  revalidateTag('opportunities-list', 'max')
  for (const role of roleKeys) revalidateTag(\`opportunities-role-\${role}\`, 'max')
}`}

Этот паттерн используется также для сущностей (`getCachedEntitiesForRole` / `invalidateEntitiesCache`) и админских новостных агрегатов (`invalidateNewsStatsCache`).

Сервисы мутаций вызывают `syncOpportunityDiscovery` / `syncEntityDiscovery` — см. [Синхронизация после мутаций Discovery](/docs/architecture/discovery-mutation-sync.md). **Никогда** не кешируйте пути записи: всегда инвалидируйте кеш после CRUD.

### Дедупликация серверных чтений

Оборачивайте тяжелые серверные fetch в `cache()` из `react`, чтобы параллельные серверные компоненты делили один запрос к БД (см. `getCachedDocument` в `lib/services/firebase-service-manager.ts`).

### Read-after-write (30 секунд)

`DatabaseService` имеет короткоживущий `EntityCache` (TTL 30 сек), чтобы новые сущности были видны в ближайших запросах в пределах одного процесса — это **не** замена для `revalidateTag`.

## Паттерны React 19 в продакшне

| Паттерн                          | Где смотреть пример                          |
|----------------------------------|---------------------------------------------|
| `useActionState`                 | `features/reviews/components/review-form.tsx`     |
| `useOptimistic`                  | `hooks/use-realtime.ts`, `hooks/use-realtime-opportunities.ts` |
| Server Actions + `revalidatePath`| `app/_actions/*.ts`                         |

Используйте Server Components для list/detail-оболочек; ограничивайте `'use client'` лишь формами, туннелями, кошельками и визуализациями.

## Подводные камни при сборке и деплое

### Не SSR тяжелые визуализации на сервере

Документация и маркетинговые виджеты подгружаются через `dynamic(..., { ssr: false })` в `mdx-heavy-components.tsx`. Серверный рендеринг Mermaid/Shiki на верхнем уровне приводил к **30-секундным задержкам и 503** в продакшене — см. [Развертывание в Docker](/docs/deployment/docker.md).

### Блоки `` асинхронно обрабатываются на сервере через Shiki

`components/docs/code.tsx` вызывает `highlightCodeToHtml` один раз на блок — не добавляйте на той же странице клиентские highlighter'ы.

### Таймаут сборки

`staticPageGenerationTimeout: 180` в `next.config.mjs` — большие деревья документации или множество локалей требуют дисциплины в инкрементальной генерации; уменьшайте область сканирования в `scanDocsStaticParams`, если сборка не влазит в лимиты CI.

### Standalone-вывод

В `next.config.mjs` выставляется `output: 'standalone'` с `outputFileTracingRoot`, `serverExternalPackages` (Firebase, Auth.js, Solana, nodemailer), и `outputFileTracingIncludes` (i18n, локали, docs, ring-config, server.ts), чтобы контейнеры включали только нужные бандлы сервера.

### Оптимизация изображений

`next.config.mjs` включает WebP/AVIF (`images.formats`) и remote patterns для Google-аватаров, Google Fonts, Vercel Blob и `cdn.ring-platform.org`, а также паттерны для каждого нового клона через `collectCloneImageRemotePatterns`. Добавляйте хосты CDN в `images.remotePatterns` при подключении клона.

### Измерение регрессий

- **Сбор:** `WebVitalsProvider` (`components/providers/web-vitals-provider.tsx`), встраивается в `app-client-shell.tsx`
- **Хранилище:** миграция `017_ring_analytics_schema.sql`
- **Запрос:** аналитика Admin или `GET /api/analytics/web-vitals?scope=platform` (admin)
- **Отключить запись:** `ANALYTICS_DISABLE_STORAGE=true` для нагрузочного тестирования

Полная справка: [Мониторинг и аналитика](/docs/deployment/monitoring.md).

### Более подробное руководство для разработчика

Паттерны реализации (Firebase `cache()`, статическая генерация, edge-заметки) смотрите в разделах [Разработка: производительность](/docs/development/performance.md) и [Возможности: паттерны производительности](/docs/features/performance.md) — сверяйте примеры с postgres-клонами перед использованием firebase-специфичного кода.

## Связанная документация

  
- [deployment/monitoring](/docs/deployment/monitoring.md) — Следующее: health-checkи, Web Vitals API и админ-аналитика.

  
- [deployment/docker](/docs/deployment/docker.md) — Схожие сценарии: история инцидентов Mermaid SSR и probes.

  
- [architecture/discovery-mutation-sync](/docs/architecture/discovery-mutation-sync.md) — Глубже: инвалидирование кеша после CRUD тегов или возможностей.

  
- [development/performance](/docs/development/performance.md) — Также смотрите: паттерны cache(), статическая генерация, заметки по edge.
