Files
2nd/10_Wiki/Topics/Architecture/SPA_라우트_전환_성능_최적화.md
T
koriweb d8a80f6272 chore(wiki): dangling 링크 canonical 정규화 (768파일/1200건)
이름만 다른(표기 변형) [[위키링크]]를 대상 문서의 canonical 제목으로 치환해
끊겼던 1,200개 링크를 연결. 제목/파일명 정규화 일치만 적용하고 별칭 매칭은
과병합 위험으로 제외(애매성 가드). 원본은 _link_reconcile_backup/ 에 백업.
도구: Datacollect/scripts/link_reconcile_apply.mjs

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 12:24:15 +09:00

5.2 KiB

id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
id title category status canonical_id aliases duplicate_of source_trust_level confidence_score verification_status tags raw_sources last_reinforced github_commit tech_stack
wiki-2026-0508-spa-라우트-전환-성능-최적화 SPA 라우트 전환 성능 최적화 10_Wiki/Topics verified self
SPA route transition perf
route transition optimization
SPA navigation perf
none A 0.9 applied
frontend
performance
spa
react
routing
2026-05-10 pending
language framework
typescript react

SPA 라우트 전환 성능 최적화

매 한 줄

"매 route 전환은 매 사용자가 매 가장 자주 만나는 perf moment". SPA에서 매 route 전환 latency는 매 INP/Core Web Vitals에 매 직접 영향. 2026년에는 매 React Router 7, TanStack Router, Next 15 App Router가 매 표준이며, 매 streaming + prefetch + view-transitions가 매 키.

매 핵심

매 병목 분류

  • JS bundle: 매 새 route chunk download/parse.
  • Data fetch: 매 loader/query waterfall.
  • Render: 매 new tree mount cost.
  • Asset: 매 image/font 신규 load.

매 최적화 lever

  • Code-split (route-level lazy).
  • Prefetch (hover/viewport/intent).
  • Parallel data load (loader pattern, no waterfall).
  • View Transitions API (visual smoothing).
  • RSC streaming (Next 15 App Router).

매 응용

  1. 매 e-commerce: product list → detail 매 < 100ms 체감.
  2. 매 dashboard: 매 widget data parallel.
  3. 매 docs site: 매 instant hover prefetch.

💻 패턴

매 Route-level code split

import { lazy, Suspense } from "react";
const Dashboard = lazy(() => import("./Dashboard"));

<Route path="/dashboard" element={
  <Suspense fallback={<Skeleton />}><Dashboard /></Suspense>
} />

매 Hover prefetch (TanStack Router)

import { Link } from "@tanstack/react-router";
<Link to="/products/$id" params={{ id }} preload="intent">
  Product
</Link>
// 매 hover/focus → 매 chunk + loader data 미리.

매 Parallel loaders (waterfall 제거)

// X — sequential
const route = createRoute({
  loader: async () => {
    const user = await fetchUser();   // 매 wait
    const orders = await fetchOrders(user.id); // 매 then wait
    return { user, orders };
  },
});

// O — parallel where possible
const route = createRoute({
  loader: async ({ params }) => {
    const [user, orders] = await Promise.all([
      fetchUser(params.id),
      fetchOrdersForId(params.id), // 매 user 의존 X로 변경
    ]);
    return { user, orders };
  },
});

매 View Transitions API

// 매 navigation에 매 native cross-fade
import { unstable_ViewTransition as ViewTransition } from "react";

function App() {
  return (
    <ViewTransition>
      <Outlet />
    </ViewTransition>
  );
}
::view-transition-old(root) { animation: fade-out 200ms; }
::view-transition-new(root) { animation: fade-in 200ms; }

매 RSC streaming (Next 15)

// app/products/[id]/page.tsx
export default async function Page({ params }: { params: { id: string } }) {
  return (
    <>
      <ProductHeader id={params.id} /> {/* 매 빠른 part */}
      <Suspense fallback={<Skeleton />}>
        <ProductReviews id={params.id} /> {/* 매 느린 part stream */}
      </Suspense>
    </>
  );
}

매 Optimistic navigation

// React 19 useOptimistic 응용
const [optimisticPath, setOptimisticPath] = useOptimistic(currentPath);

function navigate(to: string) {
  startTransition(() => {
    setOptimisticPath(to); // 매 즉시 UI 변경
    router.navigate(to);
  });
}

매 Bundle 분석 (rsdoctor / webpack-bundle-analyzer)

pnpm dlx @rsdoctor/cli analyze
# 매 route chunk 크기 매 visualize → 매 split point 매 결정

매 결정 기준

상황 Approach
매 small SPA Route-split + hover prefetch.
매 dashboard 다중 widget Parallel loaders + Suspense streaming.
매 SEO + perf Next 15 App Router (RSC).
매 highly interactive TanStack Router + View Transitions.
매 mobile-first Aggressive prefetch는 매 신중 (data cost).

기본값: Route-split + intent prefetch + parallel loaders. 매 modern routers는 매 default support.

🔗 Graph

🤖 LLM 활용

언제: 매 route 전환 매 느릴 때, 매 perf budget 책정, 매 prefetch 전략 설계. 언제 X: 매 MPA, 매 first-load 문제 (매 SSR/SSG 별도).

안티패턴

  • 매 lazy 모든 component: 매 too granular → 매 waterfall 악화.
  • 매 prefetch 모든 link: 매 모바일 데이터 burn.
  • 매 loader에 매 sequential await: 매 waterfall.
  • 매 Suspense 없이 매 lazy: 매 blank 화면.
  • 매 view-transition 만 적용: 매 underlying perf 안 고치고 cosmetic만.

🧪 검증 / 중복

  • Verified (web.dev, React Router 7 docs, TanStack Router docs, Next 15 docs).
  • 신뢰도 A.

🕓 Changelog

날짜 변경
2026-05-08 Phase 1
2026-05-10 Manual cleanup — 2026 router stack + View Transitions + RSC streaming