Heutzutage sind Bilder der Hauptstolperstein auf dem Weg zu Hochgeschwindigkeitsladestellen. Dies gilt insbesondere für E-Commerce-Projekte. Bilder auf ihnen, normalerweise ziemlich "schwer", machen den größten Teil des Inhalts der Seiten aus. Dies führt in der Regel dazu, dass sein Browser mehrere Megabyte Grafikdaten herunterladen muss, um dem Benutzer eine Seite anzuzeigen. Wie kann das Laden von Seiten in dieser Situation beschleunigt werden? Die Antwort auf diese Frage ist dem Material gewidmet, dessen Übersetzung wir heute veröffentlichen.

Allgemeine Bestimmungen
Betrachten Sie zum Beispiel die Startseite der
Home- Abteilung bei Walmart.
Eine Seite mit vielen BildernHier finden Sie Informationen dazu, wie viele Bilder geladen werden, um diese Seite zu erstellen:
Bilder, die während der Seitenbildung geladen wurdenWie Sie sehen können, gibt es 137 Bilder! Dies bedeutet, dass mehr als 80% der Daten, die zum Anzeigen der Seite benötigt und über das Netzwerk übertragen werden, als Grafikdateien dargestellt werden.
Jetzt analysieren wir die Netzwerkanforderungen, die beim Laden der Seite ausgeführt werden:
Netzwerkanforderungen, die während der Seitenbildung ausgeführt werdenIn diesem Fall werden die Dateien, die sich aus der Trennung des Projektcodes ergeben, später heruntergeladen, als sie könnten. Dies liegt daran, dass Sie zuerst das
cp_ny.bundle
laden
cp_ny.bundle
. Dieses Bundle könnte viel schneller heruntergeladen werden, wenn es nicht durch 18 Bilder gestört worden wäre, die miteinander um Bandbreite konkurrieren.
Wie kann ich das beheben? In der Tat funktioniert es nicht, dies wirklich zu „beheben“, aber Sie können viele Dinge tun, um das Laden von Bildern zu optimieren. Es gibt viele Ansätze zur Optimierung von Bildern, die auf Webseiten verwendet werden. Dazu gehören die Verwendung verschiedener Grafikdateiformate, die Datenkomprimierung, die Verwendung von Unschärfe-Animationstechniken und die Verwendung von CDN. Ich möchte auf das sogenannte "Lazy Loading" von Bildern (Lazy Loading) eingehen. Insbesondere werden wir darüber sprechen, wie diese Technik auf React-Sites implementiert wird. Da sie jedoch auf JavaScript-Mechanismen basiert, kann sie in jedes Webprojekt integriert werden.
Pilotprojekt
Beginnen wir mit einer so extrem einfachen
Image
React-Komponente:
class Image extends PureComponent { render() { const { src } = this.props; return <img align="center" src={src} />; } }
Als Eigenschaft wird eine URL verwendet und zum Rendern des
img
HTML-Elements verwendet.
Hier ist der relevante JSFiddle-Code. Das folgende Bild zeigt die Seite mit dieser Komponente. Bitte beachten Sie, dass Sie den Inhalt der Seite scrollen müssen, um das von ihm angezeigte Bild zu sehen.
Die Seite mit der Komponente, die das Bild anzeigtUm die Technik des verzögerten Ladens von Bildern in dieser Komponente zu implementieren, müssen Sie die folgenden drei Schritte ausführen:
- Rendern Sie das Bild nicht sofort nach dem Herunterladen.
- Richten Sie Tools zum Erkennen des Erscheinungsbilds eines Bildes im Anzeigebereich des Seiteninhalts ein.
- Zeigen Sie das Bild an, nachdem festgestellt wurde, dass es in den Anzeigebereich gefallen ist.
Werfen wir einen Blick auf diese Schritte.
Schritt 1
In diesem Schritt wird das Bild unmittelbar nach dem Laden nicht angezeigt.
render() { return <img />; }
Schritt 2
Hier konfigurieren wir die Mechanismen, mit denen wir den Moment erkennen können, in dem das Bild in den Betrachtungsbereich gelangt.
componentDidMount() { this.observer = new IntersectionObserver(() => { // }, { root: document.querySelector(".container") }); this.observer.observe(this.element); } .... render() { return <img ref={el => this.element = el} />; }
Lassen Sie uns diesen Code analysieren. Folgendes wurde hier getan:
- Das ref- Attribut wurde dem
img
Element hinzugefügt. Auf diese Weise können Sie den Image-Link in src
später aktualisieren, ohne die Komponente erneut rendern zu müssen. - Eine neue Instanz von
IntersectionObserver
(wir werden weiter unten darauf eingehen). - Das
IntersectionObserver
Objekt wird aufgefordert, das Bild mithilfe des Konstrukts observe(this.element)
zu beobachten.
Was ist
IntersectionObserver
? Wenn man bedenkt, dass das Wort "Schnittpunkt" als "Schnittpunkt" übersetzt wird und "Beobachter" "Beobachter" ist, kann man bereits die Rolle dieses Objekts erraten. Wenn Sie in
MDN nach Informationen dazu suchen, können Sie feststellen, dass die Intersection Observer-API es Webanwendungen ermöglicht, Änderungen an der Schnittmenge eines Elements mit seinem übergeordneten Element oder dem Umfang eines Ansichtsfensterdokuments asynchron zu überwachen.
Auf den ersten Blick mag diese Eigenschaft der API nicht besonders verständlich erscheinen, aber tatsächlich ist sie sehr einfach aufgebaut. Der
IntersectionObserver
Instanz werden mehrere Parameter übergeben. Insbesondere haben wir den
root
Parameter verwendet, mit dem wir das Root-DOM-Element, das wir als Container betrachten, um den Schnittpunkt des Elements mit dem Rand setzen können, dessen Rand wir kennen müssen. Standardmäßig ist dies der Bereich, in dem sich das sichtbare Fragment der Seite (Ansichtsfenster) befindet. Ich habe es jedoch explizit so eingestellt, dass der Container im
iframe
Element der JSFiddle verwendet wird. Dies geschieht, um später eine Möglichkeit in Betracht zu ziehen, die nicht für die Verwendung von
iframe
Elementen ausgelegt ist.
Der Grund, warum die Verwendung von
IntersectionObserver
zum Ermitteln, wann ein Element sichtbar wird, beliebter ist als herkömmliche Methoden wie die gemeinsame Verwendung von
onScroll
und
getBoundingClientRect()
, da
IntersectionObserver
Mechanismen außerhalb des Hauptthreads ausgeführt werden. Der Rückruf, der aufgerufen wird, nachdem
IntersectionObserver
den Schnittpunkt des Elements mit dem Container erkannt hat, wird natürlich im Hauptthread ausgeführt, sodass sein Code nicht zu schwer sein sollte.
Schritt 3
Jetzt müssen wir den Rückruf konfigurieren, der aufgerufen wird, wenn er den Schnittpunkt des
this.element
(in diesem Fall dieses Element) mit dem
this.element
erkennt (in unserem Fall handelt es sich um ein
div
Element
.container
).
.... this.observer = new IntersectionObserver( entries => { entries.forEach(entry => { const { isIntersecting } = entry; if (isIntersecting) { this.element.src = this.props.src; this.observer = this.observer.disconnect(); } }); }, { root: document.querySelector(".container") } ); ....
Wenn der Schnittpunkt erkannt wird, wird das Array von
entries
an den
entries
, der einer Reihe von Schnappschüssen des Status aller
entries
ähnelt, für die der Schnittpunkt des angegebenen Rahmens erkannt wird. Die Eigenschaft
isIntersecting
gibt die Richtung der Kreuzung an. Wenn das überwachte Element außerhalb des Stammelements liegt, ist es
true
. Wenn ein Element das Stammelement verlässt, ist es
false
.
Wenn sich herausstellt, dass das Element den unteren Rand des Containers überschritten hat, setze ich seine
src
Eigenschaft manuell und deaktiviere die Überwachung dafür, was nicht mehr erforderlich ist.
Schritt 4 (geheim)
Jetzt, im vierten, geheimen Schritt unserer Arbeit, können Sie das Ergebnis bewundern und Erfolg haben. Hier ist der
Code , der sammelt, worüber wir gerade gesprochen haben.
Das Ergebnis der Anwendung der Lazy Image Loading-TechnikWenn Sie sich jedoch genauer ansehen, was wir haben, stellt sich heraus, dass Sie hier etwas finden, das nicht sehr gut ist. Um dies zu sehen, habe ich schnell durch die Seite gescrollt und gleichzeitig die Geschwindigkeit der Netzwerkverbindung verlangsamt.
Seitenverhalten, wenn es schnell scrollt und die Netzwerkverbindungsgeschwindigkeit verlangsamtDa wir das Bild erst laden, nachdem es den Bereich erreicht hat, in dem es bereits sichtbar sein sollte, hat der Benutzer nicht die Möglichkeit, durch die Seite zu scrollen und den vom Bild belegten Bereich und natürlich das Bild selbst zu sehen, bevor er es lädt. Wenn Websites von normalen Computern aus angezeigt werden, die mit dem schnellen Internet verbunden sind, verursacht dies keine Probleme. Viele moderne Benutzer besuchen Websites jedoch von ihren Telefonen aus. Manchmal verwenden sie 3G-Netzwerke oder, noch schlimmer, EDGE-Verbindungen.
Es ist wahr, dass es nicht so schwierig ist, mit diesem Problem umzugehen. Dies kann aufgrund der Tatsache erfolgen, dass die Intersection Observer-API dem Entwickler die Möglichkeit bietet, die Grenzen des
.container
zu erweitern oder zu verengen (in unserem Fall ist dies das
.container
Element). Um diese Gelegenheit zu nutzen, fügen Sie einfach eine Codezeile hinzu, in der der Stammcontainer konfiguriert ist:
rootMargin: "0px 0px 200px 0px"
rootMargin
Eigenschaft
rootMargin
eine Zeile, deren Struktur den CSS-Regeln entspricht, die zum Konfigurieren des Einrückens von Elementen verwendet werden. In unserem Fall teilen wir dem System mit, dass der untere Rand, der zum Erkennen des Schnittpunkts eines Elements mit einem Container verwendet wird, um 200 Pixel erhöht werden muss. Dies bedeutet, dass der entsprechende Rückruf aufgerufen wird, wenn das Element in einen Bereich fällt, der 200 Pixel unter dem unteren Rand des Stammelements liegt (der Standardwert ist 0).
Hier ist der Code, der diese Technik implementiert.
Verbesserung der Technik des verzögerten Ladens von BildernAls Ergebnis stellt sich heraus, dass das Bild in einem Bereich geladen wird, der 200 Pixel unter dem sichtbaren Bereich der Seite liegt, wenn wir die Seite nur zum 4. Element der Liste scrollen.
Nun scheint alles, was benötigt wird, getan zu sein. Aber das ist nicht so.
Bildhöhenproblem
Wenn Sie die obigen GIF-Abbildungen sorgfältig studiert haben, werden Sie möglicherweise feststellen, dass die Bildlaufleiste nach dem Laden des Bildes einen „Sprung“ macht. Glücklicherweise ist dieses Problem leicht zu handhaben. Der Grund dafür ist, dass das Element, das das Bild anzeigt, anfänglich eine Höhe von 0 hat, die sich nach dem Laden des Bildes als 300 Pixel herausstellt. Um das Problem zu beheben, reicht es daher aus, das Element auf eine feste Höhe zu setzen, indem dem Bild das Attribut
height={300}
hinzugefügt wird.
Über Optimierungsergebnisse
Welche Ergebnisse haben wir bei Walmart erzielt, nachdem wir das verzögerte Laden von Bildern auf
dieser Seite angewendet haben? Tatsächlich variieren die spezifischen Ergebnisse stark in Abhängigkeit von vielen Umständen, unter denen wir die Netzwerkverbindungsgeschwindigkeit des Clients, die CDN-Verfügbarkeit, die Anzahl der Bilder auf der Seite und die Regeln zum Erkennen von Schnittpunkten mit dem auf sie angewendeten Stammelement notieren können. Mit anderen Worten, um die Auswirkungen des verzögerten Ladens von Bildern auf Ihr eigenes Projekt zu beurteilen, ist es für Sie am besten, dies selbst zu implementieren und zu überprüfen. Wenn Sie jedoch immer noch daran interessiert sind, was uns das verzögerte Laden von Bildern gebracht hat, finden Sie hier einige Lighthouse-Berichte. Die erste wird vor der Optimierung gebildet, die zweite nach der Optimierung.
Leuchtturmbericht vor der Optimierung erstelltLeuchtturmbericht nach Optimierung erstelltZusammenfassung
Heute haben wir uns eine Technik zur Optimierung von Webseiten durch verzögertes Laden von Bildern angesehen. Wenn die Seiten Ihrer Website voller Bilder sind, ist diese Technik möglicherweise für Sie hilfreich.
Liebe Leser! Wie optimieren Sie Bilder und deren Laden?