Increasing Next.js app performance with GetServerSideProps and Next/Image
Tags: nextjs, react, performance
Published: 2021-07-26 13:46:17


I was developing an app using react and next.js and I had to decide on the method I will be fetching my data in so I had two options to render my data

* Using Axios and fetching the data on the client

* Using the prebuilt function GetServerSideProps and rendering on the server

So, I decided on doing both and testing the performance using [pageSpeed insights](https://developers.google.com/speed/pagespeed/insights/).

First, The data I will be fetching is detailed in the interface below written in Typescript

    export interface Post {

    identifier: string

    title: string

    body?: string

    slug: string

    subName: string

    username: string

    createdAt: string

    updatedAt: string

    sub?: Sub

    mediaLink?: string

    bodyPreview?: string

    url: string

    voteScore?: number

    commentCount?: number

    userVote?: number

    }

## Fetching data on the client

First, we will fetch data dynamically using Axios as demonstrated in the code snippet below

    const [posts, setPosts] = useState<Post[]>([])

    useEffect(() => {Axios.get('/posts').then((res)=>setPosts(res.data)).catch((err) => console.log(err))}, [])

Then I will render elements using the post component

    {posts?.map((post)=>(<PostPreview post={post} key={post.identifier}/>))}

The client-side post component will be using the default HTML <img> tag

    <img src={mediaLink}/>

The post component
{% gist https://gist.github.com/mage1711/d4704b4ad3d7f57e07639d18e0247f6a.js %}
## Fetching data on the server

First, I will wrap the Axios function used on the client-side with Next.js built-in function ***GetServerSideProps***

    import { GetServerSideProps } from 'next'

    export const getServerSideProps: GetServerSideProps = async (context) => {try {

    const res = await Axios.get('/post')
    return { props: { posts: res.data } }
    } catch (err) {

    return { props: { error: 'Something went wrong' }}
    }}

and in the post component, I will be using Next/Image component instead of <img>

    <Image src={mediaLink} width={16} height={16} layout="responsive"/>

but what do they do exactly

GetServerSideProps Fetches data on each request and renders it on the server then sends it to the client

Why Image instead of <img>

because Images using Next/Image are always rendered in such a way as to avoid [Cumulative Layout Shift](https://web.dev/cls/), a [Core Web Vital](https://web.dev/vitals/) that Google uses in web search ranking, and Automatic Image Optimization according to Next.js

So no that I have two pages one that loads data on the server and one on the client I used P[ageSpeed insights](https://developers.google.com/speed/pagespeed/insights/) to test both routes.

## Test Results

I analyzed both [https://notus-client.vercel.app/](https://notus-client.vercel.app/) and [https://notus-client.vercel.app/serverside](https://notus-client.vercel.app/serverside)

and saw an increase of about 9–14 points on mobile which is the only platform we will focus on because it is the one that benefits most from server-side rendering

![Client-side results](https://cdn-images-1.medium.com/max/2000/1*XVjq-gTXobIqWiR_Bahy5Q.png)

![Client-side results](https://cdn-images-1.medium.com/max/2968/1*KvNgF6guqS-Tb4rrz7tYkw.png)

![Server-side results](https://cdn-images-1.medium.com/max/2000/1*2KrffWwQB3rqoqyvwgOJpg.png)

![Server-side results](https://cdn-images-1.medium.com/max/2996/1*wXZllSrYhbaSEEbhKMecQg.png)

As the results show the server-side approach increased the score by about 15% to 20%. which proves that this approach will be better for the app moving forward.

you can run the test if you want on

* [https://notus-client.vercel.app/](https://notus-client.vercel.app/)

* [https://notus-client.vercel.app/serverside](https://notus-client.vercel.app/serverside)

source code on GitHub: [https://github.com/mage1711/Notus-client](https://github.com/mage1711/Notus-client)