WebTransport всех победит?

• dom, nodejs

Вступление

WebTransport
97
114
26.4

В Safari 26.4 вышла поддержка WebTransport, и теперь этот функционал доступен во всех основных браузерных движках. Апи появилось относительно давно, в 2022м году. Что же такого WebTransport привносит и чего не хватало в существующих апи? Давайте разбираться.

HTTP Polling

Один из старых (и всё ещё актуальных) способов узнать, есть ли что новое у сервера (или наоборот, способ передать свежие данные серверу).

В простом варианте (short polling) работает поверх обычных запросов – сделали запрос, получили ответ, подождали и начали снова. В чуть более сложном варианте (long polling) сервер не сразу закрывает соединение, а держит его активным, отправляя данные по мере надобности. Это позволяет избавиться от части запросов, когда новых данных нет.

Минусы – очевидные. Плохая производительность за счёт большого числа соединений и запросов, неудобное апи (в случае, если разбираем несколько отправок в одном запросе).

И всё же способ всё ещё актуален, особенно для интерфейса, который обновляется нечасто. Главное – следить за количеством клиентов, чтобы поллинг не обернулся пиком запросов в один момент времени на сервер от пачки пользователей.

EventSource

Древняя, и малоизвестная штука, поэтому пройдёмся по верхам.

Позволяет установить соединение с сервером по указанному урлу, и получать от него сообщения.

const source = new EventSource('/api/source');
 
source.addEventListener('message', event => ...);

Данные могут быть отправлены только в одну сторону – от сервера к клиенту.

Апи распространения не получило, так как WebSocket закрывает возможности с лихвой.

WebSocket

Апи примерно из тех же времён, что и EventSource, однако имеет один важный плюс: данные двунаправленные. Можно не только получать сообщения от сервера, но и отправлять их самому серверу!

С момента появления (около 2010 года) стал своего рода стандартом общения между браузером и сервером, если нам нужно передавать реалтаймовые данные. Простое апи в браузерах и хорошие реализации на сервере позволяют поднять всю конструкцию за короткое время:

const ws = new WebSocket('ws://...');
 
ws.on('message', event => ...);

Пожалуй, главной сложностью в настройке является всё же серверная (девопс / фронтопс) часть:

  • Нужно в принципе поддержать Upgrade запрос. Это связано с тем, что вебсокеты работают на своём протоколе, и для перехода на него с HTTP используется специальный механизм, который нужно поддержать на сервере.
  • Соединение не должно обрываться по таймауту. В случае неактивности некоторые серверы могут прибивать соединения. Чтобы этому противодействовать, нужно или правильно настроить сервер, или сделать механизм периодических “пингов” между клиентом и сервером, чтобы соединение считалось “живым” (актуально для прокси, которыми мы не управляем).

Начиная с версии 20.10, в Node.js добавился и клиент WebSocket, аналогичный браузеру. Тем самым одном Node.js приложение может общаться с другим., используя вебсокеты.

У вебсокетов есть понятный минус: транспорт использует TCP, и это приводит к тому, что сообщения приходят в гарантированном порядке, а с другой стороны, они приходят не так быстро, как могли бы. Для плохих соединений и некоторых задач это может быть критично.

WebRTC Data Channel

Помимо передачи аудио и видео через WebRTC, есть также возможность и передачи данных между пользователями, которая зовётся Data Channel. Основная цель – передача сообщений (messages) между пользователями, а не между браузером и сервером. Однако есть серверные библиотеки, которые позволяют выступить в роли “пользователя” WebRTC, тем самым можно организовать общение браузер-сервер.

Плюсом является также и то, что для Data Channel есть настройка ordered, которая влияет на то, будет ли подход больше походить на TCP (гарантированный порядок) или на UDP (быстрые запросы без ожидания). Кстати о последнем: в классическом UDP рекомендуется делать размер пакета меньше MTU (с учётом файерволов и дополнительных слоёв сети порядка 1200-1300 байт). В Data Channel есть аналогичные рекомендации – чем меньше, тем лучше (обычно указывают число в 16 КБ, но, как будто, механизм по итогу будет похож на обычный UDP).

Также отмечу, что Data Channel – двунаправленные, и позволяют посылать данные как в одну сторону, так и в другую.

WebTransport

Переходим к герою темы, к новому WebTransport. Он базируется на HTTP/3 и QUIC, и позволяет создавать одно- и двунаправленные потоки данных, в том числе с настройкой необходимости соблюдения порядка и доставки (аналог TCP) или без неё (аналог UDP). Соединение открывается между браузером и сервером.

АПИ построено поверх возможностей новых протоколов, и позволяет создавать неблокирующие друг друга потоки данных (в том числе с разным приоритетом). В первую очередь апи привносит возможность обмена данными без гарантии их порядка, что может значительно улучшить скорость доставки в условиях нестабильного соединения (например, мобильных сетей). В случае невозможности использовать QUIC под капотом WebTransport может переключиться на TCP и HTTP/2.

