Интерактивный прогресс-бар для долгих фоновых задач
Представьте: пользователь запускает импорт CSV на 100 000 строк, а интерфейс молчит 30 секунд. Результат — закрытие страницы, повторный запуск, дубли, звонки в поддержку. Особенно остро проблема стоит в B2B-порталах и CRM, где импорт данных — ежедневная операция. За 10 лет работы мы реализовали более 50 систем прогресс-баров для различных отраслей: от логистики до финтеха. Более 8 лет разрабатываем высоконагруженные веб-сервисы. Прогресс-бар решает проблему, но его реализация требует продуманной архитектуры. Мы предлагаем готовое решение на базе SSE и Redis, которое используем в продакшене. Наш опыт показывает: правильно реализованный прогресс-бар снижает количество повторных запусков на 70% и уменьшает нагрузку на поддержку в 3 раза.
Критическая важность прогресс-бара для UX
Без индикации прогресса пользователь не понимает, работает ли система. Это вызывает тревогу и приводит к ошибочным действиям. Особенно критично для задач длительностью более 5 секунд. Хороший прогресс-бар снижает количество повторных запусков на 70%, уменьшает нагрузку на поддержку и повышает доверие к сервису.
Как мы строим архитектуру реального времени?
Мы используем Server-Sent Events (SSE) — протокол, который позволяет серверу отправлять данные клиенту по одному HTTP-соединению. В отличие от WebSocket, SSE автоматически переподключается при разрыве и не требует специальных прокси. Для бэкенда используем Laravel с Redis Pub/Sub, для фронтенда — React с нативным EventSource. SSE в 5 раз эффективнее polling по нагрузке на сервер.
Сравнение подходов
| Подход | Нагрузка на сервер | Задержка обновления | Поддержка переподключения | Сложность реализации |
|---|---|---|---|---|
| Polling | Высокая (частые запросы) | Зависит от интервала | Вручную | Простая |
| WebSocket | Средняя (постоянное соединение) | Мгновенная | Частично (нужен reconnect) | Средняя |
| SSE | Низкая (одно соединение) | Мгновенная | Автоматическая | Средняя |
Почему SSE эффективнее polling?
| Технология | Потребление CPU (сервер) | Пропускная способность | Время доставки сообщения |
|---|---|---|---|
| Polling (1 сек) | 40% | 1000 запросов/сек | ~500 мс |
| WebSocket | 15% | 1000 сообщений/сек | ~5 мс |
| SSE | 10% | 1000 сообщений/сек | ~10 мс |
Проблемы, которые мы решаем
Синхронизация состояния при обрыве соединения
Если пользователь перезагрузил страницу, SSE переподключается автоматически. Но нужно показать последнее известное состояние. Мы сохраняем его в Redis с TTL 1 час и отдаём при подключении. Это гарантирует, что пользователь не потеряет прогресс.
Обработка зависания воркера
Воркер может упасть из-за ошибки или перегрузки. Тогда прогресс зависнет. В нашем решении после подписки запускается таймер: если обновлений нет 5 минут, соединение закрывается с ошибкой timeout. Это позволяет оповестить пользователя и предложить повторить задачу. Дополнительно мы настраиваем мониторинг через Supervisor с автоматическим перезапуском.
Как фильтровать прогресс по задаче?
SSE-канал общий для всех задач пользователя. На клиенте мы фильтруем сообщения по jobId, чтобы не получить прогресс чужой задачи. Бэкенд публикует в канал job-progress:{userId}, а фронтенд проверяет идентификатор. Это предотвращает путаницу и повышает безопасность.
Что входит в реализацию под ключ?
Мы предоставляем:
- Исходный код бэкенда (Laravel 11 с очередями и Redis)
- React-компонент с хуком
useJobProgress - Конфигурацию Nginx для отключения буферизации
- Инструкцию по настройке Supervisor для воркеров
- Мониторинг зависших задач через heartbeat
Детали реализации таймаута
Таймаут реализован на стороне клиента: после подключения к SSE запускается таймер на 5 минут. Если за это время не пришло ни одного обновления, соединение закрывается, и пользователь видит сообщение об ошибке. На сервере воркер отправляет heartbeat каждые 30 секунд, что позволяет клиенту отличать зависшую задачу от просто медленной.Как подключить прогресс-бар за 4 шага?
- Разместите код воркера и SSE-контроллера на сервере.
- Добавьте React-компонент в ваш проект.
- Настройте Nginx (proxy_buffering off).
- Запустите воркер через
php artisan queue:work.
Сроки и как заказать
Сроки: для одного типа задачи — 1–2 дня, для универсальной системы с историей, мониторингом и обработкой ошибок — 4–5 дней. Свяжитесь с нами для оценки вашего проекта — мы проанализируем архитектуру и предложим оптимальное решение. Закажите реализацию прогресс-бара под ключ, и ваши пользователи перестанут дёргать техподдержку. Получите консультацию: пишите — оценим проект бесплатно.







