C.W.K.
Stream
Lesson 02 of 08 · published

왜 Server Component?

~20 min · bundle, perf, security

Level 0Curious
0 XP0/68 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

풀어주는 bundle 문제

전통 React 가 모든 component 코드를 browser 로 ship. Markdown parser, syntax highlighter, date util — 다 모든 사용자한테 보내, 한 번 transform 만 하는데도.

구체적 4 승

  1. 작은 bundle. Server Component 가 client bundle 에 0 byte. Data shaping 무거운 lib 가 server 에 머묾.
  2. 직접 data access. Postgres query, file read, internal service call 을 API hop 없이 — 같은 datacenter, 같은 process, microsecond latency.
  3. Security. API key, DB credential, internal URL 이 server 떠나지 않음.
  4. Streaming. Server Component 가 HTML 점진적 stream. 싼 부분 즉시 ship, 느린 부분 data 도착 시 stream.

실제 bundle 산수

marked (~200KB) 와 highlight.js (~800KB) 쓰는 blog post page 를 client 에서 돌리면 모든 visitor 한테 1MB JS 비용. 같은 page 가 Server Component 면 그 lib 들 0 byte ship; render 된 HTML 만 browser 로.

Code

무거운 library 가 server 에 머무름·tsx
import { marked } from 'marked';
import hljs from 'highlight.js';
import { format } from 'date-fns';
import { db } from '@/lib/db';

export default async function BlogPost({
  params,
}: {
  params: Promise<{ slug: string }>;
}) {
  const { slug } = await params;
  const post = await db.post.findUnique({ where: { slug } });
  if (!post) return null;

  const html = marked(post.content, {
    highlight: (code, lang) => hljs.highlight(code, { language: lang }).value,
  });

  return (
    <article>
      <time>{format(post.date, 'MMMM d, yyyy')}</time>
      <div dangerouslySetInnerHTML={{ __html: html }} />
    </article>
  );
}
// Client 받는 것: render 된 HTML. Bundle 영향: 0 byte.
Secret 안전하게 read·tsx
// app/admin/page.tsx — auth 뒤에서만 도착하지만, secret 접근 보기 좋은 예
export default async function Admin() {
  const stripe = process.env.STRIPE_SECRET_KEY!;
  const { data } = await fetch('https://api.stripe.com/v1/customers', {
    headers: { Authorization: `Bearer ${stripe}` },
    cache: 'no-store',
  }).then(r => r.json());
  return <CustomersTable rows={data} />;
}

External links

Exercise

package.json 에서 data shaping 만 위해 쓰는 무거운 dependency 하나 찾아 (markdown, syntax highlight, date util). Server Component 안에서만 쓰게 옮기고 bundle analyzer 로 client bundle 에서 빠지는지 확인.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.