Continue
continue ...
Các chủ đề nâng cao trong Next.js
1. Performance Optimization
1.1. Code Splitting và Lazy Loading
- Dynamic Imports: Tách code theo từng route/component
- Route-based splitting: Tự động tách theo từng trang
- Component-based splitting: Lazy load components nặng
// Lazy load component
const HeavyComponent = dynamic(() => import('@/components/HeavyComponent'), {
loading: () => <p>Loading...</p>,
ssr: false // Optional: disable SSR
})
1.2. Image Optimization
- next/image: Tự động optimize images
- Responsive images: Tạo nhiều kích thước tự động
- WebP format: Tự động chuyển đổi format hiện đại
import Image from 'next/image'
export default function OptimizedImage() {
return (
<Image
src="/photo.jpg"
alt="Description"
width={500}
height={300}
placeholder="blur"
blurDataURL="data:image/jpeg;base64,..."
/>
)
}
2. Advanced Routing Patterns
2.1. Parallel Routes
- @folder convention: Hiển thị nhiều page cùng lúc
- Conditional rendering: Render theo điều kiện
- Loading states: Xử lý loading cho từng route
app/
├── dashboard/
│ ├── @analytics/
│ │ └── page.tsx
│ ├── @team/
│ │ └── page.tsx
│ └── layout.tsx
2.2. Intercepting Routes
- (.)modal: Mở modal từ danh sách
- (..)modal: Navigate lên level
- (…)modal: Navigate từ root
// app/photos/[id]/(.)modal/page.tsx
export default function PhotoModal({ params }: { params: { id: string } }) {
return <Modal><Photo id={params.id} /></Modal>
}
3. Advanced Data Fetching
3.1. Server Actions
- Mutations: Xử lý form server-side
- Revalidation: Cập nhật cache sau mutation
- Error handling: Xử lý lỗi gracefully
// app/actions.ts
'use server'
export async function createTodo(formData: FormData) {
const title = formData.get('title')
try {
await db.todo.create({ data: { title } })
revalidatePath('/todos')
return { success: true }
} catch (error) {
return { error: 'Failed to create todo' }
}
}
3.2. Streaming UI
- loading.tsx: Loading states từng phần
- Suspense boundaries: Streaming components
- Progressive enhancement: UX mượt mà
// app/products/loading.tsx
export default function Loading() {
return (
<div className="grid">
{[...Array(6)].map((_, i) => (
<ProductSkeleton key={i} />
))}
</div>
)
}
4. Production Best Practices
4.1. Monitoring & Analytics
- Next.js Analytics: Core Web Vitals
- Error tracking: Sentry integration
- Performance monitoring: Real User Monitoring
// next.config.js
const nextConfig = {
experimental: {
instrumentationHook: true
}
}
// instrumentation.ts
export async function register() {
if (process.env.NEXT_RUNTIME === 'nodejs') {
await import('./sentry.server.config')
}
}
4.2. Security Hardening
- Content Security Policy: XSS protection
- Rate limiting: API protection
- Authentication: NextAuth.js patterns
// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
// Security headers
const response = NextResponse.next()
response.headers.set(
'Content-Security-Policy',
"default-src 'self'; script-src 'self' 'unsafe-inline'"
)
return response
}
5. Microservices Architecture
5.1. Monorepo Setup
- Turborepo: Build system
- Shared packages: Common utilities
- Deployment strategies: Multi-app setup
// turbo.json
{
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "!.next/cache/**"]
},
"dev": {
"cache": false,
"persistent": true
}
}
}
5.2. Edge Runtime
- Edge Functions: Global execution
- Database at Edge: PlanetScale, Supabase
- Caching strategies: Smart cache invalidation
// app/api/edge/route.ts
export const runtime = 'edge'
export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
const location = searchParams.get('location')
const data = await getEdgeData(location)
return Response.json(data)
}
6. Testing Strategies
6.1. Integration Testing
- Playwright: End-to-end testing
- MSW: API mocking
- Test database: Isolated test data
// tests/e2e/products.spec.ts
import { test, expect } from '@playwright/test'
test('products page loads', async ({ page }) => {
await page.goto('/products')
await expect(page.locator('h1')).toContainText('Products')
await expect(page.locator('.product-card')).toHaveCount(6)
})
6.2. Component Testing
- Testing Library: React component tests
- Mock Service Worker: API mocking
- Snapshot testing: UI regression
// components/__tests__/ProductCard.test.tsx
import { render, screen } from '@testing-library/react'
import ProductCard from '@/ProductCard'
test('renders product information', () => {
render(<ProductCard product={mockProduct} />)
expect(screen.getByText('Product Name')).toBeInTheDocument()
expect(screen.getByText('$99.99')).toBeInTheDocument()
})
7. Deployment & DevOps
7.1. Docker Optimization
- Multi-stage builds: Optimize image size
- Layer caching: Speed up builds
- Health checks: Container monitoring
# Dockerfile
FROM node:18-alpine AS base
FROM base AS deps
COPY package*.json ./
RUN npm ci --only=production
FROM base AS builder
COPY . .
RUN npm ci && npm run build
FROM base AS runner
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
EXPOSE 3000
CMD ["npm", "start"]
7.2. CI/CD Pipelines
- GitHub Actions: Automated workflows
- Preview deployments: PR previews
- Production deployments: Zero-downtime
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- run: npm ci
- run: npm run build
- run: npm test
- run: npm run deploy
8. Kết luận
Các chủ đề nâng cao trong Next.js giúp bạn:
- Tối ưu hiệu năng: Code splitting, image optimization
- Xây dựng UX phức tạp: Parallel routes, intercepting routes
- Xử lý data hiệu quả: Server actions, streaming
- Production-ready: Security, monitoring, testing
- Scale applications: Microservices, edge runtime
🔑 GHI NHỚ QUAN TRỌNG:
- Luôn đo lường hiệu năng trước khi optimize
- Sử dụng TypeScript cho type safety
- Test kỹ lưỡng trước khi deploy
- Monitor và cải thiện liên tục