renderToWebStreamによるストリーミングSSR
renderToWebStream()とrenderToString()の比較、HTTPストリーミング、TTFBの改善、チャンクのフラッシュ
「renderToWebStreamによるストリーミングSSR」はCoddyKit上の無料Vue Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはVue Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Vue Academyコースには全4レッスンが含まれています。
renderToStringからストリーミングへ
従来のSSRではrenderToStringを使い、1バイトも送信する前にHTML全体をメモリ上に構築します。ブラウザはページ全体の準備が整うまで待機したままになります。
ストリーミングSSRでは、アプリの描画に合わせてHTMLをチャンク単位で送信するため、ブラウザはより早く解析を開始できます。
renderToWebStreamの基本
Vueのサーバーレンダラーにはストリーミング用の関数があります。renderToWebStreamはReadableStream(Web Streams 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)
})Web/Edgeランタイムでのストリーミング
Edgeランタイム(Workers、Deno、Bun)では、Webストリームから直接構築したResponseを返します。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(Time To First Byte)は、最初のレスポンスバイトが到着するまでの時間を測定します。
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を再生成するのではなく、既存の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を使います- ツリーの描画に合わせてチャンクがフラッシュされるため、ブラウザは段階的に解析できます
- ブロッキング方式の
renderToStringと比べて、TTFBが短縮されます - ストリームの前後をドキュメントシェルで囲みます。最初のフラッシュ後に発生したエラーでは、ステータスを変更できません
createSSRApp().mount()によるハイドレーションの仕組みは変わりません
AI チューターと学ぶ HTML — 無料
ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。
- コース
- 42
- レッスン
- 156
よくある質問
「renderToWebStreamによるストリーミングSSR」レッスンは無料ですか?
はい。「renderToWebStreamによるストリーミングSSR」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Vue Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Vue Academyコースには全4レッスンが含まれています。
「renderToWebStreamによるストリーミングSSR」で何を学びますか?
renderToWebStream()とrenderToString()の比較、HTTPストリーミング、TTFBの改善、チャンクのフラッシュ ブラウザで直接実行するハンズオンコードでVue Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Vue Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのVue Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「renderToWebStreamによるストリーミングSSR」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このVue Academyレッスンでコードを書いて実行できますか?
はい。すべてのVue Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Vue Suspenseコンポーネント
- defineAsyncComponentによる非同期コンポーネント
- renderToWebStreamによるストリーミングSSR
- 遅延ハイドレーション戦略