textStream() и стриминг HTML в Chrome — новый API
JavaScript API · Июнь 2026

textStream() и стриминг HTML
в Chrome

Chrome Canary представляет textStream() и набор методов потокового DOM, которые меняют подход к передаче HTML из fetch() на страницу. Разберём, как они работают и когда их применять.

Олег Максимов 17 июня 2026 10 мин чтения

Зачем нужен стриминг HTML

Стриминг — один из самых эффективных паттернов производительности в вебе. Вместо ожидания полной загрузки ресурса браузер обрабатывает данные инкрементально — отображая контент по мере поступления. Новые методы потокового DOM в Chrome Canary встраивают эту возможность непосредственно в слой DOM API.

Раньше для стриминга HTML на страницу требовалась ручная оркестровка: разбор байтового потока из response.body, пропускание через TextDecoderStream и ручное добавление фрагментов в DOM. Новые API устраняют большую часть этого boilerplate-кода.

textStream(): основа нового API

Метод textStream() доступен на объектах Response и Blob. Он возвращает ReadableStream строковых фрагментов, декодированных из байтового потока как UTF-8 текст.

До textStream()

Чтобы получить текстовый поток из fetch(), нужно было вручную пропустить его через декодер:

const response = await fetch('/partial.html');
const decoder = new TextDecoderStream();
const textStream = response.body.pipeThrough(decoder);

const reader = textStream.getReader();
// ... ручное чтение фрагментов и вставка в DOM

С textStream()

Вся цепочка сворачивается в один вызов:

const response = await fetch('/partial.html');
const textStream = response.textStream();

// textStream — ReadableStream строковых фрагментов
// Готов к передаче в методы потокового DOM

textStream() эквивалентен пропусканию байтового потока через UTF-8 TextDecoderStream — но без настройки. Он также работает с Blob:

const blob = new Blob(['<h1>Привет</h1><p>Мир</p>']);
const stream = blob.textStream();
// Используйте тот же паттерн потока

Методы потокового DOM

Chrome Canary добавляет 12 новых методов на Element, которые принимают текстовый поток и рендерят его в DOM инкрементально. Они разделены на две категории: safe (всегда санитизируют) и unsafe (без санитизации по умолчанию).

Safe-методы потока

Эти методы всегда очищают HTML, удаляя скрипты и потенциально опасные элементы:

Unsafe-методы потока

Эти методы не санитизируют по умолчанию, но принимают опции с sanitizer и/или runScripts:

Ключевое различие

Пример: потоковый чат

const feed = document.getElementById('chat-feed');

async function streamMessages() {
  const response = await fetch('/api/chat/stream');
  await response.textStream()
    .pipeTo(feed.streamAppendHTML());
}

// Каждый фрагмент HTML с сервера отображается
// немедленно как новое сообщение в ленте

Сравнение с не-потоковыми методами

Вместе с потоковыми методами Chrome также вводит не-потоковые аналоги для замены устаревших DOM API. Полная картина:

Устаревший метод Новый (не-потоковый) Stream Safe Stream Unsafe
innerHTML устар. setHTMLUnsafe новый streamHTML safe streamHTMLUnsafe unsafe
outerHTML устар. replaceWithHTMLUnsafe новый streamReplaceWithHTML safe streamReplaceWithHTMLUnsafe unsafe
insertAdjacentHTML(beforeend) устар. appendHTMLUnsafe новый streamAppendHTML safe streamAppendHTMLUnsafe unsafe
insertAdjacentHTML(afterbegin) устар. prependHTMLUnsafe новый streamPrependHTML safe streamPrependHTMLUnsafe unsafe
insertAdjacentHTML(beforebegin) устар. beforeHTMLUnsafe новый streamBeforeHTML safe streamBeforeHTMLUnsafe unsafe
insertAdjacentHTML(afterend) устар. afterHTMLUnsafe новый streamAfterHTML safe streamAfterHTMLUnsafe unsafe

Новые не-потоковые методы с Unsafe — прямая замена устаревшим. Они отличаются от старых API в двух важных аспектах:

Safe-методы: setHTML и streamHTML

Безопасный не-потоковый метод setHTML и его потоковый аналог streamHTML используют Sanitizer API под капотом. Это тот же механизм, что и у класса Sanitizer: удаление скриптов, обработчиков событий и другого опасного контента при сохранении безопасной разметки.

Декларативные частичные обновления

Один из самых интересных сценариев — декларативные частичные обновления. Паттерн сочетает элементы <template> с серверными инструкциями обработки для обновления конкретных секций страницы без JavaScript-селекторов.

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

Сервер передаёт HTML, содержащий <template for="имя">. Исходная страница использует инструкции <?marker name="имя">:

<!-- Исходная разметка страницы -->
<main>
  <?marker name="main-content">
</main>
<aside>
  <?marker name="sidebar">
</aside>

Сервер отвечает определениями шаблонов:

<template for="main-content">
  <article>
    <h1>Руководство по стримингу HTML</h1>
    <p>Контент загружается постепенно...</p>
  </article>
</template>
<template for="sidebar">
  <div class="widget">
    <h3>Связанные темы</h3>
    <ul>...</ul>
  </div>
</template>

Потоковая передача соединяет их:

const response = await fetch('/page-with-partials.html');
await response.textStream()
  .pipeTo(document.body.streamAppendHTMLUnsafe());

При использовании safe-методов помните, что <template> удаляются при санитизации. Чтобы их сохранить, передайте пустой конфиг санитайзера:

await response.textStream()
  .pipeTo(document.body.streamAppendHTML({sanitizer: {}}));

Атрибуты for и name определяют, какой template заменяет какой маркер — без querySelector и ручного присваивания.

Выполнение скриптов в потоковом HTML

