Implementierung von Skelettbildschirmen in React

Veröffentlicht: 2022-03-10
Kurze Zusammenfassung ↬ In diesem Tutorial lernen Sie, was eine Skeleton-Screen-Benutzeroberfläche ist, und einige Arten von Skeleton-Screen-Bibliotheken, zusammen mit ihren Vor- und Nachteilen. Wir werden mit React Loading Skeleton eine YouTube-ähnliche Skelettbildschirm-Benutzeroberfläche erstellen. Dann können Sie selbst mit dem Skelettbildschirm-React-Paket Ihrer Wahl experimentieren.

Spinner und Loader waren traditionell der Weg, um Benutzern mitzuteilen, dass das Laden von Inhalten eine Weile dauern wird. Obwohl dieser Ansatz großartig ist, wird er in der modernen Entwicklung schnell veraltet. Skeleton-Bildschirme werden zum perfekten Ersatz für herkömmliche Lader, da sie sich eher auf den Fortschritt als auf Wartezeiten konzentrieren und somit die Frustration während der Ladezeit reduzieren.

In diesem Artikel gehen wir nicht auf die Grundlagen von CSS React oder JavaScript-Syntax ein, Sie müssen also kein Experte in einer dieser Sprachen sein, um mitzumachen.

Der Unterschied zwischen einem Ladeprogramm und einer Skelettbildschirm-Benutzeroberfläche
Der Unterschied zwischen einem Ladeprogramm und einer Skelettbildschirm-Benutzeroberfläche (große Vorschau)

UI- und UX-Experten lehren uns, dass wir sie beschäftigen sollten, während Benutzer darauf warten, dass Inhalte auf einer Seite geladen werden.

Die Idee hinter der Verwendung von Spinnern, um Benutzer anzusprechen, bevor Inhalte geladen werden, ist großartig. Das Ergebnis kann jedoch alles andere als ideal sein, da es den meisten Benutzern langweilig wird, auf einen Dummy-animierten Spinner zu starren, als wäre er eine Uhr. Luke Wroblewski geht darauf ein.

Skeleton-Bildschirme bieten eine bessere Benutzererfahrung, indem sie die Frustration während der Ladezeit reduzieren. Indem es sich auf den Fortschritt statt auf Wartezeiten konzentriert, entsteht bei den Benutzern die Illusion, dass Informationen schrittweise auf dem Bildschirm angezeigt werden. Bill Chung bestätigt dies in seiner Forschung.

Was ist ein Skeleton-Bildschirm?

Ein Skelettbildschirm ist eine Version der Benutzeroberfläche, die keinen eigentlichen Inhalt enthält. Stattdessen ahmt es das Layout der Seite nach, indem es seine Elemente in einer Form anzeigt, die dem tatsächlichen Inhalt ähnlich ist, während er geladen und verfügbar wird (dh wenn die Netzwerklatenz dies zulässt).

Ein Skelettbildschirm ist im Wesentlichen ein Drahtmodell der Seite mit Platzhalterfeldern für Text und Bilder.

Mehr nach dem Sprung! Lesen Sie unten weiter ↓

Was ist einzigartig an einem Skeleton-Bildschirm?

Eine Skelett-Benutzeroberfläche ähnelt der tatsächlichen Benutzeroberfläche der Seite, sodass die Benutzer verstehen, wie schnell die Web- oder mobile App geladen wird, noch bevor der Inhalt angezeigt wird. Hier sind einige Gründe, warum Sie die Verwendung von Skeleton-Bildschirmen in Ihrem nächsten Projekt in Betracht ziehen sollten:

  • Das Nachahmen des Layouts einer Seite ist mit einem Skelettbildschirm einfacher.
  • Inhalte werden nach und nach geladen (nicht alle auf einmal).

Skelettsiebe werden auch bezeichnet als:

  • Geisterelemente,
  • Inhaltsplatzhalter,
  • Content-Loader.

Blockchain.com, YouTube, Facebook, Medium und andere große Technologieunternehmen zeigen Skelettbildschirme an, während ihre Inhalte geladen werden, um die UX zu verbessern.

Blockchain.com

Benutzeroberfläche des Blockchain.com-Skelettbildschirms
Teilweise geladener Zustand von Blockchain.com (beachten Sie, wie ein Skelett in der Diagrammanalyse verwendet wird) (Große Vorschau)

Mittel

Mittlere Skelettbildschirm-Benutzeroberfläche
Skelett-UI des Mediums (große Vorschau)

LinkedIn

Benutzeroberfläche des LinkedIn-Skelettbildschirms
Ladezustand des Home-Feeds von LinkedIn im Jahr 2018 (große Vorschau)

Arten von Skeleton-Bildschirmen

