6 Effective Ways to Load Content in Modern Static Sites with Next.js v14 page router

Oleg Proskurin - Aug 12 - - Dev Community

Arthur Nikitsin, a seasoned developer at FocusReactive, has published an insightful article on static site generation. But even static websites can leverage various content-loading methods for enhanced performance and flexibility. In this overview, we'll explore six effective methods available in Next.js v14 using the pages router. These methods ensure optimal performance and user experience, even with SSG. Note that the app router offers more flexibility, but is recommended to wait for the stable release in v15.

Check out Arthur's original article for a detailed dive into static site generation.

1. Static Site Generation (SSG)

Generates HTML at build time and reuses it for each request. Ideal for pages with content that doesn’t change often. This is the primary method used in static site generation.

// pages/index.js
export async function getStaticProps() {
  const data = await fetchData();
  return { props: { data } };
}
Enter fullscreen mode Exit fullscreen mode

When to use: For static content like blogs or documentation.

API: getStaticProps

How it works: Fetches data at build time, creating HTML that is served on every request.

Read more about SSG

2. Server-Side Rendering (SSR)

Generates HTML on each request, useful for dynamic content.

// pages/index.js
export async function getServerSideProps() {
  const data = await fetchData();
  return { props: { data } };
}
Enter fullscreen mode Exit fullscreen mode

When to use: For frequently changing data.

API: getServerSideProps

How it works: Fetches data on every request, rendering HTML dynamically.

Read more about SSR

3. Client-Side Rendering (CSR)

Data is fetched and rendered on the client side, which can be beneficial even for static sites. This method is useful when you need to update parts of the page based on user interactions without a full page reload.

// pages/index.js
useEffect(() => {
  async function fetchData() {
    const response = await fetch('/api/data');
    setData(await response.json());
  }
  fetchData();
}, []);
Enter fullscreen mode Exit fullscreen mode

When to use: For interactive elements like forms, real-time data, or personalized content that updates after the initial page load.
API: useEffect

How it works: Fetches data in the browser after the initial load, allowing for dynamic updates without a full reload. This enhances user experience by providing instant feedback or updates based on user interactions.
Read more about CSR

4. Code Splitting

Dynamically imports parts of code to optimize load time. Code splitting can also be used for lazy loading components (see the next point).

import dynamic from 'next/dynamic'

const DynamicComponent = dynamic(() => import('../components/DynamicComponent'));
Enter fullscreen mode Exit fullscreen mode

When to use: To improve performance by loading only necessary code.

API: next/dynamic

How it works: Loads code chunks on demand, reducing initial load time.

Read more about Code Splitting

5. Lazy Loading Components

Defers loading of offscreen components until needed, enhancing performance.

import dynamic from 'next/dynamic'

const DynamicHeader = dynamic(() => import('../components/header'), {
  loading: () => <p>Loading...</p>,
})

export default function Home() {
  return <DynamicHeader />
}
Enter fullscreen mode Exit fullscreen mode

When to use: For components not immediately in view.

API: React.lazy

How it works: Loads components when they are about to enter the viewport.

Read more about Lazy Loading Components

6. Lazy Loading Images

By default, the next/image component uses lazy loading for images. The priority prop can be used to disable lazy loading when necessary.

import Image from 'next/image';

const MyComponent = () => (
  <Image
    src="/path/to/image.jpg"
    alt="Description"
    width={500}
    height={500}
    priority // use it to disable lazy loading
  />
);
Enter fullscreen mode Exit fullscreen mode

When to use: To optimize page speed with many images.

API: next/image

How it works: Defers image loading until they are needed, reducing initial load time.

Read more about lazy loading images

Conclusion

These methods in Next.js v14 can significantly improve your static site's performance and user experience. For more detailed insights, read Arthur Nikitsin's full article. You can explore more of his work in our company blog.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .