Next.js SSG vs SSR: choosing without shipping a bug
Get clarity on when to use Static Generation vs. Server-Side Rendering in Next.js and avoid common interview traps.
In an interview, you might find yourself confronted with scenarios where you need to make performance-critical decisions about rendering methods in Next.js. Candidates often stumble upon questions regarding the trade-offs between Static Generation (SG) and Server-Side Rendering (SSR), which reveal deeper implications of these choices in real-world applications.
Making the Right Rendering Choice
Consider a popular e-commerce website powered by Next.js. This site, benefiting from fast load times and SEO, must handle expected traffic spikes during sales events. The engineering team must decide whether to pre-render product pages using Static Generation or fetch data on-demand with Server-Side Rendering.
This choice isn't merely technical; it has nuanced ramifications for user experience, server costs, and data freshness. Static Generation creates HTML at build time, promising quick delivery and server-side load offloading, while SSR generates HTML per request—sacrificing speed for always up-to-date information.
Understanding Static Generation vs. Server-Side Rendering
Static Generation (SG)
- Pre-rendering at build time: Pages are generated once and served as static files, making them immediately available to users.
- Performance: Fast response times since the server delivers pre-built pages without additional processing.
- Cost-effective: Reduced server load can mean lower costs, especially under high traffic.
Server-Side Rendering (SSR)
- Dynamic rendering: Pages are generated on-demand for each user request, ensuring fresh data but could result in sporadic latency.
- SEO Benefits: Ideal for pages that need the latest content (e.g., news feeds) since they are rendered with live data.
- Higher costs: More server resources and potentially higher latency during peak loads.
Code Example: Fetching Data in a Next.js Page
To demonstrate how Static Generation and Server-Side Rendering work in practice, let’s consider a simple page setup.
// pages/products/[id].js
import { useRouter } from 'next/router';
// Using Static Generation
export async function getStaticProps({ params }) {
const res = await fetch(`https://api.example.com/products/${params.id}`);
const product = await res.json();
return {
props: { product }, // Passed to the page component as props
};
}
export async function getStaticPaths() {
const res = await fetch('https://api.example.com/products');
const products = await res.json();
const paths = products.map((product) => ({ params: { id: product.id } }));
return { paths, fallback: false }; // No fallback to show 404
}
const ProductPage = ({ product }) => {
return <div><h1>{product.name}</h1><p>{product.description}</p></div>;
};
export default ProductPage;
In this example, getStaticProps is used for Static Generation to statically generate a product page by fetching data during the build. The getStaticPaths method is essential for defining dynamic routes based on available products.
Interview Traps
Candidates often trip over specific technical aspects during interviews related to these rendering methods:
- Trade-offs between SG and SSR: Failing to articulate the impact on performance and user experience or mistaking SSR for a solution that improves SEO universally, rather than in specific cases.
- Data fetching methods: Confusion between
getStaticPropsandgetServerSideProps. Understanding when to use each can signal a candidate's comprehension of Next.js deeply. - Expected behavior of components: Misunderstanding the
use clientdirective can lead to performance issues or unexpected client-side hydration problems, which are common in interactive applications. - App Router nuances: Knowing that components in the Next.js App Router default to server-side rendering unless explicitly designated can be a critical detail.
Worked Example: A Real-World Scenario
Let’s examine a common question regarding data retrieval from an API. You’re tasked with displaying user profiles—some changing frequently—on a site built with Next.js. Choices lie between SG for static profiles and SSR for user-specific information:
Understanding user requirements: Does the profile need to reflect the latest data, or was a slight delay in reflecting edits acceptable? If fresh data is crucial, SSR should be the choice.
Setting server-side fetching logic: Implement
getServerSidePropsfor the cases where data must be fresh. Here’s how that looks:// pages/profile/[id].js export async function getServerSideProps({ params }) { const res = await fetch(`https://api.example.com/users/${params.id}`); const user = await res.json(); return { props: { user } }; }Discussing implications: Candidates must articulate the trade-offs discussed above, especially regarding user experience during traffic peaks.
Testing scenarios: Preparing tests for both methods ensures that application performance meets expectations under various conditions should also be covered.
Impact on Day-to-Day Job
In real-world projects, these choices become fundamental in the way architecture is built and resources are allocated. Handling traffic during peak hours while providing quick data access is crucial. Teams using Next.js see that:
- Misjudging when to use SG vs. SSR can lead to complaints about slow load times or stale content.
- A working knowledge of pre-rendering strategies directly correlates to user satisfaction and scalability of applications.
- Awareness of the right data-fetching lifecycle methods (like client-side vs. server-side) informs how teams manage state and cache data effectively.
In summary, mastering these concepts in Next.js requires not only understanding the technical syntax but also the strategic thinking required to weigh trade-offs based on real-world applications.
References
Ready to practice Next.js?
Answer real questions, get instant feedback, and watch your skill score climb — free. Practice is in English, like real tech interviews.
Try one 👇
↑ Go ahead — pick an answer. This is Skillpato.