Es gibt verschiedene Arten von Skelettsieben. Die wichtigsten sind Textplatzhalter und Bild- (oder Farb-)Platzhalter.

Die meisten Entwickler ziehen es vor, Textplatzhalter als Skelett-Benutzeroberfläche auf ihren Seiten zu verwenden, da sie einfach zu erstellen sind und der Entwickler keine Details über die Substanz des tatsächlichen Inhalts benötigt. Stattdessen ahmt das Skelett die Benutzeroberfläche nach.

Farbplatzhalter sind schwieriger zu erstellen, da sie Details zum Inhalt erfordern.

Einige beliebte Pakete erleichtern die Implementierung von Skeleton-Bildschirmen in Web-Apps. Schauen wir uns beide genauer an:

  • Platzhalter reagieren
  • Reagieren Laden Skelett

Wir werden uns die Vor- und Nachteile jedes Pakets ansehen, bevor wir überlegen, welches wir für unsere Anwendung verwenden.

Platzhalter reagieren

Vorteile

  • Platzhalterkomponenten werden verwendet, um eine benutzerdefinierte Skelett-Benutzeroberfläche zu erstellen.
  • Impulsanimation (dh Bewegungseffekt auf einem Element) wird unterstützt.
  • Es kommt mit einer komponentenbasierten API.

Nachteile

  • Skeleton-Komponenten werden separat verwaltet, sodass das Aktualisieren von Stilen einer Komponente möglicherweise auch das Aktualisieren der Skeleton-Komponente erfordert.
  • Die Lernkurve ist nicht linear, da es mehrere Komponenten für unterschiedliche Anforderungen gibt.

Das Folgende ist ein Beispiel für eine Skeleton-Komponente, die das Paket „ react-placeholder “ verwendet:

 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>

Durch das Importieren von TextBlock und RectShape aus „ react-placeholder/lib/placeholder “ und ReactPlaceholder aus „ react-placeholder “ haben wir eine funktionale Komponente namens GhostPlaceholder “ erstellt. GhostPlaceholder hat ein div, und innerhalb des div haben wir die RectShape-Komponente verwendet, die die Abmessungen eines Rechtecks ​​beschreibt, den Wert einer beliebigen Farbe übergibt und die Stile des Rechtecks ​​definiert.

Als Nächstes haben wir die TextBlock Komponente verwendet, um die Werte für die Zeilen und die Farbe festzulegen. Die TextBlock Komponente definiert die Anzahl der Zeilen und die Textfarbe.

Wir übergeben MyComponent als untergeordnetes Element der ReactPlaceholder Komponente, die ready und die GhostPlaceholder Komponente als Werte für ihre ready und customPlaceholder Props erhält.

Die MyComponent wird geladen, wenn die Benutzeroberfläche des Skelettbildschirms angezeigt wird.

Weitere Informationen finden Sie in der Dokumentation.

Reagieren Laden Skelett

Vorteile

  • Es ist API-basiert und hat eine Komponente mit Requisiten für alle Anpassungen.
  • Es kann als separate Skelettkomponente und auch direkt in jeder Komponente verwendet werden, sodass es flexibel ist.
  • Es unterstützt Theming und Pulse-Animation.

Nachteile

  • Es ist einfach für eine einfache Skelett-Benutzeroberfläche zu implementieren, aber kompliziert für komplexere Skelette.
  • Wenn Sie eine separate Skelettkomponente haben, wird die Wartung schwieriger, wenn sich die Benutzeroberfläche und die Stile ändern.

Das Folgende ist ein Beispiel für 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> );

Wir haben Skeleton und SkeletonTheme aus der react-loading-skeleton Bibliothek importiert und dann eine funktionale Komponente erstellt, die die SkeletonTheme -Komponente mit color und hightlightColor als Eigenschaften rendert.

Die SkeletonTheme -Komponente wird für die Gestaltung verwendet (z. B. Hinzufügen von Farbeffekten zur Skelett-Benutzeroberfläche).

Schließlich definieren wir innerhalb des Abschnitts die Skeleton Komponente, wobei die Höhen- und Breiteneigenschaften und die entsprechenden Werte übergeben werden.

Erstellen einer YouTube-ähnlichen Skeleton Screen-Benutzeroberfläche

Lassen Sie uns mit React Loading Skeleton einen YouTube-ähnlichen Skeleton-Bildschirm erstellen, um zu zeigen, wie eine Skeleton-Benutzeroberfläche funktioniert.

Reaktion einrichten

Der einfachste Weg, React einzurichten, ist die Verwendung der Create React App, die „eine offiziell unterstützte Möglichkeit ist, einseitige React-Anwendungen zu erstellen. Es bietet ein modernes Build-Setup ohne Konfiguration.“

