Quay lại blog
tips9 phút đọc

Next.js App Router: Patterns cho Production

Hướng dẫn thực chiến xây dựng web app nhanh với Next.js App Router — server components, streaming, parallel routes, caching strategies.

V
Bởi Ventra Rocket
·Đăng ngày 10 tháng 3, 2026
#Next.js#React#App Router#Server Components#Web Performance

Next.js App Router là một thay đổi căn bản trong cách tổ chức và render React app. Đây là các pattern Ventra Rocket sử dụng trong production.

1. Server Components là mặc định

Server Components không gửi JavaScript xuống client — lý tưởng cho data fetching.

// app/dashboard/page.tsx — Server Component mặc định
async function DashboardPage() {
  const metrics = await fetchMetrics(); // gọi DB trực tiếp
  return <MetricsGrid data={metrics} />;
}

Quy tắc:

  • Data fetching → Server Component
  • Tương tác (onClick, useState) → Client Component ("use client")
  • Browser APIs (localStorage) → Client Component

2. Streaming với Suspense

import { Suspense } from "react";

export default function Page() {
  return (
    <main>
      <HeroSection />
      <Suspense fallback={<SkeletonCard />}>
        <SlowDataComponent />
      </Suspense>
    </main>
  );
}

Dùng loading.tsx cho route-level loading UI — tự động là Suspense wrapper cho page.tsx.

3. Route Handler cho API

import { NextRequest, NextResponse } from "next/server";

export async function GET(request: NextRequest) {
  const page = Number(request.nextUrl.searchParams.get("page") ?? 1);
  const users = await db.users.findMany({ skip: (page - 1) * 10, take: 10 });
  return NextResponse.json({ users, page });
}

4. Chiến lược Cache

| Layer | Cơ chế | Thời gian | |-------|--------|-----------| | Request Memoization | React cache | Mỗi render | | Data Cache | fetch + next.revalidate | Persistent | | Full Route Cache | Static HTML | Build time | | Router Cache | Client-side | Per session |

// ISR: revalidate mỗi giờ
const data = await fetch("https://api.example.com/config", {
  next: { revalidate: 3600 },
});

// Luôn fresh
const live = await fetch("https://api.example.com/prices", {
  cache: "no-store",
});

5. Middleware cho Auth

export function middleware(request: NextRequest) {
  const token = request.cookies.get("auth_token");
  const isProtected = request.nextUrl.pathname.startsWith("/dashboard");
  if (isProtected && !token) {
    return NextResponse.redirect(new URL("/login", request.url));
  }
  return NextResponse.next();
}

export const config = { matcher: ["/dashboard/:path*"] };

Kết luận

App Router hoạt động tốt nhất khi: đẩy data fetching lên server, dùng Suspense cho async boundaries, và cân nhắc kỹ về Client Components. Ventra Rocket đã deploy nhiều Next.js 15 app với Time to First Byte dưới 1 giây.

Bài viết liên quan

Next.js App Router: Patterns cho Production | Ventra Rocket