Hack Frontend Community

Server-Sent Events, Polling и Long Polling: что это и когда использовать

Что это вообще?

Все три технологии — способы получения данных с сервера в браузере. Они позволяют обновлять клиент в реальном или почти реальном времени, особенно при отсутствии WebSockets.


Polling (Обычный опрос)

Клиент периодически опрашивает сервер: «Есть что-то новенькое?»

Как работает polling:

  1. Клиент отправляет GET /data
  2. Сервер немедленно отвечает (даже если ничего не изменилось)
  3. Через X секунд клиент снова отправляет запрос
setInterval(() => {
  fetch('/data')
    .then(res => res.json())
    .then(data => console.log(data));
}, 5000); // Запрос каждые 5 сек

Минусы polling

  • Постоянная нагрузка на сервер (много "пустых" запросов)
  • Данные приходят с задержкой
  • Плохая масштабируемость

Long Polling (Длинный опрос)

Улучшенная версия обычного polling'а: запрос живёт до появления новых данных.

Как работает long polling:

  1. Клиент делает запрос
  2. Сервер ждёт появления данных (или истечения тайм-аута)
  3. Отдаёт данные → клиент сразу отправляет следующий запрос
function longPolling() {
  fetch('/data')
    .then(res => res.json())
    .then(data => {
      console.log(data);
      longPolling(); // Цикл продолжается
    });
}

longPolling();

Плюсы long polling

  • Меньше "пустых" запросов
  • Данные приходят почти мгновенно
  • Не требует новой технологии (работает по обычному HTTP)

Минусы long polling

  • Данные приходят с задержкой
  • Плохая масштабируемость

Server-Sent Events (SSE)

SSE — это постоянное соединение, по которому сервер отправляет данные клиенту, когда захочет.

Это однонаправленное соединение: только сервер → клиент

Как работает SSE

  • Клиент создаёт EventSource
  • Сервер устанавливает text/event-stream
  • Сервер может отправлять сообщения без запроса от клиента

Пример (Клиент)

const eventSource = new EventSource('/events');

eventSource.onmessage = (event) => {
  console.log("Новое сообщение:", event.data);
};

Пример (Сервер на Express)

app.get('/events', (req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');

  setInterval(() => {
    res.write(`data: ${JSON.stringify({ time: new Date() })}\n\n`);
  }, 3000);
});

Преимущества SSE

  • Простая реализация
  • Работает по одному соединению
  • Идеально для уведомлений, чатов, стриминга данных
  • Работает даже через прокси (поддерживает HTTP/2)

Сравнение

МетодНаправлениеПостоянное соединениеМгновенностьСложностьПоддержка
PollingClient → ServerНетНетПростаяВсе
Long PollingClient → ServerВременноПочтиСредняяВсе
SSEServer → ClientДаДаСредняяПочти все (кроме IE)

Что выбрать?

  • Polling: если нет возможности использовать другие методы или это не критично (например, обновление раз в 30 сек)
  • Long Polling: если данные должны приходить сразу, но вы не можете использовать SSE или WebSocket
  • SSE: для однонаправленного real-time (чаты, уведомления, ленты новостей)
  • WebSocket: для двусторонней связи — игры, коллаборативные редакторы, видеочаты, чаты, и т.д.

Вывод:

Polling — это просто, но неэффективно. Long Polling — компромисс. SSE — отличное решение для real-time без использования WebSocket. Выбор зависит от направления связи, нагрузки, требований к latency и браузерной поддержки.