Wir werden es verwenden, um die Anwendung zu booten, die wir erstellen werden. Führen Sie auf Ihrem Terminal den folgenden Befehl aus:

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

Starten Sie nach Abschluss der Installation den React-Server, indem Sie npm start :

React-App - Scaffold React-App
Willkommensseite reagieren (große Vorschau)

Erstellen Sie die YouTube-Benutzeroberfläche ohne Skeleton-Bildschirm

Lassen Sie uns zunächst YouTube-Dummy-Daten eingeben. Normalerweise würden echte Endpunkte anstelle von Dummy-Daten verwendet, aber in diesem Tutorial werden wir Dummy-Daten verwenden.

Erstellen Sie eine Datei in Ihrem Ordner src/ , nennen Sie sie data.js und fügen Sie den folgenden Code hinzu.

 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;

Um das Format von YouTube zu replizieren, haben wir Dummy-Daten erstellt, die eine Reihe von Objekten mit Eigenschaften wie ID, Bild, Titel, Anzahl der Aufrufe und Veröffentlichungsdatum enthalten.

Als Nächstes erstellen wir unsere YouTube-Benutzeroberfläche. Wir werden drei Komponenten haben:

Card Enthält die Details des Video-Thumbnails, des Titels, der Anzahl der Aufrufe, des Veröffentlichungsdatums und des Kanals.
CardList Gibt alle Karten in einer Reihe zurück.
App Mountet unser dummyData Objekt, lädt die Skeleton-UI zwei Sekunden lang und gibt die CardList Komponente zurück.

Erstellen Sie in Ihrem src Ordner einen Ordner und nennen Sie ihn components . Erstellen Sie im components eine Card.js -Datei und fügen Sie den folgenden Code hinzu:

 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;

Wir haben eine Card Komponente erstellt. Darin haben wir „ React aus „ react “ importiert und die item und channel Requisiten dekonstruiert, sodass sie in der gesamten Card Komponente verwendet werden können. Jede Card Item-Komponente, die ein Video anzeigt, zeigt die Miniaturansicht, die Anzahl der Aufrufe, das Veröffentlichungsdatum und den Titel.

CardList-Komponente

Erstellen Sie im components eine CardList.js -Datei und fügen Sie den folgenden Code hinzu:

 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;

In dieser Komponente haben wir die von uns erstellte Card Komponente importiert. Die Karte akzeptiert die item und channel Requisiten, die wir durch Mapping über die list.items . Wir exportieren diese Komponente dann als CardList , da wir sie in unserer App -Komponente verwenden werden.

Hinweis : Das Items-Array, das in dieser Komponente abgebildet wird, ist das Array von Objekten in unseren dummyData .

App-Komponente

Löschen Sie in der Datei app.js im Verzeichnis src/ den dort vorhandenen Code und fügen Sie ihm Folgendes hinzu.

 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;

In dieser Komponente haben wir die useState und useEffect zusammen mit React und den anderen Dateien importiert, die wir erstellt haben und die in der App -Komponente benötigt werden.

Da es sich bei unseren Daten um Dummy-Daten handelt, müssen wir sie wie die API-Daten nachahmen, indem wir den Inhalt nach einem Timeout von zwei Sekunden mit der JavaScript-Methode setTimeout .

Als Nächstes erstellen wir in der App -Komponente einen Videostatus und setzen den Status mithilfe von useState auf ein leeres Array.

Um unsere Dummy-Daten zu laden, verwenden wir den useEffect Hook. In unserem Hook erstellen wir einen variablen Timer, der die Funktion setTimeout () enthält. Innerhalb der Funktion setzen wir unseren Videostatus auf unser dummyData Objekt und stellen sicher, dass die Daten nach zwei Sekunden geladen werden, und schließlich brechen wir den Timer beim Unmounten ab.

Schließlich ordnen wir unseren Videostatus zu und geben das Abschnittselement zurück, das den list-section und die CardList -Komponente mit ihren Listenprops enthält.

CSS hinzufügen

Bis jetzt haben wir viele Klassen ohne tatsächliches CSS verwendet. Löschen Sie im src -Ordner alles in App.css und ersetzen Sie es durch den folgenden Code;

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

Mal sehen, wie unsere YouTube-Benutzeroberfläche ohne den Skelettbildschirm aussieht. Sie können sehen, dass beim Laden der Seite zwei Sekunden lang ein weißer Bildschirm angezeigt wird und die Daten dann sofort geladen werden.

YouTube-ähnliche Benutzeroberfläche ohne Skelettbildschirm
YouTube-ähnliche Benutzeroberfläche ohne Skelettbildschirm (große Vorschau)

