React'te İskelet Ekranlarını Uygulamak

Yayınlanan: 2022-03-10
Hızlı özet ↬ Bu eğitimde, bir iskelet ekran kullanıcı arayüzünün ne olduğunu ve bazı iskelet ekran kitaplık türlerini artıları ve eksileriyle birlikte öğreneceksiniz. React Loading Skeleton'ı kullanarak YouTube benzeri bir iskelet ekran arayüzü oluşturacağız. Ardından, seçtiğiniz iskelet ekran React paketi ile kendi başınıza deney yapabilirsiniz.

Döndürücüler ve yükleyiciler, geleneksel olarak kullanıcılara içeriğin yüklenmesinin biraz zaman alacağını söylemenin yolu olmuştur. Bu yaklaşım harika olsa da, modern gelişimde hızla modası geçiyor. İskelet ekranlar, bekleme süreleri yerine ilerlemeye odaklandıkları ve dolayısıyla yükleme süresi sıkıntısını azalttığı için geleneksel yükleyiciler için mükemmel bir yedek haline geliyor.

Bu makalede, CSS React veya JavaScript sözdiziminin temellerini ele almayacağız, bu nedenle takip etmek için bu dillerden herhangi birinde uzman olmanıza gerek yok.

Bir yükleyici ve bir iskelet ekran kullanıcı arayüzü arasındaki fark
Yükleyici ve iskelet ekran kullanıcı arayüzü arasındaki fark (Geniş önizleme)

UI ve UX uzmanları bize, kullanıcılar bir sayfada içeriğin yüklenmesini beklerken onları etkileşimde tutmamız gerektiğini öğretiyor.

İçerik yüklenmeden önce kullanıcılarla etkileşim kurmak için döndürücüleri kullanmanın ardındaki fikir harika; ancak sonuç idealden daha az olabilir çünkü çoğu kullanıcı bir saatmiş gibi yapay bir animasyonlu çarka bakmaktan sıkılır. Luke Wroblewski bunu detaylandırıyor.

İskelet ekranlar, yükleme süresi sıkıntısını azaltarak daha iyi bir kullanıcı deneyimi sunar. Bekleme süreleri yerine ilerlemeye odaklanarak, kullanıcılar için bilgilerin ekranda kademeli olarak görüntüleneceği yanılsamasını yaratır. Bill Chung araştırmasında bunu doğruluyor.

İskelet Ekran Nedir?

İskelet ekran, gerçek içerik içermeyen kullanıcı arayüzünün bir sürümüdür; bunun yerine, yüklenirken ve kullanılabilir hale geldiğinde (yani ağ gecikmesi izin verdiğinde) öğelerini gerçek içeriğe benzer bir şekilde göstererek sayfanın düzenini taklit eder.

Bir iskelet ekran, metin ve resimler için yer tutucu kutuları olan, esasen sayfanın bir tel çerçevesidir.

Atlamadan sonra daha fazlası! Aşağıdan okumaya devam edin ↓

Bir İskelet Ekranının Benzersiz Olması Nedir?

Bir iskelet kullanıcı arayüzü, sayfanın gerçek kullanıcı arayüzüne benzer, böylece kullanıcılar, web veya mobil uygulamanın ne kadar hızlı yükleneceğini, içerik görünmeden önce bile anlar. Bir sonraki projenizde iskelet ekranları kullanmayı düşünmek isteyebileceğiniz birkaç neden:

  • bir sayfanın düzenini taklit etmek, bir iskelet ekranla daha kolaydır,
  • içerik aşamalı olarak yüklenir (tümü aynı anda değil).

İskelet ekranlara ayrıca şu adlar da verilir:

  • hayalet öğeler,
  • içerik yer tutucuları,
  • içerik yükleyiciler

Blockchain.com, YouTube, Facebook, Medium ve diğer büyük teknoloji şirketleri, UX'i artırmak için içerikleri yüklenirken iskelet ekranlar görüntüler.

Blockchain.com

Blockchain.com iskelet ekranı kullanıcı arayüzü
Blockchain.com'un kısmen yüklenmiş durumu (grafik analizinde bir iskeletin nasıl kullanıldığına dikkat edin) (Büyük önizleme)

Orta

Orta iskelet ekran kullanıcı arayüzü
Medium'un iskelet kullanıcı arayüzü (Büyük önizleme)

LinkedIn

LinkedIn iskelet ekranı kullanıcı arayüzü
LinkedIn'in 2018'deki ana sayfa besleme yükleme durumu (Büyük önizleme)

İskelet Ekran Çeşitleri

Farklı türde iskelet ekranları vardır. Başlıcaları metin yer tutucuları ve resim (veya renk) yer tutucularıdır.

Çoğu geliştirici, oluşturmaları kolay olduğundan ve geliştirici gerçek içeriğin özü hakkında herhangi bir ayrıntıya ihtiyaç duymadığından sayfalarında iskelet kullanıcı arayüzü olarak metin yer tutucularını kullanmayı tercih eder; bunun yerine iskelet, kullanıcı arayüzünü taklit eder.

İçerikle ilgili ayrıntılar gerektirdiğinden, renk yer tutucularının oluşturulması daha zordur.

Bazı popüler paketler, web uygulamalarında iskelet ekranların uygulanmasını kolaylaştırır. Her ikisine de daha yakından bakalım:

  • Tepki Yer Tutucu
  • Tepki Yükleme İskeleti

Uygulamamız için hangisini kullanacağımızı düşünmeden önce her paketin artılarına ve eksilerine bakacağız.

Tepki Yer Tutucu

Artıları

  • Yer tutucu bileşenleri, özel bir iskelet kullanıcı arabirimi oluşturmak için kullanılır.
  • Darbe animasyonu (yani bir öğe üzerindeki hareket efekti) desteklenir.
  • Bileşen tabanlı bir API ile birlikte gelir.

Eksileri

  • İskelet bileşenleri ayrı olarak korunur, bu nedenle bir bileşenin stillerinin güncellenmesi muhtemelen iskelet bileşeninin de güncellenmesini gerektirir.
  • Öğrenme eğrisi doğrusal değildir çünkü farklı ihtiyaçlar için birden fazla bileşen vardır.

Aşağıdaki, react-placeholder paketini kullanan bir iskelet bileşeni örneğidir:

 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>

TextBlock ve RectShape react-placeholder/lib/placeholder ve ReactPlaceholder react-placeholder tutucudan içe aktararak GhostPlaceholder adlı işlevsel bir bileşen oluşturduk. GhostPlaceholder bir div'i vardır ve div'in içinde bir dikdörtgenin boyutlarını tanımlayan, herhangi bir rengin değerini ileten ve dikdörtgenin stillerini tanımlayan RectShape bileşenini kullandık.

Daha sonra, satır ve renk değerlerini ayarlamak için TextBlock bileşenini kullandık. TextBlock bileşeni, metnin satır sayısını ve rengini tanımlar.

MyComponent , ready ve ready destekleri için değerler olarak GhostPlaceholder bileşenini alan ReactPlaceholder bileşeninin bir çocuğu olarak customPlaceholder .

MyComponent , iskelet ekranı UI gösterildiğinde yüklenecektir.

Daha fazla bilgi edinmek için belgelere bakın.

Tepki Yükleme İskeleti

Artıları

  • API tabanlıdır ve tüm özelleştirmeler için aksesuarlara sahip tek bir bileşene sahiptir.
  • Ayrı bir iskelet bileşeni olarak ve ayrıca herhangi bir bileşenin içinde doğrudan kullanılabilir, bu nedenle esnektir.
  • Tema oluşturmayı ve Darbe animasyonunu destekler.

Eksileri

  • Basit bir iskelet kullanıcı arayüzü için uygulanması kolaydır, ancak daha karmaşık iskeletler için karmaşıktır.
  • Ayrı bir iskelet bileşenine sahip olmak, kullanıcı arayüzü ve stiller değiştiğinde bakımı zorlaştıracaktır.

Aşağıdaki, React Loading Skeleton'un bir örneğidir:

 import Skeleton, { SkeletonTheme } from "react-loading-skeleton"; const SkeletonComponent = () => ( <SkeletonTheme color="#202020" highlightColor="#444"> <section> <Skeleton height={50} width={50} /> </section> </SkeletonTheme> );

react-loading-skeleton kitaplığından Skeleton ve SkeletonTheme içe aktardık, ardından color ve hightlightColor özellikleriyle SkeletonTheme bileşenini oluşturan işlevsel bir bileşen oluşturduk.

SkeletonTheme bileşeni, tema oluşturmak için kullanılır (örneğin, iskelet kullanıcı arayüzüne renk efektleri ekleme).

Son olarak, bölüm içinde, yükseklik ve genişlik özellikleri ve bunların uygun değerleri iletilmiş olan Skeleton bileşenini tanımlıyoruz.

YouTube Benzeri Bir İskelet Ekran Kullanıcı Arayüzü Oluşturma

Bir iskelet kullanıcı arayüzünün nasıl çalıştığını göstermek için React Loading Skeleton kullanarak YouTube benzeri bir iskelet ekranı oluşturalım.

React'i Ayarla