WebTransport выстроен вокруг современных объектов стримов, которые появились в браузерах и Node.js относительно недавно, а не вокруг сообщений (messages), как было в WebSockets. Прямое использование апи подразумевает выбор между datagrams (подобие UDP без гарантий) и uni- / bidirectional streams (доставка с гарантией, а-ля TCP).

Важным отличием от WebRTC Data Channel является максимальный размер сообщения. Если в Data Channel есть специальный механизм фрагментации сообщений, который позволяет их склеивать обратно, то в базе WebTransport datagrams лежат потоки, которые не подразумевают “склеивания”. Максимальный размер одного “куска” данных в таком потоке – MTU (а лучше, как мы помним, значение около 1200-1300 байт). Конечно, в случае разбиения сообщения на несколько пакетов эффективность негарантированной доставки в Data Channel снижается (так как нужно дождаться всех кусков, чтобы склеить), однако это может стать препятствием при применении WebTransport.

Текущий статус поддержки WebTransport

Если для вебсокетов есть известные пакеты, которые хорошо решают задачу на стороне Node.js, то в случае WebTransport есть примерно один более-менее известный пакет, который позволяет поднять HTTP/3 сервер: @fails-components/webtransport.

Пакет вышел не вчера, и вполне себе имеет стабильную версию, однако под MacOS у меня так и не заработал (видимо, готовлю неправильно). Тот же самый код под линуксом завёлся без проблем. WebTransport требует обязательного https, а с ним приезжают и дополнительные ограничения в разработке – обязательное наличие сертификатов (с определённым шифрованием и сроком жизни не более 14 дней!), запуск браузера со специальными параметрами для их обхода и так далее.

Ещё один большой вопрос – нативная поддержка в Node.js. По идее, она должна быть построена поверх HTTP/3 и QUIC. Однако ни того, ни того сейчас в Node.js нет. Базовая поддержка QUIC реализована, однако на момент февраля 2026го автор просит поддержки у сообщества для доделывания функционала до стабильного состояния. Когда (и если) в таких условиях появится нативная поддержка WebTransport – большой вопрос. Надежды на 2026 всё ещё есть.

Если говорить про серверы под другими языками программирования, то я слышал про реализации под C#, Python, Rust. О текущем статусе их судить не могу, не пробовал, возможно, за прошедшие годы они окрепли и их спокойно можно использовать в продакшене с большой нагрузкой.

Сравнение разных технологий

Приведу примерную таблицу для сравнения. EventSource за бортом, мне кажется, он давно неактуален. Также сразу скажу, что и гарантированная доставка, и негарантированная являются плюсами – просто для них разные области применения.

АПИНазначениеПорядок данных
ПоллингБраузер-СерверГарантированный
WebSocketБраузер-СерверГарантированный
WebRTC Data ChannelБраузер-Браузер, Браузер-Сервер*Гарантированный + Негарантированный
WebTransportБраузер-СерверГарантированный + Негарантированный

Чем ниже – тем, в теории, лучше. Однако под каждый проект можно выбрать соответствующую технологию:

Поллинг. Подойдёт для редких обновлений интерфейса, для которого не потребуется поддерживать постоянное соединение.

WebSocket. Старый и надёжный. Имеет понятные нюансы, с которыми за годы научились работать. Вероятно, самый простой вариант из WebSocket/Data Channel/WebTransport в настройке, и подойдёт для гарантированной доставки около реалтаймовых данных. Либо просто реалтаймовых, если вас устраивает.

WebRTC Data Channel. Имеет свою нишу в обмене данными между пользователями (peer-to-peer). Также, в теории, можно попробовать его для реалтаймового обмена данными с сервером, однако на практике я такого подхода не встречал и как он себя поведёт – сказать трудно. Этот случай интересен при условии, что вас не устраивает WebTransport (например, поддержкой).

WebTransport. Подойдёт как для быстрого обмена реалтаймовыми данными, так и для гарантированной доставки сообщений (например, в чате). Имеет вопросы по настройке (которые, я надеюсь, устаканятся). Можно сделать фолбек в сторону WebSocket.

Итого

Эволюция? Похоже на то. В местах, где разработчики годами привыкли использовать WebSocket, можно искать место для нового WebTransport. Главное – суметь справиться со всеми нюансами по пути.

В нише “реалтаймового” обмена данными с серверами, когда скорость критична, WebTransport и вовсе незаменим.

Дело за широким распространением технологии, а с ним и уверенность в использовании у разработчиков (и у меня) возрастёт.

Обсудить в Telegram

Почитать ещё посты

  • Origin API
  • Отслеживание поддержки фич
  • Navigation API реализован во всех браузерах
  • gesturechange и зум тачпадом на маках
  • Обзор TypeScript 6