Verwendung von React Loading Skeleton

Im Gegensatz zu anderen Bibliotheken, in denen Sie akribisch einen Skelettbildschirm erstellen würden, der zu den Schriftgrößen, Zeilenhöhen und Rändern Ihres Inhalts passt, ist die Skeleton -Komponente so konzipiert, dass sie direkt in Ihren Komponenten anstelle des geladenen Inhalts verwendet wird.

Lassen Sie uns einige Gründe durchgehen, warum wir React Loading Skeleton anderen vorgezogen haben.

Thematisierung

React Loading Skeleton unterstützt Themen. So können Sie ganz einfach die Farben aller Skeleton-Komponenten ändern, indem Sie SkeletonTheme verwenden und Werte an die props übergeben.

Unten ist ein Beispiel, das zeigt, wie es funktioniert:

 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> 
Theming-Effekt in Aktion
Themeneffekt in Aktion (große Vorschau)

Dauer

Zusätzlich zu den Requisiten height , width und color können wir auch eine Requisite für die duration angeben.

 <Skeleton duration={2} />

Die Dauer ist standardmäßig auf 1.2 eingestellt. Dies bestimmt, wie lange es dauert, einen Zyklus der Skelettanimation auszuführen.

Weitere Informationen finden Sie in der Dokumentation.

Implementieren der Skeleton Screen-Benutzeroberfläche

Jetzt installieren wir respond react-loading-skeleton . Führen Sie den folgenden Befehl in Ihrem Terminal aus, um das Paket zu installieren:

 npm install react-loading-skeleton

Skelettkomponente

Lassen Sie uns eine Skelettkomponente für unsere Videodaten erstellen. Erstellen Sie in unserem components eine SkeletonCard.js -Datei und fügen Sie den folgenden Code hinzu:

 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;

Wir haben eine ungeordnete Liste erstellt. Darin haben wir die Methode Array.fill() verwendet. Da wir neun Dummy-Datenelemente haben, haben wir die Array.fill() -Methode verwendet, um die Länge unseres items -Objekts zu durchlaufen und es ohne Indexwert zu füllen, wodurch unser Array leer wird. Sehen Sie sich die Array.fill-Dokumentation an, um zu erfahren, wie es funktioniert.

Als nächstes haben wir unser leeres Array gemappt, um eine Liste mit den Skeletteigenschaften zurückzugeben, und wir haben den Wert jeder der Skeletteigenschaften angegeben.

Hier bedeutet height die Länge eines Skelett-Rechtecks ​​und width bezieht sich auf die Breite, während circle den abgerundeten Teil der Skelett-Benutzeroberfläche erzeugt.

React Loading Skeleton wird mit einer standardmäßigen Pulse-Animation geliefert, was es praktisch macht. Sie könnten eine Pulse-Animation erstellen, die zu Ihrem Projekt passt, aber wenn Sie mich fragen, würde ich bei der Standardeinstellung bleiben.

Endlich ist der vollständige Quellcode verfügbar.

Wir haben jetzt eine voll funktionsfähige Skelettbildschirm-Benutzeroberfläche. Unser Beispiel zeigt das Skelett für fünf Sekunden, bevor der Inhalt angezeigt wird.

Sehen wir uns unser bisheriges Ergebnis an:

YouTube-ähnliche Benutzeroberfläche plus Skeleton-Bildschirm-Benutzeroberfläche
Unsere YouTube-ähnliche Skelett-Benutzeroberfläche (große Vorschau)

Fazit

Skeleton-Bildschirme verbessern die Benutzererfahrung enorm, indem sie die Frustration vermeiden, einen völlig leeren Bildschirm zu sehen, und dem Benutzer einen Eindruck davon vermitteln, wie der Inhalt aussehen wird, bevor er geladen wird.

Wenn Sie mit keinem der Pakete, die wir uns angesehen haben, vertraut sind, können Sie Ihre eigene Skelett-Benutzeroberfläche erstellen, indem Sie Rechtecke und Kreise erstellen, die das Layout der Seite nachahmen.

Bitte teilen Sie Ihr Feedback und Ihre Erfahrungen im Kommentarbereich unten mit. Ich würde gerne sehen, was Sie sich einfallen lassen!

Das unterstützende Repository für diesen Artikel ist auf Github verfügbar.

Verweise

  • „Alles, was Sie über Skelettbildschirme wissen müssen“, Bill Chung, UX Collective
  • „Skelett lädt Seiten mit React“, Anthony Panagi, Octopus Wealth
  • „Skelettbildschirme mit React und React Native“, Chris Dolphin, Alligator.io
  • „Implementierung von Skeleton Loading in React“, Adrian Bece, DEV