React Academy · บทเรียน

เบื้องหลังการทำงานของ React SSR

ติดตามเส้นทาง renderToString/renderToPipeableStream และดูว่าไคลเอ็นต์ทำไฮเดรชันต่ออย่างไร

บทเรียน 1 จาก 412 ขั้นตอน

เบื้องหลังการทำงานของ React SSR เป็นบทเรียน React Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน React Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส React Academy มีบทเรียนทั้งหมด 4 บทเรียน

ปัญหาที่ SSR แก้ไข

React ฝั่งไคลเอ็นต์ต้องใช้ JavaScript เพื่อเรนเดอร์ ผู้ใช้จะเห็นหน้าเปล่าจนกว่า JS จะโหลดและทำงาน SSR จะเรนเดอร์ HTML ล่วงหน้าบนเซิร์ฟเวอร์ ทำให้ผู้ใช้เห็นเนื้อหาได้ทันที ช่วยปรับปรุงประสิทธิภาพที่รับรู้และ SEO

renderToString

ส่วนติดต่อ SSR ดั้งเดิม: renderToString(<App />) จะเรนเดอร์ต้นไม้คอมโพเนนต์เป็นสตริง HTML บนเซิร์ฟเวอร์แบบพร้อมกัน

import { renderToString } from 'react-dom/server';
import App from './App';

// In an Express handler:
app.get('*', (req, res) => {
  const html = renderToString(<App />);
  res.send(`
    <!DOCTYPE html>
    <html><body>
      <div id="root">${html}</div>
      <script src="/bundle.js"></script>
    </body></html>
  `);
});

การไฮเดรตบนไคลเอ็นต์

หลังจาก HTML มาถึง เบราว์เซอร์จะแยกวิเคราะห์และเรนเดอร์ส่วนติดต่อผู้ใช้ จากนั้น hydrateRoot() ของ React จะเชื่อมตัวรับฟังเหตุการณ์และทำให้ HTML แบบคงที่โต้ตอบได้ กระบวนการนี้เรียกว่า การไฮเดรต

// client/index.tsx
import { hydrateRoot } from 'react-dom/client';
import App from './App';

hydrateRoot(document.getElementById('root'), <App />);

เกิดอะไรขึ้นระหว่างการไฮเดรต

React จะเดินผ่าน DOM ที่เรนเดอร์โดยเซิร์ฟเวอร์และ DOM เสมือนพร้อมกัน หากตรงกัน React จะเชื่อมตัวรับฟังโดยไม่แตะต้อง DOM หากแตกต่างกัน ระบบจะบันทึกคำเตือนการไฮเดรตและแก้ไข DOM

renderToPipeableStream

ส่วนติดต่อการสตรีมของ React 18 จะส่ง HTML เป็นส่วน ๆ เมื่อข้อมูลพร้อมใช้งาน ทำให้เบราว์เซอร์ค่อย ๆ แสดงเนื้อหาได้ขณะที่เซิร์ฟเวอร์ยังประมวลผลอยู่

import { renderToPipeableStream } from 'react-dom/server';

app.get('*', (req, res) => {
  const { pipe } = renderToPipeableStream(<App />, {
    bootstrapScripts: ['/bundle.js'],
    onShellReady() {
      res.setHeader('content-type', 'text/html');
      pipe(res); // starts streaming
    },
  });
});

Suspense และการสตรีม

เมื่อใช้ SSR แบบสตรีม ขอบเขต Suspense จะสตรีมเนื้อหาสำรองก่อน แล้วแทนที่ด้วยเนื้อหาเมื่อข้อมูลได้รับการแก้ไข โดยไม่บล็อกการส่ง HTML ชุดแรก

// The shell (nav, layout) streams immediately;
// <UserProfile> suspends and streams when data resolves
function App() {
  return (
    <Layout>
      <Suspense fallback={<Skeleton />}>
        <UserProfile /> {/* streams after data loads */}
      </Suspense>
    </Layout>
  );
}

การทำให้ข้อมูลเป็นอนุกรม

