Membuat Skeleton Screen di React JS

Membuat Skeleton Screen di React JS

Implementasi Skeleton Screen Loading di Aplikasi React JS

Penggunaan Spinner untuk digunakan pada loading screen dianggap cepat usang di jaman pengembangan modern seperti saat ini. Selain itu juga, penggunaan Spinner pada loading screen juga memiliki user experience ( UX ) yang kurang baik, karena penggunaan Spinner lebih mengfokuskan kepada indicator bukan pada progress, sehingga berkesan bahwa seorang pengguna itu harus menunggu. Dengan kesan seolah-olah menunggu dan terlebih lagi bentuk Spinners yang seperti bentuk jam tersebut, membuat waktu terasa lebih lambat dan hal tersebut pun berdampak pada aplikasi kita, pengguna menganggap seolah-olah waktu loading data aplikasi kita seperti lebih lambat.

Hal tersebut dijelaskan pada blog Luke Wroblewski pada eksperimennya dengan aplikasi Polar.

Untuk menggantikan Spinner pada loading screen, kita bisa menggunakan Skeleton Screens. Skeleton screens dianggap lebih memiliki user experience ( UX ) yang lebih baik dibandingkan Spinners. Mengapa demikian, menurut Luke Wroblewski pada tulisannya mengatakan

With a skeleton screen, the focus is on content being loaded not the fact that its loading and that’s real progress.

Dengan berfokus pada progress, user menganggap bahwa informasi atau data akan muncul pada layar secara bertahap dan ini baik untuk user experience ( UX ) dibandingkan harus menunggu seperti pada penggunaan Spinners. Hal tersebut dapat kita lihat dan konfirmasi juga kebenarannya pada penelitian oleh Bill Chung.

Jadi, apa itu Skeleten Screen ?

Pernah lihat seperti ini ketika mengakses halaman Youtube atau Linkedin ? youtube-linkedin-skeleton.png

Ya itulah yang dinamakan dengan Skeleton Screen.

Atau definisinya, Skeleton Screen adalah sebuah elemen yang layoutnya menyerupai seperti konten aslinya dan biasanya berwarna abu-abu. Skeleton screen itu muncul beberapa saat sebelum data seperti teks, video dan gambar muncul.

Membuat Skeleton Screen di React

Kita akan mencoba membuat Skeleton Screen di React pada projek yang sebelumnya saya buat yaitu Hashnode GraphQL di React. Kalian bisa membacanya terlebih dahulu atau kalian juga bisa clone projeknya di Github.

$ git clone https://github.com/juliansyahrifqi/hashnode-api-reactjs.git
$ cd hashnode-api-reactjs
$ npm install
$ npm start

Setelah itu kita buat folder baru dengan nama skeletons di dalam folder src.

Membuat Skeleton Element

Skeleton Element ini adalah sebuah reuseable komponen yang menerima sebuah props dengan nama element. Nantinya Skeleton Element ini akan merender komponen sesuai dengan props yang diterima, apakah elemen itu berupa gambar, teks atau judul.

Kita buat file dengan nama SkeletonElement.js di dalam folder skeletons.

import React from 'react';

const SkeletonElement = ({ element }) => {
    const classElement = `skeleton ${element}`;

    return (
        <div className={classElement}></div>
    )
}

export default SkeletonElement;

Selanjutnya kita tambahkan sebuah styling untuk skeleton elementnya.

.skeleton {
    background: #ddd;
    border-radius: 4px;
}

.skeleton.image {
    width: 350px;
    height: 180px;
    border-radius: 10px;
}

.skeleton.title {
    width: 80%;
    height: 25px;
    margin-top: 15px;
}

.skeleton.date {
    width: 40%;
    height: 12px;
    margin: 15px 0;
}

.skeleton.text {
    width: 100%;
    height: 15px;
    margin-top: 8px;
}

Jangan lupa untuk mengimport Skeleton.css di SkeletonElement.js

.  .  .
import './Skeleton.css';

.  .  .
.  .  .

Membuat Skeleton Post

Skeleton Post ini adalah komponen skeleton yang menyerupai dengan layout konten aslinya. Di dalam Skeleton Post ini kita akan memanggil komponen Skeleton Element dan melempar sebuah props element yang akan diisi sesuai dengan layout konten asli.

