Ответ вслух Middle System design на фронте спрашивают часто обновлено

Спроектируй ленту новостей

Вопрос

Спроектируй фронтенд ленты новостей как во «ВКонтакте»: посты с текстом и фото, лайки, комментарии, бесконечный скролл, новые посты появляются сверху. Пройди этапы: требования, оценка нагрузки, API, данные, компоненты, узкие места.

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Начинаю с требований: смотреть ленту, лайкать, открывать комментарии, видеть новые посты. Нефункционально: быстрый первый экран на мобильных, доступность, лента за логином, поэтому SEO не важен.

Что должно прозвучать в ответе

  • Требования: просмотр, лайк, комментарии, новые посты, медиа; нефункциональные: быстрый первый экран, мобильные, доступность, SEO не нужен (за логином)

  • Оценка: сотни и тысячи постов за сессию, фото тяжёлые, частота новых постов, слабые телефоны

  • API: GET /feed с курсором, POST like, новые посты через SSE или поллинг с плашкой «N новых»

  • Данные: нормализованные посты и авторы по id, лента как массив id, кеш в TanStack Query

  • Компоненты: FeedList с виртуализацией, PostCard, LikeButton с оптимистичным обновлением, Comments лениво

  • Узкие места: виртуализация, IntersectionObserver, lazy и srcset для фото, сохранение позиции скролла, откат лайка при ошибке

Что могут спросить следом

  • Как сохранить позицию скролла при возврате на ленту?
  • Почему не вставлять новые посты сразу сверху?
  • Как не потерять лайк без сети?

Разбор

Начинаю с требований: смотреть ленту, лайкать, открывать комментарии, видеть новые посты. Нефункционально: быстрый первый экран на мобильных, доступность, лента за логином, поэтому SEO не важен. По масштабу пользователь листает сотни постов, фото тяжёлые, устройства слабые, значит, нужна виртуализация и экономия трафика. API: GET /feed с курсором и limit, потому что offset даёт дубли при вставке новых постов; POST лайка; о новых постах сервер сообщает через SSE, а я показываю плашку «5 новых», а не вставляю их, чтобы не дёргать контент под пальцем. Данные храню нормализованно: посты и авторы по id, лента как список id, всё в TanStack Query с infinite query. Компоненты: FeedList с виртуализацией через TanStack Virtual, PostCard, LikeButton с оптимистичным обновлением и откатом, комментарии грузятся лениво. Узкие места: картинки через srcset и loading lazy с заданными размерами против CLS, подгрузка следующей страницы заранее через IntersectionObserver, восстановление позиции скролла при возврате, обработка офлайна.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.