ข้อมูลที่ดึงมาบนเซิร์ฟเวอร์ต้องทำให้เป็นอนุกรมและฝังไว้ใน HTML เพื่อให้ไคลเอ็นต์อ่านข้อมูลระหว่างการไฮเดรตได้โดยไม่ต้องดึงข้อมูลซ้ำ

// Server:
const data = await fetchData();
const html = renderToString(<App data={data} />);
const serialized = JSON.stringify(data).replace(/</g, '\\u003c');

// Inline data in HTML:
`<script>window.__INITIAL_DATA__ = ${serialized};</script>`

// Client hydration reads:
const data = window.__INITIAL_DATA__;

ความแตกต่างของสภาพแวดล้อม

โค้ดฝั่งเซิร์ฟเวอร์ทำงานใน Node.js ไม่ใช่เบราว์เซอร์ โค้ดที่อ้างอิง window, document หรือ localStorage จะทำให้เซิร์ฟเวอร์หยุดทำงาน ป้องกันกรณีนี้ด้วย typeof window !== 'undefined'

const isBrowser = typeof window !== 'undefined';

function getTheme() {
  if (!isBrowser) return 'light'; // server-safe default
  return localStorage.getItem('theme') ?? 'light';
}

React Server Components เทียบกับ SSR

SSR จะเรนเดอร์คอมโพเนนต์เป็น HTML ในแต่ละคำขอ ส่วน React Server Components (RSC) แตกต่างออกไป เพราะจะไม่ส่ง JS ไปยังไคลเอ็นต์เลยและสามารถทำงานแบบไม่พร้อมกันได้ แต่ RSC ต้องใช้ตัวรวมชุดคำสั่งที่รองรับโปรโตคอล RSC (Next.js และอื่น ๆ)

ประโยชน์ด้านประสิทธิภาพของการสตรีม

SSR แบบสตรีมช่วยปรับปรุง Time To First Byte (TTFB) ของโครงหน้า และเปิดใช้การไฮเดรตแบบเลือกเฉพาะส่วน เบราว์เซอร์จึงสามารถไฮเดรตส่วนโต้ตอบได้ก่อนที่ HTML ของทั้งหน้าจะสตรีมเสร็จ

ตรวจสอบความเข้าใจ

เมื่อมี HTML จากเซิร์ฟเวอร์อยู่แล้ว hydrateRoot() ของ React ทำอะไรแตกต่างจาก createRoot()

สรุปทบทวน

SSR ใช้ renderToPipeableStream เพื่อส่ง HTML ก่อนที่ JS จะโหลด ไคลเอ็นต์เรียก hydrateRoot() เพื่อเชื่อมตัวรับฟังเหตุการณ์เข้ากับ HTML จากเซิร์ฟเวอร์ SSR แบบสตรีมร่วมกับ Suspense จะส่งโครงหน้าก่อนแล้วเติมเนื้อหาแบบไม่พร้อมกัน ป้องกันการเข้าถึงส่วนติดต่อของเบราว์เซอร์ด้วย typeof window !== 'undefined'

เริ่มต้นได้ฟรี

เรียนรู้ React ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
88
บทเรียน
324

คำถามที่พบบ่อย

บทเรียน “เบื้องหลังการทำงานของ React SSR” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “เบื้องหลังการทำงานของ React SSR” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส React Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส React Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “เบื้องหลังการทำงานของ React SSR”

ติดตามเส้นทาง renderToString/renderToPipeableStream และดูว่าไคลเอ็นต์ทำไฮเดรชันต่ออย่างไร คุณปฏิบัติ React Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน React Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน React Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน

บทเรียน “เบื้องหลังการทำงานของ React SSR” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน React Academy นี้ได้ไหม

ได้ บทเรียน React Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. เบื้องหลังการทำงานของ React SSR
  2. ข้อผิดพลาดของไฮเดรชัน: สาเหตุและวิธีแก้
  3. ไฮเดรชันแบบเลือกและ HTML แบบสตรีม
  4. รูปแบบสถาปัตยกรรม Islands
← กลับไปที่ React Academy