DEV Community

Cover image for Implementasi Lazy Loading pada Component Next JS yang Bisa Bikin Aplikasi Ngebut dengan Dynamic Import
Yoga Meleniawan Pamungkas
Yoga Meleniawan Pamungkas

Posted on

Implementasi Lazy Loading pada Component Next JS yang Bisa Bikin Aplikasi Ngebut dengan Dynamic Import

Image description

Pernah mengalami aplikasi yang kita kembangkan terasa lemot karena ada banyak component yang sedang di-render? Pastinya semua orang yang baru belajar next js akan mengalami hal yang sama. Karena pada dasarnya ketika kita baru pertama kali belajar next js pasti tidak memperhatikan performa dari aplikasi.

Kalau kita bicara masalah performa dari aplikasi memang pengaruh ya? ketika kita menggunakan lazy loading dan tidak menggunakan? Kalau data yang temen-temen gunakan itu masih sedikit dan itu proses running aplikasi dilakukan di lokal ya bisa dipastikan tidak ada pengaruh sama sekali. Tapi, kalau data temen-temen itu sudah jutaan maka itu menjadi issue yang perlu kita perbaiki.

Lalu kira-kira apa perbedaannya ketika kita menggunakan lazy loading atau tidak? Saya akan coba memberikan contoh yang paling sederhana ya temen-temen dengan menggunakan cara dynamic import atau code splitting. Oiya, temen-temen juga bisa cobain sendiri ya dengan kode program yang akan saya tuliskan dibawah.


Tidak Menggunakan Lazy Loading

Disini kita memiliki 1 page dengan 2 component. Dibawah ini merupakan kode program untuk page dari next js.

"use client"
import React from 'react'
import ComponentIncrement from './components/ComponentIncrement'
import HeavyComponent from './components/HeavyComponent'

const Home = () => {

  return (
    <main className="flex flex-col min-h-screen gap-3 m-10">
      <ComponentIncrement />
      <HeavyComponent/>
    </main>
  )
}

export default Home
Enter fullscreen mode Exit fullscreen mode

Dibawah ini merupakan kode program dari component ComponentIncrement

"use client"
import React, { useEffect, useState } from 'react'
import { setInterval } from 'timers'

const ComponentIncrement = () => {
    const [count, setCount] = useState(0)

    useEffect(() => {
        setInterval(() => {
            setCount((s) => s + 1)
        }, 1000)
    }, [])

    return (
        <div className="bg-slate-500 w-10 h-10">
            {count}
        </div>
    )
}

export default ComponentIncrement
Enter fullscreen mode Exit fullscreen mode

Dibawah ini merupakan kode program dari component HeavyComponent

"use client"

import Image from "next/image";
import { useEffect, useState } from "react";
import Gambar from "../../../public/images/image.jpg"

const fetchData = async () => {
    const response = await fetch(`https://jsonplaceholder.typicode.com/posts/1`);
    const data = await response.json();
    return data;
};

const HeavyComponent = () => {
    const [data, setData] = useState<any>();

    useEffect(() => {
        const fetchDataAsync = async () => {
            const result = await fetchData();

            if (result) {
                setData(result);
            }
        };

        fetchDataAsync();
    }, []);

    return (
        <div className="flex flex-col">
            {
                data != null ? <>
                    <Image src={Gambar} alt="Image" width={200} height={200} />
                    <h2>Heavy Component</h2>
                    <p>Title: {data.title}</p>
                    <p>Body: {data.body}</p>
                </> : 'Fetching data from API'
            }
        </div>
    );
};

export default HeavyComponent;
Enter fullscreen mode Exit fullscreen mode

Untuk hasilnya kurang lebih seperti ini :

Image description

Hasil diatas belum bisa kita lihat ya temen-temen, apakah menggunakan lazy loading atau tidak. Tapi, kita akan coba berikan logging berupa teks yang akan ditampilkan pada console browser. Kurang lebih hasilnya seperti ini :

Image description

Kita akan simpan hasil itu dan nanti akan kita komparasikan diakhir artikel ini ya temen-temen untuk mengetahui yang sebenarnya fungsi dari lazy loading.

