System Design: frontend-вопросы
Frontend system design — жанр собеседований уровня senior/staff. Интервьюер хочет видеть системное мышление: компромиссы, масштабируемость, доступность, производительность. Типичные вопросы: image gallery, autocomplete, news feed, collaborative editor, design system.
Общий framework ответа
Независимо от задачи начинай с одного шаблона: уточни функциональные и нефункциональные требования (DAU, latency SLA, offline support, a11y), нарисуй компонентную схему (UI → State → API layer → cache), обсуди трейдоффы каждого решения. Интервьюер оценивает процесс мышления, а не схему.
- Functional requirements: что система делает
- Non-functional: latency, bandwidth, offline, accessibility
- Out of scope: что намеренно исключаем и почему
Image Gallery (Pinterest / Instagram)
Виртуализированная сетка через IntersectionObserver с динамическими высотами строк. Прогрессивная загрузка: blurhash placeholder → WebP → fullres. Prefetch следующей страницы при достижении 80% скролла. Состояние: нормализованный Map<id, image> + pages: id[][]. Кэш: service worker caches API-ответы + изображения; stale-while-revalidate для свежести.
- Virtualization: только видимые + overscan ±2 строки в DOM
- Images: srcset + sizes, lazy loading, LQIP/blurhash-placeholder
- Pagination: cursor-based (бесконечный скролл) vs offset (по номеру страницы)
- A11y: role=“list/listitem”, alt-тексты, focus management при роутинге
Autocomplete / Search-as-you-type
Три критичных вещи: дебаунс запросов (150–300 мс, trailing edge), отмена устаревших запросов через AbortController, кэш результатов (LRU Map<query, {results, ts}> с TTL). UI-паттерн: ARIA combobox (role=“combobox”, aria-expanded, aria-activedescendant). Оффлайн: кэшировать топ-1000 запросов в IndexedDB.
- Debounce: 150–300 мс, только после паузы в наборе
- Race conditions: AbortController или sequence counter — игнорировать устаревшие ответы
- Cache: LRU с TTL ~30 с; нормализация регистра запроса как ключ
- Keyboard: стрелки вверх/вниз, Enter — выбор, Escape — закрыть
News Feed (Twitter / Facebook)
Основные вызовы: infinite scroll с виртуализацией, real-time updates, optimistic UI для лайков/репостов, нормализованный стор. Структура данных: entities: Map<id, post>, feed: id[] (ordered by time). Новые посты — только при явном действии (“10 new posts”) — не прерывать чтение.
- Real-time: WebSocket (двусторонний) vs SSE (однонаправленный push) vs long polling
- Optimistic UI: временный id, rollback при ошибке API
- Virtualization: dynamic row heights (ResizeObserver), сохранять scroll при prepend
- Media: lazy video (IntersectionObserver), autoplay только в viewport
Real-time Collaborative Editor (Google Docs)
Самый сложный frontend system design. Алгоритмы: OT (Operational Transformation) или CRDT (Conflict-free Replicated Data Type — Yjs, Automerge). На собеседовании достаточно объяснить проблему конфликтов (два пользователя вставляют символ в одну позицию) и как OT трансформирует операции относительно друг друга. WebSocket для передачи операций, локальный cursor для немедленного отклика, сервер как арбитр порядка.
- Transport: WebSocket + reconnect с exponential backoff + queue pending ops
- Conflict resolution: OT (transform позицию) или CRDT (merge без конфликтов)
- Presence: курсоры других пользователей, throttle 50 мс на mousemove
- Offline: очередь pending ops в IndexedDB, sync при reconnect
Design System / Component Library
Вопрос про дизайн-систему проверяет понимание API design, versioning и доступности. Компонент должен иметь: Props API (минимальный, расширяемый через slots/children), Design Tokens (CSS custom properties), a11y (ARIA roles, keyboard nav, focus ring), theming (CSS variables предпочтительнее JS-in-CSS). Versioning: semantic versioning, breaking changes только в major, deprecation warnings за 2 минора до удаления.
- Tokens: color/spacing/typography в CSS custom properties — меняются без перекомпиляции
- Compound components: Context API для связи родитель↔дочерний (Select/Option)
- Bundle size: tree-shakeable named exports; CSS modules vs CSS-in-JS трейдоффы
- Testing: unit (logic), visual regression (Storybook/Chromatic), a11y (axe-core)
Итог: Framework: уточнить требования → компонентная схема → трейдоффы. Ключевые темы: виртуализация, real-time (WS/SSE), кэширование, доступность (ARIA).