Спроектируйте компонент поиска с автодополнением (autocomplete) для крупного сайта: API, состояние, производительность, доступность.
Короткий ответ
- Уточнить требования: источники данных, объёмы, платформы
- Debounce ввода и минимальная длина запроса
- Отмена устаревших запросов через AbortController
- Кэш последних запросов и мгновенный показ из кэша
- Состояния: пусто, загрузка, результаты, ошибка, «ничего не найдено»
- Клавиатурная навигация и ARIA-паттерн combobox
- Метрики: задержка подсказок, CTR по подсказкам
Автодополнение — это управление потоком запросов (debounce, отмена, кэш), честная обработка всех состояний UI и доступность по паттерну combobox, а не просто инпут с выпадашкой.
Как сказать вслух
пример ответаЯ бы начал с требований: откуда данные, сколько пользователей, нужна ли история запросов и работа с клавиатуры. Дальше ключевая механика: запросы шлём не на каждую букву, а с debounce и начиная с двух-трёх символов; каждый новый запрос отменяет предыдущий, иначе старый ответ может прийти позже и перезатереть свежие подсказки. Добавляю кэш последних запросов — повторный ввод показывает результат мгновенно. Отдельно проектирую состояния интерфейса — загрузку, пустой результат, ошибку — и доступность: управление стрелками и корректные ARIA-атрибуты.
Подробный ответ
Основной ответ
Архитектура: контролируемый инпут, слой запросов и выпадающий список как отдельные части. Поток данных: ввод → debounce 150–300 мс → проверка минимальной длины → запрос с AbortController, отменяющий предыдущий, → нормализация ответа → рендер. Гонки — главный источник багов: кроме отмены, стоит сверять, что ответ соответствует текущему тексту инпута. Кэш (Map запрос → результаты с TTL, LRU на несколько десятков записей) даёт мгновенные подсказки при повторном вводе и навигации назад. Состояния UI перечисляются явно: idle с историей или популярными запросами, loading без дёргания интерфейса (не скрывать старые результаты, а приглушать), success, empty с подсказкой, error с повтором. Доступность — паттерн WAI-ARIA combobox: role=combobox на инпуте, aria-expanded, aria-activedescendant для виртуального фокуса, список role=listbox; стрелки, Enter, Escape с клавиатуры. Производительность: при больших списках — виртуализация; подсветку совпадений делать безопасно, без innerHTML с сырым текстом (XSS). На бэкенд-стороне обсуждаю формат API: лимит подсказок, ранжирование, передача выделяемых диапазонов.
Ключевые моменты
- Гонки запросов. Отмена предыдущего запроса и сверка ответа с текущим вводом — без этого подсказки перезатираются устаревшими данными.
- Поток ввода. Debounce, минимальная длина и кэш сокращают нагрузку на порядок и ускоряют отклик.
- Состояния UI. Пять состояний проектируются явно; «ничего не найдено» и ошибка — не меньшая часть UX, чем успех.
- Доступность. Combobox-паттерн с клавиатурной навигацией — стандарт для продакшена, его отсутствие заметит и пользователь, и интервьюер.
Практический контекст
Один из самых популярных вопросов фронтенд system design: компактный, но вскрывает работу с асинхронностью, состоянием, сетью и a11y сразу. Интервьюер смотрит на структуру рассуждения: уточнение требований, проговаривание trade-off-ов (задержка debounce против отзывчивости, кэш против свежести), а не на единственно верный ответ. Хорошо сослаться на опыт: что ломалось в реальном поиске и как чинили.
Частые ошибки
- Сразу рисуют компоненты, не уточнив требования и объёмы
- Забывают про гонки запросов — самый ожидаемый пункт ответа
- Игнорируют клавиатурную навигацию и ARIA, ограничиваясь «выпадашкой по клику»