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 (واجهة 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)
})البث في بيئة تشغيل الويب أو Edge
في بيئات تشغيل Edge (مثل Workers وDeno وBun)، تعيدون كائن 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 (الزمن حتى أول بايت) المدة اللازمة لوصول أول بايت من الاستجابة.
مع 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، بينما يستخدم NodepipeToNodeWritable - تُرسل الأجزاء أثناء رسم الشجرة، لذلك يحللها المتصفح تدريجيًا
- يخفض ذلك 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 يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- مكوّن Vue Suspense
- المكوّنات غير المتزامنة باستخدام defineAsyncComponent
- SSR المتدفق باستخدام renderToWebStream
- استراتيجيات Hydration المؤجلة