React'i kurmanın en kolay yolu, "tek sayfalı React uygulamaları oluşturmanın resmi olarak desteklenen bir yolu" olan Create React App'i kullanmaktır. Konfigürasyon gerektirmeyen modern bir yapı kurulumu sunuyor.”

Oluşturacağımız uygulamayı önyüklemek için kullanacağız. Terminalinizden aşağıdaki komutu çalıştırın:

 npx create-react-app skeleton-screens && cd skeleton-screens

Kurulum tamamlandıktan sonra, npm start çalıştırarak React sunucusunu başlatın:

React uygulaması - Scaffold React uygulaması
Tepki karşılama sayfası (Büyük önizleme)

İskelet Ekranı Olmadan YouTube Kullanıcı Arayüzü Oluşturun

İlk olarak, YouTube kukla verilerini girelim. Normalde kukla veriler yerine gerçek uç noktalar kullanılır, ancak bu eğitimde kukla verileri kullanacağız.

src/ klasörünüzde bir dosya oluşturun ve data.js olarak adlandırın, aşağıdaki kodu ekleyin.

 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;

YouTube'un biçimini kopyalamak için kimlik, resim, başlık, görüntüleme sayısı ve yayın tarihi gibi özelliklere sahip bir dizi nesneye sahip yapay veriler oluşturduk.

Ardından, YouTube UI'mizi oluşturalım. Üç bileşenimiz olacak:

Card Videonun küçük resminin, başlığının, görüntülenme sayısının, yayın tarihinin ve kanalının ayrıntılarını içerir.
CardList Tüm kartları arka arkaya döndürür.
App dummyData , iki saniye için iskelet kullanıcı arabirimini yükler ve CardList bileşenini döndürür.

src klasörünüzün içinde bir klasör oluşturun ve onu components olarak adlandırın. components klasörünün içinde bir Card.js dosyası oluşturun ve buna aşağıdaki kodu ekleyin:

 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;

Bir Card bileşeni oluşturduk. Bunun içinde, react öğesinden React içe aktardık ve Card bileşeninde kullanılabilecekleri şekilde item ve channel aksesuarlarını bozduk. Bir video görüntüleyen her Card öğesi bileşeni, küçük resmi, görüntüleme sayısını, yayın tarihini ve başlığı gösterir.

CardList Bileşeni

components klasörünün içinde bir CardList.js dosyası oluşturun ve buna aşağıdaki kodu ekleyin:

 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;

Bu bileşende, oluşturduğumuz Card bileşenini içe aktardık. Kart, list.items aracılığıyla eşleştirerek elde ettiğimiz item ve channel aksesuarlarını kabul eder. Daha sonra bu bileşeni CardList olarak dışa aktarırız çünkü onu App bileşenimizde kullanacağız.

Not : Bu bileşende eşlenen öğeler dizisi, dummyData nesnelerin dizisidir.

Uygulama Bileşeni

src/ dizinindeki app.js dosyasının içinde orada bulunan kodu silin ve aşağıdakini ekleyin.

 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;

Bu bileşende, React ve oluşturduğumuz ve App bileşeninde gerekli olacak diğer dosyaların yanı sıra useState ve useEffect kancalarını içe aktardık.

Verilerimiz yapay veriler olduğundan, JavaScript setTimeout yöntemini kullanarak içeriği iki saniyelik bir zaman aşımından sonra yükleyerek API verileri gibi taklit etmemiz gerekir.

Ardından, App bileşeninde bir video durumu oluşturuyoruz ve durumu useState kullanarak boş bir diziye ayarlıyoruz.

Sahte verilerimizi yüklemek için useEffect kancasını kullanacağız. Kancamızda, setTimeout () işlevini tutan değişken bir zamanlayıcı oluşturuyoruz. Fonksiyon içerisinde video durumumuzu dummyData ve verilerin iki saniye sonra yüklenmesini sağlıyoruz ve son olarak demonte ederken timer'ı iptal ediyoruz.

Son olarak, video durumumuzla eşleşiriz ve list-section içeren bölüm öğesini ve liste destekleriyle CardList bileşenini döndürürüz.

CSS ekleme

Şimdiye kadar, gerçek CSS'siz birçok sınıf kullandık. src klasörünün içinde, App.css içindeki her şeyi silin ve aşağıdaki kodla değiştirin;

 .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%; } }

Bakalım iskelet ekran olmadan YouTube kullanıcı arayüzümüz nasıl görünüyor. Sayfa yüklendiğinde, iki saniye boyunca beyaz bir ekranın göründüğünü ve ardından verilerin hemen yüklendiğini görebilirsiniz.