skeleton-element.png

Kita buat file dengan nama SkeletonPost.js di dalam folder skeletons.

import React from 'react';
import SkeletonElement from './SkeletonElement';
import './Skeleton.css';

const SkeletonPost = () => {
    return (
        <div className="skeleton-posts">
            <SkeletonElement element="image" />
            <SkeletonElement element="title" />
            <SkeletonElement element="date" />
            <hr></hr>
            <SkeletonElement element="text" />
            <SkeletonElement element="text" />
            <SkeletonElement element="text" />
        </div>
    )
}

export default SkeletonPost;

Setelah itu, kita coba jalankan skeleton screen kita, caranya buka file src/components/BlogPost.js. Pada bagian <div className="post"> kita tambahkan kode dibawah ini.

.  .  .

{!posts && (
    <div className="skeleton-container">
         {[1, 2, 3, 4, 5, 6].map((n) => <SkeletonPost key={n} />)}
    </div>
)}

Kode tersebut maksudnya adalah, ketika state posts isinya masih null, maka kita tampilkan komponen SkeletonPost sebanyak 6 kali, sampai data state posts sudah terisi ( tidak berisi null ).

Jika kita refresh halaman localhost:3000, maka tampilannya akan seperti ini.

ezgif-3-bce1a37748fe.gif

Nah, skeleton screen kita sudah tampil. Selanjutnya agar tampilannya lebih bagus kita tambahkan styling pada Skeleton.css.

.skeleton-container {
    width: 90%;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    margin: 60px auto;
}

.skeleton-posts {
    width: 350px;
    height: auto;
    border-radius: 10px;
    padding: 15px;
    margin-bottom: 50px;
    background: #f2f2f2;
    position: relative;
    overflow: hidden;
}

Setelah diberi styling, maka tampilannya akan menjadi seperti ini.

skeleton-card.gif

Menambah Animasi

Agar lebih menarik ketika dilihat, kita coba tambahkan sedikit animasi berkilau atau shimmer.

Kita buat file dengan nama Shimmer.js di dalam folder skeletons.

import React from 'react';
import './Skeleton.css';

const Shimmer = () => {
    return (
        <div className="shimmer-container">
            <div className="shimmer"></div>
        </div>
    )
}

export default Shimmer;

Tambahkan styling untuk membuat animasinya.

.shimmer-container {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    animation: shimmering 2.3s infinite;
}

.shimmer {
    width: 50%;
    height: 100%;
    background: rgba(255, 255, 255, 0.3);
    box-shadow: 0 0 30px 30px rgba(255, 255, 255, 0.05);
    transform: skewX(10deg);
}

@keyframes shimmering {
    0% {
        transform: translateX(-180%);
    }

    50% {
        transform: translateX(-80%);
    }

    100% {
        transform: translateX(180%);
    }
}

Kita tambahkan animasi atau effek shimmering tersebut ke dalam komponen SkeletonPost. Tambahkan tag dibawah ke dalam <div className="skeleton-posts">

<Shimmer />

Dan jangan lupa import terlebih dahulu efek shimmernya di dalam SkeletonPost.js

import Shimmer from './Shimmer';

Setelah itu, agar efek shimmer ini terlihat, kita beri waktu pada saat melakukan fetch ke Hashnode API selama 4 detik, agar skeleton screen kita tampil lebih lama.

Pada file src/components/BlogPost.js kita gantu fungsi fetchAPI pada useEffect dengan kode dibawah ini.

setTimeout(async () => {
    const response = await fetch('https://api.hashnode.com', {
        method: 'POST',
        headers: {
           'Content-type': 'application/json',
        },
       body: JSON.stringify({ query }),
    })
   const responseData = await response.json();

   setPosts(responseData.data.user.publication.posts);
}, 4000);

Jika kita refresh halaman localhost:3000 kita, maka tampilannya pun akan seperti ini.

shimmering.gif


Hooray! Kita sudah berhasil membuat sebuah skeleton screen. Kalian bisa melihat live website diatas disini dan untuk source code bisa dilihat di Github.

Terima kasih sudah membaca tulisan ini, jika ada masukkan atau pertanyaan bisa melalui kolom komentar. See you next time!


Sumber: