0Pricing
Vue Academy · Урок

Потоковый SSR с renderToWebStream

renderToWebStream() и renderToString(), потоковая передача HTTP, улучшение TTFB и отправка фрагментов

«Потоковый SSR с renderToWebStream» — бесплатный урок Vue Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Vue Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Vue Academy содержит 4 уроков всего.

От renderToString к потоковой передаче

Классическая SSR использует renderToString, которая полностью создаёт HTML в памяти, прежде чем отправить хотя бы один байт. Браузер бездействует в ожидании, пока вся страница не будет готова.

Потоковая SSR отправляет HTML фрагментами по мере отрисовки приложения, поэтому браузер начинает разбирать его раньше.

Основы renderToWebStream

Серверный модуль Vue предоставляет функции потоковой передачи. renderToWebStream возвращает ReadableStream (API веб-потоков), а renderToNodeStream/pipeToNodeWritable работают с интерфейсом потоков Node.

Каждый фрагмент отправляется по мере разрешения дерева компонентов.

import { renderToWebStream } from 'vue/server-renderer'
import { createSSRApp } from 'vue'
import App from './App.vue'

const app = createSSRApp(App)
const stream = renderToWebStream(app)

Передача потока в HTTP-ответ

На сервере Node поток передаётся в ответ. С помощью pipeToNodeWritable данные записываются непосредственно в доступный для записи объект res, а фрагменты отправляются по мере их создания.

import { pipeToNodeWritable } from 'vue/server-renderer'

server.get('*', (req, res) => {
  const app = createSSRApp(App)
  res.write('<!DOCTYPE html><html><body><div id="app">')
  pipeToNodeWritable(app, {}, res)
})

Потоковая передача в веб-среде и на периферии

В периферийных средах выполнения (Workers, Deno, Bun) возвращается объект HTTP-ответа, созданный непосредственно из веб-потока. Потоки Node не используются.

import { renderToWebStream } from 'vue/server-renderer'

export default async function handler(request) {
  const app = createSSRApp(App)
  const stream = renderToWebStream(app)
  return new Response(stream, {
    headers: { 'Content-Type': 'text/html' }
  })
}

Как фрагменты достигают браузера

По мере отрисовки узлов Vue помещает сериализованные строки HTML в поток. Уровень HTTP немедленно отправляет эти байты. Инкрементальный анализатор HTML в браузере отображает видимое содержимое ещё до завершения ответа.

Поэтому пользователь видит заголовок и макет, пока тело страницы всё ещё передаётся потоком.

TTFB: главный показатель

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

При использовании renderToString TTFB включает всё время отрисовки. При потоковой передаче первый фрагмент покидает сервер почти сразу, что значительно уменьшает TTFB и улучшает воспринимаемую скорость.

// renderToString: client waits for full HTML
const html = await renderToString(app) // blocks
res.end(fullPage(html))

// streaming: first bytes flush right away
pipeToNodeWritable(app, {}, res) // non-blocking chunks

Обёртывание потока HTML-разметкой макета

Обычно оболочку документа (<head>, открывающие теги) нужно отправить до потока приложения, а закрывающие теги — после него. Запишите префикс, передайте поток приложения, а затем запишите суффикс после завершения потока.

res.write('<!DOCTYPE html><head><title>App</title></head>')
res.write('<body><div id="app">')

pipeToNodeWritable(app, ctx, {
  write: (chunk) => res.write(chunk),
  end: () => res.end('</div></body></html>')
})

Обработка ошибок во время потоковой передачи

После отправки байтов изменить код состояния HTTP уже нельзя. Обрабатывайте ошибки отрисовки с помощью параметра onError (или через путь обработки ошибок доступного для записи объекта). Для критических ошибок, обнаруженных заранее, предпочтительнее непотоковая отрисовка, чтобы можно было отправить код 500.

pipeToNodeWritable(app, ctx, {
  write: (c) => res.write(c),
  end: () => res.end(suffix),
  destroy: (err) => {
    console.error('Stream failed:', err)
    res.end() // status already sent
  }
})

Гидратация после потоковой передачи

Потоковая HTML-разметка по-прежнему гидратируется на клиенте с помощью createSSRApp().mount(). Vue добавляет обработчики к существующему DOM, а не создаёт его заново. Потоковая передача влияет только на способ доставки разметки, но не на работу гидратации.

// client entry
import { createSSRApp } from 'vue'
import App from './App.vue'

createSSRApp(App).mount('#app') // hydrates streamed markup

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

Для компонентов, зависящих от данных, получайте критически важные данные до начала потоковой передачи или в её процессе. Потоковая передача особенно эффективна, когда части дерева независимы: оболочка отправляется сразу, а более медленные разделы отображаются по мере готовности их данных.

// fetch critical data, then stream the rest
const app = createSSRApp(App, { initialData })
const stream = renderToWebStream(app)
return new Response(stream, {
  headers: { 'Content-Type': 'text/html' }
})

Когда выбирать потоковую передачу

Используйте потоковую передачу для насыщенных содержимым страниц, где важны TTFB и воспринимаемая скорость и где сначала можно отправить стабильную оболочку. Выбирайте renderToString для небольших страниц или когда нужен полный контроль над итоговым кодом состояния и заголовками.

Быстрая проверка

Проверьте своё понимание потоковой SSR.

Повторение

Вы узнали о потоковой SSR:

  • renderToWebStream возвращает ReadableStream, а Node использует pipeToNodeWritable
  • Фрагменты отправляются по мере отрисовки дерева, поэтому браузер разбирает HTML постепенно
  • Это уменьшает TTFB по сравнению с блокирующей renderToString
  • Оболочка документа записывается вокруг потока; ошибки после первой отправки данных не могут изменить код состояния
  • Гидратация с помощью createSSRApp().mount() не меняется

Часто задаваемые вопросы

Урок «Потоковый SSR с renderToWebStream» бесплатный?

Да — полный текст урока «Потоковый SSR с renderToWebStream» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Vue Academy, подпишись на CoddyKit PRO. Курс Vue Academy содержит 4 уроков всего.

Чему я научусь в уроке «Потоковый SSR с renderToWebStream»?

renderToWebStream() и renderToString(), потоковая передача HTTP, улучшение TTFB и отправка фрагментов Ты практикуешь Vue Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Vue Academy?

Предыдущий опыт не требуется. Vue Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Потоковый SSR с renderToWebStream»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Vue Academy?

Да. Каждый урок Vue Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Компонент Vue Suspense
  2. Асинхронные компоненты с defineAsyncComponent
  3. Потоковый SSR с renderToWebStream
  4. Стратегии отложенной гидратации
← Назад к Vue Academy