Если потоковый HTML содержит <script>, которые должны выполниться, используйте unsafe-метод с опцией runScripts:

const response = await fetch('/dynamic-widget.html');
await response.textStream()
  .pipeTo(
    document.body.streamAppendHTMLUnsafe({runScripts: true})
  );

Это осознанное проектное решение — safe-методы никогда не выполняют скрипты, а unsafe требуют явного согласия. Это предотвращает XSS-уязвимости даже при использовании unsafe-семейства.

Поддержка браузеров

На июнь 2026 года textStream() и методы потокового DOM доступны только в Chrome Canary. Они ещё не вышли в Chrome Stable, и нет сигналов от Firefox или Safari о планах по реализации.

Сводка по браузерам

Для продакшена используйте не-потоковые аналоги или полифиллы. Потоковые API идеальны для экспериментов, прогрессивного улучшения и подготовки к будущей поддержке браузеров.

Практические сценарии

💬

Чат / Комментарии

Потоковая вставка новых сообщений в DOM по мере поступления с сервера — без WebSocket-обработчиков для рендеринга.

📊

Виджеты дашбордов

Загрузка компонентов дашборда прогрессивно — каждый виджет рендерится по мере поступления HTML-чанка.

📝

Серверные частичные обновления

Обновление секций страницы с сервера без клиентской маршрутизации и управления состоянием.

🔌

Стриминг WYSIWYG контента

Передача серверного форматированного текста (markdown, ProseMirror) непосредственно в область контента.

Миграция

Если вы сейчас используете innerHTML или insertAdjacentHTML для вставки HTML из fetch(), вот путь миграции:

  1. Начните с не-потоковых замен — замените innerHTML на setHTMLUnsafe (или setHTML для санитизированного контента). Они работают сегодня и не требуют стриминга.
  2. Добавляйте стриминг по необходимости — для длинных ответов (чат, дашборды, частичные обновления) переходите на textStream().pipeTo(element.streamAppendHTML()).
  3. Всегда используйте safe-методы для непроверенного контента — пользовательский HTML должен проходить через safe-методы. Встроенный санитайзер автоматически удаляет XSS-векторы.

FAQ

Что такое textStream() в JavaScript?
textStream() — это новый метод объектов Response и Blob, возвращающий поток текстовых фрагментов (ReadableStream строк). Это аналог ручного пропускания байтового потока через TextDecoderStream, но с одним вызовом метода вместо цепочки операций. Это значительно упрощает получение потокового HTML из fetch().
Какие методы стриминга DOM доступны в Chrome Canary?
Chrome Canary предлагает 12 новых методов: streamHTML, streamReplaceWithHTML, streamAppendHTML, streamPrependHTML, streamBeforeHTML, streamAfterHTML и их Unsafe-варианты. Safe-методы санитизируют HTML по умолчанию; Unsafe — нет, но могут опционально использовать санитайзер или разрешать скрипты через опции.
В чем разница между safe и unsafe методами стриминга?
Safe-методы (streamHTML, streamAppendHTML и др.) всегда очищают HTML, удаляя скрипты и потенциально опасные элементы. Unsafe-варианты (streamHTMLUnsafe, streamAppendHTMLUnsafe и др.) не санитизируют по умолчанию, но могут опционально использовать санитайзер или разрешать выполнение скриптов через {runScripts: true}. Для пользовательского контента всегда используйте safe-методы.
Чем textStream() отличается от response.text()?
response.text() возвращает весь ответ целиком как строку, буферизируя всё в памяти перед разрешением промиса. textStream() возвращает ReadableStream строковых фрагментов, позволяя обрабатывать HTML инкрементально — начинать рендеринг контента до полной загрузки ответа. Это уменьшает время до первого байта и улучшает воспринимаемую производительность.
Что такое декларативные частичные обновления со стримингом HTML?
Это паттерн, при котором сервер присылает элементы <template for="имя"> в потоке HTML, а страница содержит инструкции обработки <?marker name="имя">. При стриминге в document.body содержимое каждого template автоматически заменяет соответствующий маркер по имени — без querySelector и клиентской маршрутизации.
Какие браузеры поддерживают textStream() и методы стриминга DOM?
На июнь 2026 года textStream() и методы стриминга DOM поддерживаются исключительно в Chrome Canary. Это экспериментальные функции, ещё не доступные в Chrome Stable, Firefox, Safari или других браузерах. Edge будет следовать за графиком Chrome после стабилизации API.
Можно ли выполнять скрипты в потоковом HTML?
Да, но только через unsafe-методы с явным флагом: streamAppendHTMLUnsafe({runScripts: true}). Safe-методы никогда не выполняют скрипты, а unsafe-методы требуют явного согласия — это продуманная мера безопасности, предотвращающая XSS-уязвимости даже при использовании небезопасного код-патча.

Заключение

textStream() и методы потокового DOM — значительный шаг вперёд для манипуляции DOM. Объединяя примитивы стриминга из Streams API с прямой вставкой в DOM, Chrome делает создание страниц с прогрессивной загрузкой и реактивными обновлениями значительно проще.

Пока это экспериментальные API, доступные только в Chrome Canary. Но паттерны, которые они вводят — декларативные частичные обновления, безопасная по умолчанию санитизация и стриминг как первоклассная концепция — вероятно, повлияют на будущее веб-разработки во всех браузерах.

Если вы создаёте веб-приложение с обновлениями в реальном времени, прогрессивной загрузкой или серверным частичным рендерингом, эксперименты с этими API сегодня подготовят вас к тому, куда движется платформа.

Контакты

Нужна помощь с современными веб-API?

Создаёте приложение со стримингом, обновлениями в реальном времени или прогрессивной загрузкой? Могу помочь с архитектурой и реализацией. Бесплатная консультация.