Menggunakan Lazy Loading

Disini kita memiliki 1 page dengan 2 component. Dibawah ini merupakan kode program untuk page dari next js.

"use client"
import React from 'react'
import ComponentIncrement from './components/ComponentIncrement'
import dynamic from 'next/dynamic'

const DynamicHeavyComponent = dynamic(() => import('./components/HeavyComponent'), {
  loading: () => <p className="text-white">Loading Heavy Component...</p>,
  ssr: false,
})

const Home = () => {

  return (
    <main className="flex flex-col min-h-screen gap-3 m-10">
      <ComponentIncrement />
      <DynamicHeavyComponent />
    </main>
  )
}

export default Home
Enter fullscreen mode Exit fullscreen mode

Dibawah ini merupakan kode program dari component ComponentIncrement

"use client"
import React, { useEffect, useState } from 'react'
import { setInterval } from 'timers'

const ComponentIncrement = () => {
    const [count, setCount] = useState(0)

    useEffect(() => {
        setInterval(() => {
            setCount((s) => s + 1)
        }, 1000)
    }, [])

    return (
        <div className="bg-slate-500 w-10 h-10">
            {count}
        </div>
    )
}

export default ComponentIncrement
Enter fullscreen mode Exit fullscreen mode

Dibawah ini merupakan kode program dari component HeavyComponent

"use client"

import Image from "next/image";
import { useEffect, useState } from "react";
import Gambar from "../../../public/images/image.jpg"

const fetchData = async () => {
    const response = await fetch(`https://jsonplaceholder.typicode.com/posts/1`);
    const data = await response.json();
    return data;
};

const HeavyComponent = () => {
    const [data, setData] = useState<any>();

    useEffect(() => {
        const fetchDataAsync = async () => {
            const result = await fetchData();

            if (result) {
                setData(result);
            }
        };

        fetchDataAsync();
    }, []);

    return (
        <div className="flex flex-col">
            {
                data != null ? <>
                    <Image src={Gambar} alt="Image" width={200} height={200} />
                    <h2>Heavy Component</h2>
                    <p>Title: {data.title}</p>
                    <p>Body: {data.body}</p>
                </> : 'Fetching data from API'
            }
        </div>
    );
};

export default HeavyComponent;
Enter fullscreen mode Exit fullscreen mode

Untuk hasilnya kurang lebih seperti ini, sama seperti tanpa menggunakan lazy loading :

Image description

Dan untuk hasil console menggunakan lazy loading seperti ini :

Image description

Kira-kira apakah hasil console tidak menggunakan dan menggunakan lazy loading ada perbedaannya? Ada dong. Mari kita bahas ya temen-temen.

Hasil console tanpa menggunakan lazy loading 2:
Image description

Hasil console menggunakan lazy loading 2
Image description

Ketika temen-temen tidak mengimplementasikan lazy loading maka 2 component tersebut akan dirender secara paralel atau secara bersamaan dan perubahan state maupun pemanggilan end point API pun juga dilakukan secara bersamaan. Akibatnya apa? bayangkan jika salah satu component punya behavior yang cukup berat atau proses render maupun proses pengambilan datanya membutuhkan waktu. Maka, component lainnya yang seharusnya sudah selesai render maka harus nunggu sampai component sebelumnya selesai di-render.

Render component secara paralel tanpa lazy loading:
Image description

Sedangkan, ketika kita mengimplementasikan lazy loading maka, masing-masing komponen itu tidak akan di-render secara bersama-sama tetapi akan di-render sesuai dengan urutannya. Selain itu, kita juga bisa memberikan UX (User Experience) dengan sebuah teks bahwa komponen tersebut sedang dimuat.

Render component secara bergantian menggunakan lazy loading:
Image description


Bagaimana? Apakah sudah ada gambaran pentingnya implementasi lazy loading pada aplikasi yang kita kembangkan menggunakan next js? Saya berharap artikel kali ini bisa memberikan ilmu tambahan untuk mengembangkan aplikasi menggunakan Next JS. Sampai bertemu di lain kesempatan dengan artikel yang lebih menarik lagi.

Top comments (0)