Rendering Strategies
Next.js offers a range of powerful rendering strategies that allow developers to optimize web applications for performance, SEO, and user experience based on the specific needs of each page. I will break down each one and discuss why I chose a particular one in the context of this website.
Here is a nice reference from Next.js docs about each strategy https://nextjs.org/learn/seo/rendering-strategies
1. Static Site Generation (SSG)
Generates the HTML and other static assets during build time, rather than runtime.
✅ Fast page loads - because HTML is pre-generated
✅ Zero server cost at runtime
✅ Perfect for CDN caching - depending on the frequency of change, can have long cache times
✅ SEO optimised - Complete HTML available immediately
✅ Security - No server-side attack surface
⚠️ Limited dynamic data - incorporating dynamic data will be more complicated, as the HTML is generated at build time
⚠️ Requires rebuild to update - changing content will require redeployment, which can be slow, especially if many static pages need to be generated.
The pages I chose to use SSG in this website are the /home
, /about
and /_not-found
(404) as these pages rarely require updates, so it can take advantage of all the SSG upsides. It has minimal to no impact on build and deployment, as there are only a few of those pages that are using the SSG strategy.
SSG is the default rendering strategy as long as you're not using functions such as getServerSideProps
2. Server-Side Rendering (SSR)
Generates the page on the server on every request.
✅ Always Fresh - The Latest data and content are rendered on every request
✅ SEO benefits - Search engines can crawl and index SSR pages easily, which improves application visibility
✅ Dynamic - SSR allows dynamic data to be fetched server-side
⚠️ Increased server load - since pages are generated on the server every request with SSR, this can lead to increased load on the server especially for complex pages that call many APIs in the background to render content
⚠️ Higher cost - the increased server load can lead to higher consumption and higher hosting costs due to the need for more powerful servers to process requests
⚠️ Performance - SSR pages tend to be slower because of the process it requires to generate content.
I chose SSR for the first page of the /blog/page/1
post list only. As I wanted the first page to always have fresh content. Since I only have one page using SSR I can minimise the downside of using this approach whilst achieving my goal of having fresh information.
3. Incremental Static Regeneration (ISR)
Re-generates static files after the build, using a cache to store the initially generated static HTML and then revalidating it after the configured time.
✅ Improved performance - fast page load, as clients can fetch a pre-generated static version of the page.
✅ Reduced server load and cost - with ISR pages, they are only re-generated at an interval or on demand through revalidate.
✅ Dynamic - ISR allows for dynamic data to be fetched during the regeneration process.
⚠️ Additional complexity - ISR pages require a bit more configuration and cache management.
I've chosen the ISR strategy for the blog listing from page 2 and above /blog/page/[page]
I want to refresh the content of that list after some time. Data freshness is not critical on those pages.
4. On-demand ISR (dynamic page with cache and revalidation)
This approach is essentially just a variation of ISR except it generates pages on first request, then the pages get cached after first regeneration. It has all the pros and cons of ISR but the important thing to note is pages are not generated during build time! Which is great to use for cases such as individual blog post or product details pages.
Content can be revalidated via the configured interval or on demand via the /revalidate
endpoint
I have used this rendering strategy for all my individual blog post and cache it for 24hrs. This strategy is perfect because I can take advantage for the caching mechanism whilst having the ability to publish fresh content on demand.
5. Client-Side Rendering (CSR)
The rendering process occurs on the client browser using JavaScript. Similar to how traditional Single-Page Applications (SPA) work
✅ Highly Interactive - with JavaScript in the client, you can provide a very dynamic user experience
✅ Dynamic data - CSR enables dynamic data fetching in the client browser
✅ Reduces server load, as rendering is shifted to the client
⚠️ Slower initial page load - as the browser needs to download, parse and execute JavaScript before rendering content
⚠️ Less SEO friendly - CSR can make it difficult for search engines to index content
I only used CSR strategy for the components I want to be lazy loaded or rendered on the client-side, one example is the GithubGistsComponent
where I render gists, for example, code on the client-side.
Conclusion
I believe that the power of Next.js lies in combining these strategies. By having a good understanding of each approach, you can make informed decisions to build highly performant, SEO-friendly, and user-centric web applications with Next.js.