Server Response Time at First Load
Next.js provides a comprehensive set of tools to help optimise the performance of websites built with React. If SEO is a priority for your site, improving performance is essential—not only to enhance your search engine rankings but also to lower bounce rates and increase conversion rates.
One of the easiest ways to analyse your website’s performance is by using Lighthouse in Google Chrome. You can also integrate Lighthouse into your Next.js workflow for continuous performance monitoring.
When running Lighthouse in Chrome, it’s best to use Incognito mode. This helps ensure that browser extensions don’t interfere with or skew your performance scores.
There are several strategies to improve your Lighthouse performance scores. In this article, I’ll walk you through the techniques our team uses to address one of the most important metrics—Initial Server Response Time.
Server-Side Rendering (SSR) vs Static Site Generation (SSG)
Next.js provides two powerful pre-rendering strategies to enhance web application performance by reducing the amount of JavaScript sent to the client: Server-Side Rendering (SSR) and Static Site Generation (SSG).
During the initial development stages of a Next.js project, it’s common to use getServerSideProps for page rendering. This is often the default choice, especially when dynamic data fetching is required.
The getServerSideProps function is executed on the server during every request, allowing for real-time database operations and just-in-time page rendering. This aligns with traditional server-side rendering principles and is straightforward to implement.
**The Need for Speed
**
However, a key drawback of SSR is speed. Even a quick, indexed database query on a low-latency server can take 150–200ms. This delay is typically the biggest contributor to slow Initial Server Response Time, which significantly impacts overall performance. In our case, the database query alone accounted for nearly one-third of the total page load time.
To overcome this bottleneck and achieve faster page loads, the best approach is to switch to Static Site Generation. With SSG, pages are generated at build time, not request time, and data is pre-rendered into static HTML. This eliminates the need for runtime database queries and results in lightning-fast delivery.
Incremental Static Regeneration (ISR)
The downside to SSG is that the site becomes static—meaning updates to the database won’t reflect on the website immediately. This poses challenges for websites with frequently changing content.
Thankfully, Next.js supports Incremental Static Regeneration (ISR). ISR allows pages to be updated at runtime after the initial build, providing a balance between speed and freshness.
Here’s an example of how ISR is implemented:
In this example, if a request is made and the cached page is older than 3 hours (10,800 seconds), Next.js will serve the stale page but regenerate it in the background for future requests.
You can set the revalidate value as low as 1 second. On Vercel, ISR does not count toward your serverless or edge function quotas—making it essentially “free.”
To support this, update the Cache-Control headers in your next.config.js:
The Tradeoff
Migrating from getServerSideProps to getStaticProps isn’t without tradeoffs. The biggest challenge for us was build time. Our websites, singaporemalls.com and nolcardchecks.com, one is a directory containing tens of thousands of merchant pages and other is a NOL Card blog guide also containing tens of thousands of merchant pages. Previously, we used a single dynamic page with SSR to handle all merchant data. Moving to SSG meant each page had to be statically generated at build time.
Since each page involved querying the database, our total build time exceeded one hour—an issue on Vercel, which enforces a 45-minute build time limit across all plans (Hobby, Pro, and Enterprise). This hard limit leads to deployment failures if exceeded.
Navigating Vercel’s Build Time Limit
To work around this limitation, we developed a custom Node.js script to run at build time. This script fetches data in parallel batches and generates local JSON files on the build server.
By reading from these pre-built JSON files instead of querying a remote database for each page, we drastically reduced page generation time—bringing the total build process back within Vercel’s 45-minute limit.
**
Conclusion
**
Transitioning from getServerSideProps to getStaticProps was the most impactful change in improving our Initial Server Response Time, pushing our Lighthouse performance scores into the high 90s. By shifting the load to build time rather than page request time, we provided a much faster experience for end users.
This change not only enhances the user experience but also contributes to better SEO—since Google rewards websites that load quickly.
Top comments (0)