Einführung
In diesem Lab werden wir untersuchen, wie man in einer React-Anwendung das Lazy Loading von Bildern implementiert. Das Lazy Loading verbessert die Seitenleistung, indem es das Laden von Bildern bis zum Zeitpunkt ihres Bedarfs verzögert, die Initialladezeit reduziert und die Benutzererfahrung verbessert. Wir werden die Intersection Observer API und React Hooks verwenden, um einen wiederverwendbaren Komponenten zu erstellen, der das Lazy Loading von Bildern unterstützt.
Lazy-Laden von Bildern
index.htmlundscript.jswurden bereits in der VM bereitgestellt. Im Allgemeinen müssen Sie nur Code inscript.jsundstyle.csshinzufügen.
Um ein Bild zu rendern, das das Lazy Loading unterstützt, folgen Sie diesen Schritten:
- Verwenden Sie den
useState()-Hook, um einen zustandsbehafteten Wert zu erstellen, der angibt, ob das Bild geladen wurde. - Verwenden Sie den
useEffect()-Hook, um zu überprüfen, obHTMLImageElement.prototype'loading'enthält. Dies überprüft, ob das Lazy Loading nativ unterstützt wird. Wenn nicht, erstellen Sie einen neuenIntersectionObserverund verwenden SieIntersectionObserver.observer(), um das<img>-Element zu beobachten. Verwenden Sie den Rückgabewert des Hooks, um aufzuräumen, wenn die Komponente abmontiert wird. - Verwenden Sie den
useCallback()-Hook, um eine Callback-Funktion für denIntersectionObserverzu memoize. Diese Callback-Funktion wird denisLoaded-Zustandsvariablen aktualisieren undIntersectionObserver.disconnect()verwenden, um dieIntersectionObserver-Instanz zu trennen. - Verwenden Sie den
useRef()-Hook, um zwei Refs zu erstellen. Eine wird das<img>-Element halten und die andere dieIntersectionObserver-Instanz, wenn erforderlich. - Schließlich rendern Sie das
<img>-Element mit den angegebenen Attributen. Wenden Sieloading='lazy'an, um es lazily zu laden, wenn erforderlich. Verwenden SieisLoaded, um den Wert dessrc-Attributs zu bestimmen.
Hier ist eine Beispielimplementierung dieser Schritte:
const LazyLoadImage = ({
alt,
src,
className,
loadInitially = false,
observerOptions = { root: null, rootMargin: "200px 0px" },
...props
}) => {
const observerRef = React.useRef(null);
const imgRef = React.useRef(null);
const [isLoaded, setIsLoaded] = React.useState(loadInitially);
const observerCallback = React.useCallback(
(entries) => {
if (entries[0].isIntersecting) {
observerRef.current.disconnect();
setIsLoaded(true);
}
},
[observerRef]
);
React.useEffect(() => {
if (loadInitially) return;
if ("loading" in HTMLImageElement.prototype) {
setIsLoaded(true);
return;
}
observerRef.current = new IntersectionObserver(
observerCallback,
observerOptions
);
observerRef.current.observe(imgRef.current);
return () => {
observerRef.current.disconnect();
};
}, []);
return (
<img
alt={alt}
src={isLoaded ? src : ""}
ref={imgRef}
className={className}
loading={loadInitially ? undefined : "lazy"}
{...props}
/>
);
};
Um diese LazyLoadImage-Komponente zu verwenden, rufen Sie sie einfach mit den src- und alt-Attributen des Bilds auf:
ReactDOM.createRoot(document.getElementById("root")).render(
<LazyLoadImage src="https://picsum.photos/id/1080/600/600" alt="Erdbeeren" />
);
Bitte klicken Sie in der unteren rechten Ecke auf 'Go Live', um den Webdienst auf Port 8080 auszuführen. Anschließend können Sie die Registerkarte Web 8080 aktualisieren, um die Webseite zu previewen.
Zusammenfassung
Herzlichen Glückwunsch! Sie haben das Lab zu Lazy-Laden von Bildern abgeschlossen. Sie können in LabEx weitere Labs absolvieren, um Ihre Fähigkeiten zu verbessern.