Increasing Next.js app performance with GetServerSideProps and Next/Image

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.
    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 tag
    <img src={mediaLink}/>
    The post component
    interface PostPreviewProps {
    post: Post
    revalidate?: Function
    key?: string
    }
    export default function PostPreviewClient({
    post: {
    identifier,
    slug,
    title,
    body,
    subName,
    createdAt,
    voteScore,
    userVote,
    commentCount,
    url,
    username,
    sub,
    mediaLink,
    bodyPreview,
    },
    revalidate,
    }: PostPreviewProps) {
    const router = useRouter()
    return (
    <div className="w-full lg:max-w-full lg:flex" key={identifier} id={identifier}>
    <div className="flex-none h-48 overflow-hidden text-center bg-cover rounded-t lg:h-auto lg:w-48 lg:rounded-t-none lg:rounded-l " title="Post Image">
    <img src={mediaLink}/>
    </div>
    <div className="flex flex-col justify-between w-full p-4 leading-normal bg-white border-b border-l border-r border-gray-400 rounded-b lg:border-l-0 lg:border-t lg:border-gray-400 lg:rounded-b-none lg:rounded-r">
    <div className="mb-2">
    <Link href={`/topic/${subName}`}>
    <p className="flex items-center text-sm text-gray-600 cursor-pointer hover:underline"> /topic/{subName}</p>
    </Link>
    <Link href={url}>
    <div className="mb-2 text-xl font-bold text-gray-900 cursor-pointer">{title}</div>
    </Link>
    <p className="text-base text-gray-700">{bodyPreview}</p>
    </div>
    <div className="flex items-center">
    <div className="text-sm">
    <p className="leading-none text-gray-900">{username}</p>
    <p className="text-gray-600">{dayjs(createdAt).fromNow()}</p>
    </div>
    </div>
    <div className="flex flex-row w-6 h-full py-2 space-x-6 text-center lg:w-12">
    <div
    className="text-gray-400 cursor-pointer hover:bg-gray-300 hover:text-red-500"
    onClick={() => vote(1)}
    >
    <i
    className={classNames('fas fa-2x fa-arrow-up', {
    'text-red-500': userVote === 1,
    })}
    ></i>
    </div>
    <p className="font-bold ">{voteScore}</p>
    <div
    className="text-gray-400 rounded cursor-pointer hover:bg-gray-300 hover:text-blue-600"
    onClick={() => vote(-1)}
    >
    <i
    className={classNames('fas fa-2x fa-arrow-down', {
    'text-blue-600': userVote === -1,
    })}
    ></i>
    </div>
    </div>
    </div>
    </div>
    )
    }
    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
    <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
    because Images using Next/Image are always rendered in such a way as to avoid Cumulative Layout Shift, a Core Web Vital 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 PageSpeed insights to test both routes.
    Test Results
    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
    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

    45

    This website collects cookies to deliver better user experience

    Increasing Next.js app performance with GetServerSideProps and Next/Image