Проектируем профессиональный фронт для мессенджера
- вторник, 3 марта 2026 г. в 00:00:04
Ранее я писал статью Пишем высокопроизводительный вьюпорт для мессенджера / Хабр В которой демонстрировалось создание простого вьюпорта для мессенджера и он не был основан на кроссплатформенном решении.

Перед тем как писать наш будущий мессенджер нужно определиться с технологией на которой будем его разрабатывать. Явными фаворитами среди инструментов web разработки для SPA являются Angular и React. Я не буду акцентировать преимущества каждого из этих инструментов, а остановлюсь сразу на Angular, т.к. ранее проводил ресёрч по неклассическим виртуализированным спискам и выявил, что для данной задачи он справится эффективнее, чем React.
Решение для построения неклассических виртуализированных списков на Angular ng-virtual-list и на React rcx-virtual-list (не реализовано до кроссплатформенного состояния, т.к. Angular лучше справляется с подобной задачей).
Сделаем вьюпорт групп открывающийся из дока.
Вьюпорт сообщений с разделением по дате создания.
Флоу редактирования и удаления сообщений.
Блок создания сообщений.
Поиск сообщений по подстроке.
Уникальный дизайн с темизацией.
Кроссбраузерное и кроссплатформенное решение.
Создаем новый проект Angular, в данном примере будем использовать 20.x версию. Добавляем пакет ng-virtual-list и настраиваем по описанию.
Сразу предоставлю исходный код проекта ng-virtual-list-chat-demo. Далее я буду останавливаться на ключевых моментах в коде репозитория, чтобы объяснить подробнее.
Проект функционирует полностью на моках, транспорт имплементируется с помощью mock-служб.
Службы
Служба для работы с группами сообщений groups-mock.service.ts. Реализует методы getGroups, createGroup, updateGroup и deleteGroup.
Служба для переключения чатов message.service.ts
Mock-служба для работы с сообщениями messages-mock.service.ts. Служба предоставляет функционал getMessages, createMessage, updateMessage, patchMessages и deleteMessage по указанному chatId.
Служба для работы с уведомлениями о создании новых сообщений (имитирует работу ws) messages-notification-mock.service.ts Реализует 2 Observable $typing (сигнализирует о наборе сообщения пользователем с заданным userId) и $messages (Сигнализирует о добавлении сообщения, в качестве значения передаёт версию изменений).
Служба темизации theme.service.ts
Служба локализации localization.service.ts. Важно отметить, что интерфейс "умеет" адаптироваться под языки с написанием right-to-left, например такие как иврит. За это отвечает директива locale-sensitive.directive.ts.
Основные компоненты
Основная страница мессенджера chat.component.ts
Компонент групп чатов groups.component.ts
Компонент вьюпорта сообщений messages.component.ts. Реализация коллекций основана на ProxyCollection. При получении "сырых" данных они переводятся в ProxyCollection<IMessageItemData>, которая при изменении формирует новый список элементов для <ng-virtual-list>
Важно отметить, что ng-virtual-list умеет кэшировать сообщения по типу, для чего введены такие типы элементов как typing-indicator, unmailed-separator, group, quote и message, которые рендерятся, как элементы определенного типа.
<ng-template #itemRenderer let-index="index" let-data="data" let-prevData="prevData" let-nextData="nextData" let-measures="measures" let-config="config" let-reseted="reseted"> <div staticClick [maxStaticClickDistance]="maxStaticClickDistance" class="message-template" (onStaticClick)="config.select(data.edited ? true : undefined)"> @if (data?.data) { @switch (data.data.type) { @case ("typing-indicator") { <x-messages-typing-indicator ... /> } @case ("unmailed-separator") { <x-message-unmailed-separator ... /> } @case ("group") { <x-message-group ... /> } @case ("quote") { <x-message-box [messageType]="'quote'"... /> } @default { <x-message-box ... /> } } } </div> </ng-template>
Компонент сообщения message-box.component.ts реализует функционал просмотра, выбора, редактирования и удаления. Компонент использует SVG визуализацию message-substrate.component.ts с различными визуальными эффектами и анимациями.
В проекте реализован ряд контролов @shared/components также основанных на SVG рендеринге. Такие как button, button-group, check-box, context-menu, dialog, drawer и базовый substrate.
Поиск сообщений по подстроке реализован средствами библиотеки ng-virtual-list, а подсветка подстроки с помощью директивы search-highlight.directive.ts.
В проекте реализован свой ResourceManager с политиками загрузки и кэширования изображений.
Дизайн элементов устроен с учетом анимации градиентных заливок.
Решение работает на любом браузере и любой платформе.
Demo: https://chat-demo.eugene-grebennikov.pro/

Demo ng-virtual-list: ng-virtual-list-examples
P.S.: Если понравился проект, ставьте звездочку ⭐ инструменту для работы с виртуализированными списками ng-virtual-list