DEV Community

Introduction
Building a performant web application involves balancing static and dynamic content effectively. Next.js offers a suite of features to achieve this balance, including Streaming React Server Components (RSC), Partial Prerendering (PPR), Incremental Static Regeneration (ISR), Server-Side Rendering (SSR), Static Site Generation (SSG), caching, prefetching, and suspense boundaries. Let's explore these concepts through a real-world example: a blog website with a mix of static and dynamic content.
Scenario: Blog Homepage
Our blog homepage will display:
- Static Header and Blog Posts: These are mostly static, updated occasionally.
- Dynamic "Latest Comments" Section: This updates frequently.
Step-by-Step Implementation
Step 1: Project Setup
- Directory Structure:
/app
/layout.tsx # Root layout for the app
/page.tsx # Homepage route
/components
/BlogPostList.tsx # Component for rendering the blog post list
/LatestComments.tsx # Component for rendering latest comments
/lib
/data.ts # Functions to fetch blog posts and comments
- Mock Data Source: Use a JSON file or API for blog posts and comments.
Step 2: Define Data Fetching Functions
In /lib/data.ts
, create functions to fetch blog posts and comments:
// lib/data.ts
export async function getBlogPosts() {
await new Promise((resolve) => setTimeout(resolve, 1000)); // Simulate delay
return [
{ id: 1, title: "Blog Post 1", content: "This is the first post." },
{ id: 2, title: "Blog Post 2", content: "This is the second post." },
];
}
export async function getLatestComments() {
await new Promise((resolve) => setTimeout(resolve, 1500)); // Simulate delay
return [
{ id: 1, text: "Great post!", user: "User1" },
{ id: 2, text: "Thanks for sharing!", user: "User2" },
];
}
Step 3: Create Components
- BlogPostList Component: Use SSG with ISR for blog posts.
// components/BlogPostList.tsx
import { getBlogPosts } from "../lib/data";
export default async function BlogPostList() {
const posts = await getBlogPosts();
return (
Blog Posts
{posts.map((post) => (
{post.title}
{post.content}
))}
);
}
- LatestComments Component: Use SSR with a suspense boundary for dynamic comments.
// components/LatestComments.tsx
import { getLatestComments } from "../lib/data";
export default async function LatestComments() {
const comments = await getLatestComments();
return (
Latest Comments
{comments.map((comment) => (
{comment.user}: {comment.text}
))}
);
}
Step 4: Build the Homepage
Combine static and dynamic content using Streaming SSR and Suspense.
// app/page.tsx
import { Suspense } from "react";
import BlogPostList from "../components/BlogPostList";
import LatestComments from "../components/LatestComments";
export const revalidate = 600; // Enable ISR
export default async function Home() {
return (
My Blog
{/* Static Blog Posts with SSG + ISR */}
{/* Dynamic Comments with Streaming SSR and Suspense */}
Loading latest comments...}>
);
}
Step 5: Optimize Caching and Prefetching
-
Prefetching: Use
prefetch={true}
in links for faster navigation.
// components/BlogPostList.tsx (updated)
import Link from "next/link";
import { getBlogPosts } from "../lib/data";
export default async function BlogPostList() {
const posts = await getBlogPosts();
return (
Blog Posts
{posts.map((post) => (
{post.title}
{post.content}
))}
);
}
-
Cache Headers for Static Assets: Set cache headers in
next.config.js
.
// next.config.js
module.exports = {
async headers() {
return [
{
source: "/:path*",
headers: [
{
key: "Cache-Control",
value: "public, max-age=31536000, immutable", // Cache static assets for 1 year
},
],
},
];
},
};
Explanation of Rendering Strategies
- SSG with ISR for BlogPostList: Pre-rendered at build time, revalidated every 10 minutes.
- Streaming SSR with PPR for LatestComments: Dynamic content is streamed as it becomes available.
- Suspense Boundary: Ensures a smooth loading experience by showing a fallback UI.
Benefits
- Fast Initial Load: Static content loads immediately.
- Dynamic Updates: Fresh data is fetched at request time.
- Improved UX: Suspense boundaries prevent page blocking.
- Caching: Reduces server requests on repeat visits.
- Prefetching: Enhances navigation speed.
Tags:
#NextJS
#React
#WebDevelopment
#PerformanceOptimization
#StreamingRSC
#ISR
#SSG
#SSR
#SuspenseBoundary
#Caching
#Prefetching
This approach ensures a fast and user-friendly experience by leveraging Next.js's advanced features to balance static and dynamic content effectively.
For further actions, you may consider blocking this person and/or reporting abuse
Top comments (0)