İskelet ekranı olmayan YouTube benzeri kullanıcı arayüzü
İskelet ekranı olmayan YouTube benzeri kullanıcı arayüzü (Büyük önizleme)

Tepki Yükleme İskeletini Kullanma

İçeriğinizin yazı tipi boyutlarına, satır yüksekliklerine ve kenar boşluklarına uyması için titizlikle bir iskelet ekran oluşturacağınız diğer kitaplıkların aksine, Skeleton bileşeni, yüklenen içeriğin yerine doğrudan bileşenlerinizde kullanılmak üzere tasarlanmıştır.

Diğerleri yerine React Loading Skeleton'ı seçmemizin birkaç nedenini gözden geçirelim.

Temalandırma

React Loading Skeleton tema oluşturmayı destekler. Böylece SkeletonTheme kullanarak tüm iskelet bileşenlerinin renklerini kolayca değiştirebilir ve renk props değerler iletebilirsiniz.

Aşağıda nasıl çalıştığını gösteren bir örnek verilmiştir:

 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> 
Eylemde tema efekti
Eylem halinde tema efekti (Büyük önizleme)

Süre

height , width ve color unsurlarına ek olarak, bir duration unsuru da belirtebiliriz.

 <Skeleton duration={2} />

Süre varsayılan olarak 1.2 . Bu, iskelet animasyonunun bir döngüsünün ne kadar süreceğini belirler.

Daha fazla bilgi edinmek için belgelere bakın.

İskelet Ekranı Kullanıcı Arayüzü Uygulama

Şimdi, react-loading-skeleton . Paketi kurmak için terminalinizde aşağıdaki komutu çalıştırın:

 npm install react-loading-skeleton

İskelet Bileşeni

Video verilerimiz için bir iskelet bileşeni oluşturalım. components klasörümüzün içinde bir SkeletonCard.js dosyası oluşturun ve aşağıdaki kodu ekleyin:

 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;

Sırasız bir liste oluşturduk. Bunun içinde Array.fill() yöntemini kullandık. Dokuz yapay veri öğemiz olduğundan, items nesnemizin uzunluğu boyunca döngü yapmak için Array.fill() yöntemini kullandık ve onu dizin değeri olmadan doldurduk, bu nedenle dizimizi boş hale getirdik. Nasıl çalıştığını öğrenmek için Array.fill belgelerine bakın.

Daha sonra, iskelet özelliklerini içeren bir liste döndürmek için boş dizimizi eşledik ve her bir iskelet özelliğinin değerini belirledik.

Burada height , bir iskelet dikdörtgeninin uzunluğunu ifade eder ve width , genişliği ifade ederken, circle , iskelet kullanıcı arayüzünün yuvarlak kısmını oluşturur.

React Loading Skeleton, varsayılan Pulse animasyonu ile birlikte gelir, bu da onu kullanışlı kılar. Projenize uyacak şekilde Darbe animasyonu oluşturabilirsiniz, ancak bana sorarsanız varsayılana sadık kalırdım.

Son olarak, tam kaynak kodu mevcuttur.

Artık tamamen işlevsel bir iskelet ekran kullanıcı arayüzüne sahibiz. Örneğimiz, içeriği göstermeden önce iskeleti beş saniye gösterir.

Şimdiye kadarki sonucumuzu görelim:

YouTube benzeri kullanıcı arayüzü artı iskelet ekran kullanıcı arayüzü
YouTube benzeri iskelet kullanıcı arayüzümüz (Geniş önizleme)

Çözüm

İskelet ekranlar, tamamen boş bir ekranla karşı karşıya kalmanın yarattığı hayal kırıklığını önleyerek ve kullanıcıya içeriğin yüklenmeden önce nasıl görüneceğine dair bir izlenim vererek kullanıcı deneyimini büyük ölçüde geliştirir.

İncelediğimiz paketlerin hiçbirinden memnun değilseniz, sayfa düzenini taklit eden dikdörtgenler ve daireler oluşturarak kendi iskelet kullanıcı arayüzünüzü oluşturabilirsiniz.

Lütfen geri bildiriminizi ve deneyiminizi aşağıdaki yorumlar bölümünde paylaşın. Ne bulduğunu görmek isterim!

Bu makalenin destekleyici deposu Github'da mevcuttur.

Referanslar

  • “İskelet Ekranları Hakkında Bilmeniz Gereken Her Şey”, Bill Chung, UX Collective
  • “React ile İskelet Yükleme Sayfaları”, Anthony Panagi, Octopus Wealth
  • “React And React Native ile İskelet Ekranlar”, Chris Dolphin, Alligator.io
  • “React'te İskelet Yüklemesinin Uygulanması”, Adrian Bece, DEV