Maximize Your Site's Speed with Pre-Rendering in Next JS

Jayant - Feb 13 '23 - - Dev Community

Pre-Rendering in Next JS

What is Rendering

It is the process of converting your React Code into HTML.

There are various types of rendering

1) Client Side Rendering [ Used By ReactJS ]

In this, the Client Receives the Basic Structure of HTML Documents, and JavaScript renders all the Elements.

client-side-rendering.png

2) Pre Rendering

The HTML is generated on the Server side, and on the Client Side React makes the Component Interactive using the JavaScript provided by the Server.

Pre-rendering.png

It is of 2 Types

  • Server-Side Rendering
    • In Server Side Rendering, the HTML is generated on the Server for each request, and the Rendered HTML page and JavaScript are sent to the Client.
    • On the client side, React uses JavaScript to make the HTML Page Interactive.
    • For Every Request, the HTML page is generated, so not recommended due to performance Reasons.
  • Static-Site Generation [ RECOMMENDED ]
    • In This, the HTML page is only generated once at the build time and is reused at each request.

Server-Side Rendering.png

Hydration → Once the client gets the pre-rendered page & the JS code, React works on that page and makes it Interactive this process is called Hydration.

We can have multiple rendering methods in a single Next.js application

By default, Next JS pre-renders all the pages with no dynamic data

Once we are on a page and we are trying to get to another page, then pre-rendering doesn’t happen cuz at that React is the in charge and manipulates the DOM using JS.


How Next JS knows which code to run on the Server Side?

1) getStaticProp() Function

  • Used for the Static site generation
  • *It is a Async Function ( Returns a Promise *
**export async function getStaticProps(){
    // All the Code we will write here will execute on the Server side.
    // Also, this Code will not visible to the Client, So we can Include the 
    // Credential of the Database here. 
**
Enter fullscreen mode Exit fullscreen mode
  • It returns an object that will contains the props[]as a key ] and then that props will pass down to the respective function
export default function MyApp(props){
    const {product} = props.product;
    return(
        <>                        // React Fragments
            {products.map(product=><li>{product}</li>)}
        </>
    )
}

// This will be executed 1st
export async function getStaticProps(){
    return{
        props:{
            product:[
                "Larry","Josh","harry"
            ]
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Ques - What if there is some “Dynamic Data” in the getStaticProp() method?

Ans - To solve this problem, we have a new key called revalidate, which tells Next JS to re-render the page after a specific time ( in milliseconds.)

Client-Side fetching.png

export async function getStaticProp(){
        const data = await axios.get('<Dynamic Changing Data>')
        return{
                props:{
                    data:data
                },
                revalidate:300               // time in millisecond
        }
}
Enter fullscreen mode Exit fullscreen mode

This is called Incremental Static Regeneration” -** It is the property of the Next JS to update the pages after we have built the site.

We can update the pages separately without updating the whole site build.

There are 2 other keys in the return object that will be used when we have some problem in fetching the Data.

1) notFound

  • It is a Boolean value, It tells whether we have received the data.
  • If it was true, then Next JS shows us a 404 page.

2) redirect

  • It redirects the user to another route if the data can’t be fetched.
export async function getStaticProp(){
    //const data = fetching data from server
    if(!data){
        return{
            notFound: true
        }
    }
    if(!data){
        return{
            redirect:{
                destination:'/'
            }
        }
    }

    return {
        props:{
            name: "Jayant"
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

How Next JS Renders the Dynamic Paths Pages.

Suppose we have [blogId].js file inside of Blog Folder

So it has a Dynamic path, and it can have multiple Pages.

If Next JS tries to pre-render the pages, it doesn’t know how many pages it has to generate.

To solve this problem, we have the getStaticPaths() method.

getStaticPaths() → It tells Next JS for how many pages it has to render.

export async function getStaticPaths(){
        return{
            paths:[
            {params: {pid:'1'}},
            {parans:{pid:'2'}},
            {params:{pid:'3'}}   // In path everything is of type String
            ],
            fallback:false
        }
}

// fallback is used when we have multiple pages & preloading them will take so much time, so we only preload some mostly visited pages, and others are loaded Just in time when we go to the page URL. 
// for this we have set the fallback to true , It will tell the next Js that there are       more pages than this also.

export async function getStaticPath(){
        return{
            paths:[
            {params: {pid:'1'}},
            ],
            fallback:true || 'blocking'
        }
}

// we can use either of those values, blocking means only load when the data is fetched this can leads to greater loading time but we don't have to use the loading icon.

Enter fullscreen mode Exit fullscreen mode

While using the Fallback, make sure that if the user enters some invalid path, then it will give some error rather than a 404 Page

*To avoid this *

  • Use the notFound key & Inside the Page Component wait for some time to load the Data, for this use the Loading Icon.

2**getServerSideProps() Function**

  • Used for Server side rendering
  • Same as getStaticProps(), but it will render the pages on every request and have some more functions like res() and req()
  • It doesn’t have the revalidate key.
export async function getServerSideProps(context){
        const {params , req, res} = context;
        console.log(req);
        console.log(res);
        return{
            Name:"Jayant"
        }
}
Enter fullscreen mode Exit fullscreen mode
  • Using the res function we can send the response or attach any header to it.
  • Using the req function, we get access to many things like cookies, headers etc.
  • Both are Useful for the Authentication Purpose
  • It doesn’t have Methods like getStaticPaths , cuz pre-rendering doesn’t happen.

**getServerSideProps** & getStaticProps can only be exported from Page components. It will not be run on components imported into a page.


Client Side Data Fetching

Client-Side Data Fetching.png

  • There are many situations when we don’t have to use the Server-side rendering like
    • When there is a lot of Data to fetch then it just slows down the server.
    • User-specific Data which we don’t want that Crawler reads that

Example →

import {useEffect,useState} from 'react'

function College() {
    const [isLoading,setIsLoading] = useState(true);
    const [Data,setData] = useState([]);
    useEffect(()=>{
        const url = 'https://next-js-ab208-default-rtdb.firebaseio.com/sales.json' //.json is firebase specific
        fetch(url)
        .then(res=>res.json())
        .then(data=>{
            console.log(data);
            const loadedData = [];
            for (const key in data){
                loadedData.push({
                    id:key,name:data[key].username,age:data[key].age
                })
            }
            setData(loadedData);
            setIsLoading(false);
        })

    },[])

    if(isLoading){
        return <p>Loading...</p>
    }
  return (
    <div>
        {Data.map((item)=>{
            return <p key={item.id}>{item.name} is {item.age} years old</p>
        })}
    </div>
  )
}

export default College;
Enter fullscreen mode Exit fullscreen mode

Imp → This Page is also pre-rendered cuz by default next js pre-renders all the pages, but as we are fetching the data on the client-side, that data will not be pre-rendered.

If we try to see the Source Code of this, we can only see, the Loading Paragraph

Loading....
Enter fullscreen mode Exit fullscreen mode

Now for the Client-side Data Fetching we can use this as it is or we can create our own hook or we can use Someone’s other hook[SWR].

It is a React Hook for Data Fetching , you can use this if you want.

Combining Pre-fetching with Client-Side Rendering

To do this we use the getStaticProps or getServerSideProps to get the Data and then uses states to save them & then we can use the Client side rendering to update the state

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