Menerapkan Skeleton Screens In React
Diterbitkan: 2022-03-10Pemintal dan pemuat secara tradisional menjadi cara untuk memberi tahu pengguna bahwa konten akan memakan waktu cukup lama untuk dimuat. Meskipun pendekatan ini bagus, pendekatan ini dengan cepat menjadi usang dalam perkembangan modern. Skeleton screen menjadi pengganti yang sempurna untuk loader tradisional karena mereka berfokus pada kemajuan daripada waktu tunggu, sehingga mengurangi frustrasi waktu pemuatan.
Dalam artikel ini, kita tidak akan membahas dasar-dasar CSS React atau sintaks JavaScript, jadi Anda tidak perlu menjadi ahli dalam salah satu bahasa ini untuk mengikutinya.
Pakar UI dan UX mengajari kami bahwa, sementara pengguna menunggu konten dimuat di halaman, kami harus membuat mereka tetap terlibat.
Ide di balik penggunaan pemintal untuk melibatkan pengguna sebelum konten dimuat sangat bagus; namun, hasilnya bisa jadi kurang ideal karena sebagian besar pengguna akan bosan menatap pemintal animasi tiruan seperti jam. Luke Wroblewski menguraikan hal ini.
Layar kerangka menawarkan pengalaman pengguna yang lebih baik dengan mengurangi frustrasi waktu pemuatan. Dengan berfokus pada kemajuan alih-alih waktu tunggu, ini menciptakan ilusi bagi pengguna bahwa informasi akan ditampilkan secara bertahap di layar. Bill Chung dalam penelitiannya menegaskan hal ini.
Apa itu Skeleton Screen?
Layar kerangka adalah versi UI yang tidak berisi konten sebenarnya; sebagai gantinya, ini meniru tata letak halaman dengan menunjukkan elemen-elemennya dalam bentuk yang mirip dengan konten sebenarnya saat dimuat dan tersedia (yaitu ketika latensi jaringan memungkinkan).
Layar kerangka pada dasarnya adalah bingkai gambar halaman, dengan kotak placeholder untuk teks dan gambar.
Apa yang Unik Tentang Skeleton Screen?
UI kerangka menyerupai UI halaman yang sebenarnya, sehingga pengguna akan memahami seberapa cepat web atau aplikasi seluler akan dimuat bahkan sebelum konten muncul. Berikut adalah beberapa alasan mengapa Anda mungkin ingin mempertimbangkan untuk menggunakan layar kerangka di proyek Anda berikutnya:
- meniru tata letak halaman lebih mudah dengan layar kerangka,
- konten dimuat secara progresif (tidak sekaligus).
Skeleton screen juga disebut sebagai:
- elemen hantu,
- penampung konten,
- pemuat konten.
Blockchain.com, YouTube, Facebook, Medium, dan perusahaan teknologi besar lainnya menampilkan layar kerangka sementara konten mereka dimuat untuk meningkatkan UX.
Blockchain.com
Sedang
Jenis Layar Kerangka
Ada berbagai jenis layar kerangka. Yang utama adalah placeholder teks dan placeholder gambar (atau warna).
Sebagian besar pengembang lebih suka menggunakan placeholder teks sebagai UI kerangka di halaman mereka karena mudah dibuat, dan pengembang tidak memerlukan detail apa pun tentang substansi konten yang sebenarnya; sebagai gantinya kerangka meniru UI.
Placeholder warna lebih sulit dibuat karena memerlukan detail tentang konten.
Beberapa paket populer membuat penerapan layar kerangka di aplikasi web menjadi lebih mudah. Mari kita lihat lebih dekat keduanya:
- React Placeholder
- Bereaksi Memuat Kerangka
Kita akan melihat pro dan kontra dari setiap paket, sebelum mempertimbangkan mana yang akan digunakan untuk aplikasi kita.
React Placeholder
kelebihan
- Komponen placeholder digunakan untuk membuat UI kerangka kustom.
- Animasi pulsa (yaitu efek gerakan pada elemen) didukung.
- Muncul dengan API berbasis komponen.
Kontra
- Komponen kerangka dipertahankan secara terpisah, jadi memperbarui gaya komponen mungkin memerlukan pembaruan komponen kerangka juga.
- Kurva belajar tidak linier karena ada beberapa komponen untuk kebutuhan yang berbeda.
Berikut ini adalah contoh komponen kerangka menggunakan paket react-placeholder
:
import { TextBlock, RectShape } from 'react-placeholder/lib/placeholders'; import ReactPlaceholder from 'react-placeholder'; const GhostPlaceholder = () => ( <div className='my-placeholder'> <RectShape color='gray' style={{width: 25, height: 70}} /> <TextBlock rows={6} color='blue'/> </div> ); <ReactPlaceholder ready={ready} customPlaceholder={<GhostPlaceholder />}> <MyComponent /> </ReactPlaceholder>
Mengimpor TextBlock
dan RectShape
dari react-placeholder/lib/placeholder
dan ReactPlaceholder
dari react-placeholder
, kami telah membuat komponen fungsional bernama GhostPlaceholder
. GhostPlaceholder
memiliki div, dan di dalam div kita telah menggunakan komponen RectShape, yang menjelaskan dimensi persegi panjang, meneruskan nilai warna apa pun, dan mendefinisikan gaya persegi panjang.
Selanjutnya, kami menggunakan komponen TextBlock
untuk mengatur nilai baris dan warna. Komponen TextBlock
mendefinisikan jumlah baris dan warna teks.
Kami meneruskan MyComponent
sebagai anak dari komponen ReactPlaceholder
, yang menerima ready
dan komponen GhostPlaceholder
sebagai nilai untuk props ready
dan customPlaceholder
.
MyComponent
akan dimuat saat UI layar kerangka ditampilkan.
Untuk mempelajari lebih lanjut, periksa dokumentasi.
Bereaksi Memuat Kerangka
kelebihan
- Ini berbasis API, dan memiliki satu komponen dengan alat peraga untuk semua penyesuaian.
- Ini dapat digunakan sebagai komponen kerangka terpisah dan juga di dalam komponen apa pun secara langsung, sehingga fleksibel.
- Ini mendukung tema dan animasi Pulse.
Kontra
- Sangat mudah diterapkan untuk UI kerangka sederhana, tetapi rumit untuk kerangka yang lebih kompleks.
- Memiliki komponen kerangka terpisah akan mempersulit pemeliharaan saat UI dan gaya berubah.
Berikut ini adalah contoh React Loading Skeleton:
import Skeleton, { SkeletonTheme } from "react-loading-skeleton"; const SkeletonComponent = () => ( <SkeletonTheme color="#202020" highlightColor="#444"> <section> <Skeleton height={50} width={50} /> </section> </SkeletonTheme> );
Kami telah mengimpor Skeleton
dan SkeletonTheme
dari perpustakaan react-loading-skeleton
, kemudian membuat komponen fungsional yang merender komponen SkeletonTheme
, dengan color
dan hightlightColor
sebagai properti.
Komponen SkeletonTheme
digunakan untuk tema (misalnya, menambahkan efek warna ke UI kerangka).
Terakhir, di dalam bagian, kita mendefinisikan komponen Skeleton
, dengan properti tinggi dan lebar dan nilai yang sesuai yang diteruskan.
Membangun UI Layar Kerangka Seperti YouTube
Mari buat layar kerangka seperti YouTube, menggunakan React Loading Skeleton, untuk menunjukkan cara kerja UI kerangka.
Mengatur Reaksi
Cara termudah untuk mengatur React adalah dengan menggunakan Create React App, yang merupakan “cara yang didukung secara resmi untuk membuat aplikasi React satu halaman. Ini menawarkan pengaturan build modern tanpa konfigurasi.”
Kita akan menggunakannya untuk bootstrap aplikasi yang akan kita bangun. Dari terminal Anda, jalankan perintah di bawah ini:
npx create-react-app skeleton-screens && cd skeleton-screens
Setelah instalasi selesai, jalankan server React dengan menjalankan npm start
:
Buat UI YouTube Tanpa Layar Kerangka
Pertama, mari kita masukkan data dummy YouTube. Titik akhir nyata biasanya digunakan sebagai pengganti data dummy, tetapi dalam tutorial ini kita akan menggunakan data dummy.
Buat file di folder src/
Anda, dan beri nama data.js
, tambahkan kode berikut ke dalamnya.
const dummyData= [ { section: "Recommended", channel: "CNN", items: [ { id: "fDObf2AeAP4", image: "https://img.youtube.com/vi/fDObf2AeAP4/maxresdefault.jpg", title: "75 million Americans ordered to stay home", views: "1.9M views", published: "3 days agos" }, { id: "3AzIgAa0Cm8", image: "https://img.youtube.com/vi/3AzIgAa0Cm8/maxresdefault.jpg", title: "Gupta: The truth about using chloroquine to fight coronavirus pandemic", views: "128K views", published: "4 hours ago" }, { id: "92B37aXykYw", image: "https://img.youtube.com/vi/92B37aXykYw/maxresdefault.jpg", title: "Willie Jones STUNS Simon Cowell In Pitch Perfect Performance of 'Your Man'!", views: "2.47 million views", published: "1 month ago" }, { id: "J6rVaFzOEP8", image: "https://img.youtube.com/vi/J6rVaFzOEP8/maxresdefault.jpg", title: "Guide To Becoming A Self-Taught Software Developer", views: "104K views", published: "17 days ago" }, { id: "Wbk8ZrfU3EM", image: "https://img.youtube.com/vi/Wbk8ZrfU3EM/maxresdefault.jpg", title: "Tom Hanks and Rita Wilson test positive for coronavirus", views: "600k views", published: "1 week ago" }, { id: "ikHpFgKJax8", image: "https://img.youtube.com/vi/ikHpFgKJax8/maxresdefault.jpg", title: "Faces Of Africa- The Jerry Rawlings story", views: "2.3 million views", published: "2014" } ] }, { section: "Breaking News", channel: "CGTN America", items: [ { id: "tRLDPy1A8pI", image: "https://img.youtube.com/vi/tRLDPy1A8pI/maxresdefault.jpg", title: "Is Trump blaming China for COVID-19? You decide.", views: "876k views", published: "9 days ago" }, { id: "2ulH1R9hlG8", image: "https://img.youtube.com/vi/2ulH1R9hlG8/maxresdefault.jpg", title: "Journalist still goes to office during pandemic, see her daily routine", views: "873 views", published: "3 hours ago" }, { id: "TkfQ9MaIgU", image: "https://img.youtube.com/vi/_TkfQ9MaIgU/maxresdefault.jpg", title: "How are small businesses going to survive the economic downturn of the COVID-19 era?", views: "283 views", published: "4 day ago" } ] } ]; export default dummyData;
Untuk mereplikasi format YouTube, kami telah membuat data dummy yang memiliki larik objek, dengan properti seperti ID, gambar, judul, jumlah penayangan, dan tanggal publikasi.
Selanjutnya, mari kita buat UI YouTube kita. Kami akan memiliki tiga komponen:
Card | Menyimpan detail gambar mini, judul, jumlah penayangan, tanggal publikasi, dan saluran video. |
CardList | Mengembalikan semua kartu secara berurutan. |
App | Memasang objek dummyData kita, memuat UI kerangka selama dua detik, dan mengembalikan komponen CardList . |
Di dalam folder src
Anda, buat folder dan beri nama components
. Di dalam folder components
, buat file Card.js
, tambahkan kode berikut ke dalamnya:
import React from "react"; const Card = ({ item, channel }) => { return ( <li className="card"> <a href={`https://www.youtube.com/watch?v=${item.id}`} target="_blank" rel="noopener noreferrer" className="card-link" > <img src={item.image} alt={item.title} className="card-image" /> <img src={item.image} alt={item.title} className="channel-image" /> <h4 className="card-title">{item.title}</h4> <p className="card-channel"> <i>{channel}</i> </p> <div className="card-metrics"> {item.views} • {item.published} </div> </a> </li> ); }; export default Card;
Kami membuat komponen Card
. Di dalamnya, kami mengimpor React
dari react
, dan kami mendekonstruksi item
dan channel
props sehingga dapat digunakan di seluruh komponen Card
. Setiap komponen item Card
yang menampilkan satu video akan menampilkan gambar mini, jumlah penayangan, tanggal publikasi, dan judul.
Komponen Daftar Kartu
Di dalam folder components
, buat file CardList.js dan tambahkan kode berikut ke dalamnya:
import React from "react"; import Card from "./Card"; const CardList = ({ list }) => { return ( <ul className="list"> {list.items.map((item, index) => { return <Card key={index} item={item} channel={list.channel} />; })} </ul> ); }; export default CardList;
Pada komponen ini, kita telah mengimpor komponen Card
yang telah kita buat. Kartu menerima alat peraga item
dan channel
, yang kita dapatkan dengan memetakan melalui list.items
. Kami kemudian mengekspor komponen ini sebagai CardList
, karena kami akan menggunakannya di komponen App
kami.
Catatan : Array item yang dipetakan dalam komponen ini adalah array objek di dummyData
kita.
Komponen Aplikasi
Di dalam file app.js di direktori src/
, hapus kode yang ada di sana dan tambahkan kode berikut ke dalamnya.
import React, { useState, useEffect } from "react"; import "./App.css"; import dummyData from "./data"; import CardList from "./components/CardList"; const App = () => { const [videos, setVideos] = useState([]); const [loading, setLoading] = useState(false); useEffect(() => { setLoading(true); const timer = setTimeout(() => { setVideos(dummyData); setLoading(false); }, 5000); return () => clearTimeout(timer); }, []); return ( <div className="App"> { videos.map((list, index) => { return ( <section key={index}> <h2 className="section-title">{list.section}</h2> <CardList list={list} /> <hr /> </section> ); })} </div> ); }; export default App;
Dalam komponen ini, kami telah mengimpor kait useState
dan useEffect
bersama React
dan file lain yang telah kami buat dan yang akan dibutuhkan dalam komponen App
.
Karena data kita adalah data dummy, kita perlu menirunya seperti data API dengan memuat konten setelah batas waktu dua detik, menggunakan metode JavaScript setTimeout
.
Selanjutnya, di komponen App
, kita membuat status video, dan menyetel status ke array kosong menggunakan useState
.
Untuk memuat data dummy kita, kita akan menggunakan hook useEffect
. Di hook kami, kami membuat timer variabel yang memegang fungsi setTimeout
()
. Di dalam fungsi, kami mengatur status video kami ke objek dummyData
kami, dan kami memastikan bahwa data dimuat setelah dua detik, dan, terakhir, kami membatalkan penghitung waktu saat melepas.
Terakhir, kami memetakan melalui status video kami dan mengembalikan elemen bagian yang berisi bagian list-section
dan komponen CardList
dengan props daftarnya.
Menambahkan CSS
Sampai sekarang, kami telah menggunakan banyak kelas tanpa CSS yang sebenarnya. Di dalam folder src
, hapus semua yang ada di App.css
dan ganti dengan kode berikut;
.App { max-width: 960px; margin: 0 auto; font-size: 16px; } .list { display: flex; justify-content: space-between; flex-wrap: wrap; list-style: none; padding: 0; } .section-title { margin-top: 30px; } .card { width: calc(33% - 10px); margin: 20px 0; } .card-link { color: inherit; text-decoration: none; } .card-image { width: 100%; } .channel-image { border-radius: 100%; padding: 0, 10px, 0, 0; width: 40px; height: 40px; } .card-title { margin-top: 10px; margin-bottom: 0; } .card-channel { margin-top: 5px; margin-bottom: 5px; font-size: 14px; } /* Tablets */ @media (max-width: 1000px) { .App { max-width: 600px; } .card { width: calc(50% - 22px); } } /* Mobiles \*/ @media (max-width: 640px) { .App { max-width: 100%; padding: 0 15px; } .card { width: 100%; } }
Mari kita lihat seperti apa UI YouTube kita tanpa layar kerangka. Anda dapat melihat bahwa ketika halaman dimuat, layar putih muncul selama dua detik, dan kemudian data segera dimuat.
Menggunakan React Loading Skeleton
Tidak seperti perpustakaan lain di mana Anda akan dengan cermat menyusun layar kerangka agar sesuai dengan ukuran font, tinggi garis, dan margin konten Anda, komponen Skeleton
dirancang untuk digunakan langsung di komponen Anda, menggantikan konten yang sedang dimuat.
Mari membahas beberapa alasan mengapa kami memilih React Loading Skeleton daripada yang lain.
Bertema
React Loading Skeleton mendukung tema. Dengan demikian, Anda dapat dengan mudah mengubah warna semua komponen kerangka dengan menggunakan SkeletonTheme
dan meneruskan nilai ke props
warna .
Di bawah ini adalah contoh yang menunjukkan cara kerjanya:
import Skeleton, { SkeletonTheme } from "react-loading-skeleton"; <SkeletonTheme color="grey" highlightColor="#444"> <p> <Skeleton height={250} width={300} count={1} /> </p> </SkeletonTheme> <SkeletonTheme color="#990" highlightColor="#550"> <p> <Skeleton height={250} width={300} count={1} /> </p> </SkeletonTheme>
Durasi
Selain height
, width
, dan color
props, kami juga dapat menentukan duration
prop.
<Skeleton duration={2} />
Durasi default ke 1.2
. Ini menentukan berapa lama waktu yang dibutuhkan untuk melakukan satu siklus animasi kerangka.
Untuk mempelajari lebih lanjut, lihat dokumentasi.
Menerapkan UI Layar Kerangka
Sekarang, kita akan menginstal react-loading-skeleton
. Jalankan perintah berikut di terminal Anda untuk menginstal paket:
npm install react-loading-skeleton
Komponen kerangka
Mari buat komponen kerangka untuk data video kita. Di dalam folder components
kami, buat file SkeletonCard.js
, dan tambahkan kode berikut:
import React from "react"; import Skeleton from "react-loading-skeleton"; const SkeletonCard = () => { return ( <section> <h2 className="section-title"> <Skeleton height={30} width={300} /> </h2> <ul className="list"> {Array(9) .fill() .map((item, index) => ( <li className="card" key={index}> <Skeleton height={180} /> <h4 className="card-title"> <Skeleton circle={true} height={50} width={50} /> <Skeleton height={36} width={`80%`} /> </h4> <p className="card-channel"> <Skeleton width={`60%`} /> </p> <div className="card-metrics"> <Skeleton width={`90%`} /> </div> </li> ))} </ul> </section> ); }; export default SkeletonCard;
Kami telah membuat daftar yang tidak berurutan. Di dalamnya, kami telah menggunakan metode Array.fill()
. Karena kita memiliki sembilan item data dummy, kita telah menggunakan metode Array.fill()
untuk mengulang panjang objek items
kita dan mengisinya tanpa nilai indeks, sehingga membuat array kita kosong . Lihat dokumentasi Array.fill untuk mempelajari cara kerjanya.
Selanjutnya, kami memetakan melalui array kosong kami untuk mengembalikan daftar yang berisi properti kerangka, dan kami menentukan nilai masing-masing properti kerangka.
Di sini, height
berkonotasi dengan panjang persegi panjang kerangka, dan width
mengacu pada lebar, sementara circle
membuat bagian bulat dari UI kerangka.
React Loading Skeleton hadir dengan animasi Pulse default, yang membuatnya praktis. Anda dapat membuat animasi Pulse agar sesuai dengan proyek Anda, tetapi jika Anda bertanya kepada saya, saya akan tetap menggunakan default.
Akhirnya, kode sumber lengkap tersedia.
Kami sekarang memiliki UI layar kerangka yang berfungsi penuh. Contoh kami menunjukkan kerangka selama lima detik sebelum menampilkan konten.
Mari kita lihat hasil kita sejauh ini:
Kesimpulan
Layar kerangka sangat meningkatkan pengalaman pengguna dengan menghindari frustrasi menghadapi layar yang sepenuhnya kosong dan memberi kesan kepada pengguna tentang seperti apa tampilan konten sebelum dimuat.
Jika Anda tidak nyaman dengan salah satu paket yang telah kami lihat, Anda dapat membuat UI kerangka Anda sendiri dengan membuat persegi panjang dan lingkaran yang meniru tata letak halaman.
Silakan bagikan umpan balik dan pengalaman Anda di bagian komentar di bawah. Saya ingin melihat apa yang Anda dapatkan!
Repo pendukung untuk artikel ini tersedia di Github.
Referensi
- “Semua yang Perlu Anda Ketahui Tentang Skeleton Screen”, Bill Chung, Kolektif UX
- “Halaman Pemuatan Kerangka Dengan Bereaksi”, Anthony Panagi, Gurita Kekayaan
- “Layar Kerangka Dengan Bereaksi Dan Bereaksi Asli”, Chris Dolphin, Alligator.io
- “Implementasi Skeleton Loading In React”, Adrian Bece, DEV