0,1 Sekunden wert! Eine kurze Diskussion über das Problem der Beschleunigung der Front-End-Webseiten

0,1 Sekunden wert! Eine kurze Diskussion über das Problem der Beschleunigung der Front-End-Webseiten

Ich erinnere mich, dass mir bei meinem Vorstellungsgespräch für meinen jetzigen Job ein Vorgesetzter ganz ernsthaft sagte: „Die heutige Welt ist die Welt des Internets und der Wettbewerb zwischen IT-Unternehmen ist sehr hart. Wenn die Lade- und Anzeigegeschwindigkeit einer Webseite im Vergleich zu den Seiten anderer Anbieter um 0,1 Sekunden verbessert wird, ist das ebenfalls eine großartige Leistung.“

Dann wusste ich nicht, wie ich mit dem Schreiben weitermachen sollte, also fragte ich die militärischen Berater in der Gruppe und das Ergebnis war Folgendes. . .

Okay, es ist Zeit, das Thema zu wechseln und zum eigentlichen Thema zurückzukehren: Wie können wir die Zugriffsgeschwindigkeit unserer Site-Seiten verbessern, die Wartezeit verkürzen und das Zugriffserlebnis der Benutzer maximieren?

Um dieses Problem zu beheben, schlagen wir heute eine Reihe von Lösungen aus der Front-End-Perspektive vor, die alle die Zugriffsgeschwindigkeit Ihrer Seiten effektiv verbessern können.

1. Reduzieren Sie die Dateianforderungen an den Server

Herkömmliche HTTP-Anfragen sind kurze Verbindungen in der Form „Anfrage“ – „Antwort“ – „Trennen“. Für jede unabhängige Ressource senden wir eine Get-Anfrage an den Server und warten dann, bis der Server die benötigte Datei zurücksendet. Jede Ressourcenanforderung verbraucht tatsächlich eine „Connect-Wait-Receive“-Zeit (natürlich kann das Einstellen der HTTP-Anforderung auf den Keep-Alive-Verbindungsstatus die Anzahl und Zeit der „Verbindung“ reduzieren). Wenn wir die Anzahl der Anforderungen für Serverdateien effektiv reduzieren können, bedeutet dies, dass wir einige Seitenwartezeit einsparen und die Belastung des Servers verringern können.

Für diese Lösung können wir Folgendes tun:

1. Verwenden Sie die CSS-Sprite-Technologie, um mehrere Bilder in einer einzigen Bilddatei zusammenzuführen. Wenn Sie sie tatsächlich verwenden, verwenden Sie background-position, um die Hintergrundposition zu lokalisieren (ich glaube, das ist das Erste, was Ihnen in den Sinn kommt);

2. Führen Sie mehrere CSS-Stildateien zu einer einzigen Stildatei zusammen, führen Sie mehrere Skripte zu einem einzigen Skript zusammen und verweisen Sie dann auf der Seite auf die zusammengeführte Stil-/Skriptdatei. Sie können hierfür r.js verwenden, ich persönlich empfehle diese Methode jedoch nicht, da nach dem Zusammenführen der Dateien die gemeinsamen Stil-/Skriptdateien mehrerer Seiten nicht auf dem Client zwischengespeichert werden können.

3. Verwenden Sie zur Anzeige von Bildern die Base64-Kodierung. Genau wie die 404-Seite von GitHub:

Mit diesem Tool können Sie Bilder in Base64-codierte Dateiströme konvertieren. Generell wird jedoch empfohlen, diese Methode nur auf Seiten zu verwenden, die von Benutzern seltener besucht werden, da sie zwar nicht vom Server abgerufen werden müssen, aber nicht auf dem Client zwischengespeichert werden können, wodurch die Seite bei jedem Besuch des Benutzers neu gerendert werden muss. Darüber hinaus nimmt der lange Dateistreamcode viel Codeplatz auf Ihrer Seite in Anspruch, und die Wartung der Seite wird wahrscheinlich sehr frustrierend sein.

4. Schreiben Sie kleine CSS- und JS-Codeausschnitte direkt auf die Seite, anstatt unabhängige Style-/Skriptdateien auf der Seite einzufügen. Ich glaube, dass einige Freunde an die Norm gewöhnt sind, „Struktur (Markup), Präsentation (Stil) und Verhalten (Skript) getrennt zu halten“, und zu diesem Standpunkt möglicherweise eine Meinung haben. Ich kann nur sagen, dass Standards keine Dogmen sind und dass das, was Ihnen passt, die harte Wahrheit ist. Die Vorteile des Schreibens kleiner, wenig wiederverwendbarer Stile/Skripte direkt auf der Seite überwiegen immer noch die Nachteile (die Nachteile können darin bestehen, dass sich die Größe des Seitencodes erhöht und die Wartung nicht so einfach ist). Wenn man sich andererseits die Seitenquelldateien aller gängigen Portale ansieht, importiert fast keines von ihnen alle Stile/Skripte als externe Dateien (unabhängig davon, ob sie mit der Reduzierung der Serveranforderungen beginnen, ist dies eine Tatsache);

5. Verwenden Sie das Meta-Tag http-equiv="expires", um einen zukünftigen Zeitpunkt als Ablaufzeitpunkt für die Auslagerungsdatei festzulegen. Auslagerungsdateien, die von Benutzern vor Ablauf des Ablaufzeitpunkts abgerufen werden, werden nur aus dem Cache entnommen. Allerdings ist diese Methode zu starr (manchmal kann es vorkommen, dass der Client nicht zum Server geht, um neue Dateiressourcen gemäß den neu geänderten Regeln abzurufen, selbst wenn der Server die Ablaufzeit rechtzeitig auf die Endzeit ändert). Daher wird sie im Allgemeinen nicht empfohlen.

2. Dateigröße reduzieren

Große Dateien (insbesondere Bilder) führen zu langen Ladezeiten, die oft der größte Feind sind, der das Ladeerlebnis einer Seite beeinträchtigt. Daher ist es sehr wichtig, die Größe der angeforderten Datei so weit wie möglich zu reduzieren. Was wir tun können, ist:

1. Komprimieren Sie Stil-/Skriptdateien. Sie können hierfür Gulp oder Grunt verwenden. Beide können die Größe von CSS-/JS-Dateien reduzieren (und Variablen und Funktionsnamen für JS verschleiern).

2. Wählen Sie das Bildformat gezielt aus. Wenn kein transparenter Hintergrund erforderlich ist, verwenden Sie das GIF-Format nur für Bilder mit einer einzigen Farbe und ohne Farbverlauf. Bei JPG-Bildern können Sie beim Exportieren von JPG auch die entsprechende „Qualität“ entsprechend der Anforderungen an die Klarheit optimieren:

Wenn Sie gerne neue Dinge ausprobieren, können Sie wie Taobao das Bildformat webp verwenden, mit dem die Dateigröße bei gleicher Bildqualität optimiert werden kann:

3. Verwenden Sie Font Awesome, um die Symbole auf der Seite zu ersetzen. Das Prinzip besteht darin, @font-face zu verwenden, damit Benutzer ein sehr kleines UI-Schriftpaket herunterladen und die auf der Seite verwendeten Symbole in Form von Zeichen anzeigen können, wodurch der Bildbedarf und die Symboldateigröße verringert werden.

3. CDN richtig nutzen

Die Verwendung von CDN bietet mehrere Vorteile: Wenn der Benutzer diese CDN-Ressource von anderen Sites heruntergeladen hat, muss er sie beim Besuch unserer Site nur aus dem Cache abrufen. Es reduziert die Dateianforderungen an den eigenen Site-Server (im Fall eines externen CDN), wodurch die Serverlast verringert wird. Mehrere Domänen erhöhen die maximale Anzahl von Ressourcen, die vom Browser asynchron heruntergeladen werden dürfen. Wenn eine Site beispielsweise nur Ressourcen von einer Domäne anfordert, erlaubt FireFox nur den gleichzeitigen asynchronen Download von maximal 2 Dateien. Wenn jedoch ein externes CDN zum Einführen von Ressourcen verwendet wird, ermöglicht FF nicht nur den gleichzeitigen asynchronen Download von zwei Ressourcen in der aktuellen Domäne, sondern auch den gleichzeitigen asynchronen Download von 2 Ressourcen unter einer anderen Domäne (CDN).

Die Verwendung von CDN bringt jedoch ein großes Problem mit sich: Sie erhöht den Aufwand für die DNS-Auflösung. Wenn eine Seite gleichzeitig Ressourcen von mehreren CDNs einführt, kann es aufgrund der DNS-Auflösung zu langen Wartezeiten kommen, wodurch die Kosten den Nutzen übersteigen.

In Bezug auf dieses Problem wird allgemein empfohlen, nur dasselbe zuverlässige und schnelle CDN zu verwenden, um verschiedene erforderliche Ressourcen auf einer Site einzuführen. Mit anderen Worten wird empfohlen, dass eine Seite Ressourcen von zwei verschiedenen Domänen anfordert (z. B. der Site-Domäne und der CDN-Domäne). Dies ist die beste Option (angeblich wurde diese Schlussfolgerung von Front-End-Ingenieuren von Yahoo vorgeschlagen).

4. Verzögerungsanforderungen und asynchrones Laden von Skripten

Unter allen gängigen Browsern werden unsere Skriptdateien normalerweise wie andere Ressourcendateien asynchron heruntergeladen. Hier gibt es jedoch ein Problem. Nachdem FireFox beispielsweise das Skript heruntergeladen hat, tritt eine Situation „blockierte Ausführung“ auf. Das heißt, während der Zeit, in der der Browser das Skript herunterlädt und ausführt, werden andere Verhaltensweisen des Browsers blockiert, was dazu führt, dass andere Ressourcen auf der Seite nicht angefordert und heruntergeladen werden können:

Wenn die Ausführung des JS-Codes auf Ihrer Seite zu lange dauert, spürt der Benutzer die Verzögerung der Seite deutlich. Dieses Problem lässt sich auf einfache Weise lösen: Platzieren Sie das Skriptanforderungs-Tag vor dem schließenden Tag </body>, sodass das Skript auf der Seite zur letzten angeforderten Ressource wird und die Anforderungsereignisse anderer Seitenressourcen nicht auf natürliche Weise blockiert.

Obwohl oben erwähnt wurde, dass „unsere Skriptdateien wie andere Ressourcendateien asynchron heruntergeladen werden“, bedeutet asynchroner Download nicht asynchrone Ausführung. Um die Richtigkeit der Skriptlogikreihenfolge und der Abhängigkeitsbeziehungen strikt sicherzustellen, führt der Browser die Skripte in der Reihenfolge aus, in der die Skripte angefordert werden. Dann tritt das Problem auf: Wenn zwischen den Skripten auf der Seite keine großen oder gar keine Abhängigkeiten zueinander bestehen, verlängern die Browserregeln nur die Zeit, die die Seitenanforderung blockiert (genauso, als würden Sie viel Geld für den Abschluss einer Versicherungspolice ausgeben, aber während der Versicherungslaufzeit passiert Ihnen nichts … Nun, diese Metapher ist ein wenig unmenschlich …).

Die Lösung für dieses Problem besteht darin, das Skript asynchron auszuführen, ohne es zu blockieren. Dies kann beispielsweise durch Hinzufügen von Defer- und Async-Attributen zum Skript-Tag oder durch dynamisches Einfügen des Skripts (siehe hier) erfolgen. Dies sind jedoch keine guten Lösungen. Entweder gibt es Kompatibilitätsprobleme oder sie sind zu problematisch und können Abhängigkeiten nicht verarbeiten.

Ich persönlich empfehle die Verwendung von requireJS (AMD-Spezifikation) oder seaJS (CMD-Spezifikation), um Skripte asynchron zu laden und Modulabhängigkeiten zu handhaben. Ersteres „ersetzt Abhängigkeiten vorab“ (lädt alle abhängigen Skriptmodule vorab, um die schnellste Ausführungsgeschwindigkeit zu erzielen), während letzteres „vom Nächstliegenden abhängt“ (verzögertes Laden abhängiger Skriptmodule, das Anfordern von Skripten ist wissenschaftlicher). Sie können die am besten geeignete Methode basierend auf den spezifischen Anforderungen des Projekts auswählen.

5. Verzögern Sie die Anforderung von Dateien außerhalb des ersten Bildschirms

Lassen Sie es mich zunächst erklären. Der „erste Bildschirm“ bezieht sich auf den Anzeigebereich für Seiteninhalte beim Initialisieren der Seite, also den Bereich, den der Benutzer zuerst sieht, wenn die Seite geladen wird.

Beispielsweise haben JD.com und Taobao ähnliche Lazyload-Verarbeitungen für Bilder implementiert, bei denen man scrollen muss, um die Seite zu sehen. Dies ist nichts weiter als das Konzept des Proxy-Modells, aber sie vermitteln den Benutzern die Illusion, dass die Seite schneller geladen wird, weil ich den Inhalt schnell auf dem Bildschirm sehen kann (selbst wenn ich die Bildlaufleiste nicht heruntergezogen habe und die Dateien am Ende der Seite noch nicht geladen sind).

Wir können diese Lösung wie folgt implementieren, ohne auf eine Lazyload-Bibliothek angewiesen zu sein. Nehmen wir beispielsweise ein Bild. Wir können das img-Tag eines Bildes außerhalb des ersten Bildschirms schreiben (vorausgesetzt, die Adresse eines Bildes ist a.jpg) wie folgt:

<img src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-src="a.jpg">

Wie oben gezeigt, verwendet die Seite beim ersten Laden dieses Bilds direkt base64 (natürlich können Sie stattdessen auch ein Platzhalterbild „loading.gif“ verwenden), um schnell ein sehr kleines Bild anzuzeigen, und der tatsächliche Pfad des Bilds selbst befindet sich im data-src-Attribut. Wir können seine tatsächliche Datei vom Server anfordern und sie ersetzen, nachdem die Seite geladen wurde:

Funktion init(){

var imgDefer = document.getElementsByTagName('img');

für (var i=0; i<imgDefer.length; i++) {

wenn(imgDefer[i].getAttribute('data-src')) {

imgDefer[i].setAttribute('src',imgDefer[i].getAttribute('data-src'));

}

}

}

Fenster.onload = init;

Oben ist der verzögerte Ladevorgang für Bilder dargestellt. Für Video- und Audiodateien kann das gleiche Prinzip zum verzögerten Laden verwendet werden, wodurch die Wartezeit für die Seiteninitialisierung effektiv verkürzt wird.

6. Optimieren Sie die Reihenfolge der Platzierung der Seitenmodule

Hier ist ein gutes Beispiel. Beispielsweise gibt es eine Seite wie diese - links befindet sich die Seitenleiste, in der der Avatar des Benutzers, Informationen und auf der Website platzierte Anzeigen gespeichert werden, und rechts befindet sich der Artikelinhaltsbereich:

Dann könnte unser Code folgendermaßen aussehen:

<Text>

<Seitenleiste>

<!-- Seitenleisteninhalt -->

</Seitenleiste>

<Inhalt>

<!-- Artikelinhalt-->

</Inhalt>

</body>

Daher lädt der Browser gemäß seinem UI-Single-Thread-Prinzip zuerst die Seitenleiste von oben nach unten und dann unseren Artikel. . .

Dies ist offensichtlich keine humane Ladereihenfolge. Wir müssen herausfinden, welches Bereichsmodul auf der Seite für den Benutzer am wichtigsten ist und welches zuerst angezeigt werden soll.

Für das obige Beispiel sollte der Artikelinhalt der Bereich sein, den Benutzer zuerst sehen und den der Browser zuerst anfordern und anzeigen soll. Daher müssen wir unseren Code wie folgt ändern:

<Text>

<Inhalt>

<!-- Artikelinhalt-->

</Inhalt>

<Seitenleiste>

<!-- Seitenleisteninhalt -->

</Seitenleiste>

</body>

Natürlich ist dies nur ein kleines Beispiel, um Ihre Vorstellungskraft anzuregen. Zu wissen, wie man Schlussfolgerungen zieht und diese in der Praxis anwendet, ist die wahre Wahrheit.

VII. Weitere Vorschläge

1. Verwenden Sie @import nicht in CSS, da dadurch eine Stildatei auf die Anforderung einer anderen Stildatei warten muss, wodurch die Wartezeit der Seite verlängert wird (wenn Sie SCSS verwenden, ist @import natürlich eine andere Sache, aber das ist nicht das Thema~);

2. Vermeiden Sie die Umleitung von Seiten oder Auslagerungsdateien. Das ist so, als ob Sie in eine Toilette gehen und dann ein Schild mit der Aufschrift „Das ist anders, bitte gehen Sie auf die Toilette vorne links“ sehen und dann noch einmal hindurchgehen müssen.

3. Reduzieren Sie ungültige Anfragen. Wenn Sie beispielsweise eine nicht vorhandene Ressource über CSS/JS anfordern, kann dies zu längeren Wartezeiten und Blockierungen führen (bis eine Fehlermeldung zurückgegeben wird).

4. Unabhängig davon, ob Sie das Skript am Ende der Seite platzieren möchten oder nicht, stellen Sie sicher, dass es nach der Stildatei platziert wird.

5. Ich werde nicht näher auf Backend-Lösungen wie das Konfigurieren von .htaccess-Dateien, die Verwendung der Gzip-Seitenkomprimierung und das Aktivieren des Keep-Alive-Verbindungsmodus eingehen.

Ich bin der Meinung, dass die Lösungen zur Beschleunigung von Seiten definitiv nicht auf die oben genannten beschränkt sind und jedes Projekt unterschiedliche Anforderungen und Situationen aufweist, sodass Sie je nach Bedarf nur die Lösung auswählen können, die zu Ihnen passt.

Das Wichtigste ist jedoch, das Benutzererlebnis in den Vordergrund zu stellen. Egal, ob es um das Laden der Seite oder die Interaktion geht, Sie sollten die beste Lösung aus der Perspektive des Benutzers denken und entwerfen. Auf diese Weise können Sie meiner Meinung nach herausragende und beliebte Werke schaffen.

Das ist alles, worüber wir heute sprechen müssen. Lasst uns einander ermutigen~

<<:  CSS+HTML zur Realisierung der Funktion der oberen Navigationsleiste

>>:  Verwaltung von xinetd-basierten Diensten, die mit RPM-Paketen in Linux installiert wurden

Artikel empfehlen

VMware12 installiert die Desktopversion von Ubuntu19.04 (Installations-Tutorial)

1. Versuchsbeschreibung Installieren Sie in der v...

Vue3 AST Parser-Quellcode-Analyse

Inhaltsverzeichnis 1. Generieren Sie einen abstra...

Drei Diskussionen zum Iframe Adaptive Height Code

Beim Erstellen einer B/S-Systemschnittstelle stößt...

Zusammenfassung der Erfahrungen beim Website-Erstellen

<br />Welche Grundsätze sollten beachtet wer...

Schritte zum Bereitstellen eines Spring Boot-Projekts mit Docker

Inhaltsverzeichnis Erstellen Sie ein einfaches Sp...

Grafisches Tutorial zur Installation und Konfiguration von MySQL 8.0.19

In diesem Artikel wird das grafische Tutorial zur...

So stellen Sie Spring Boot mit Docker bereit

Die Entwicklung der Docker-Technologie bietet ein...

CentOS verwendet expect, um Skripte und Befehle remote in Stapeln auszuführen

Manchmal müssen wir Server stapelweise bedienen, ...

Reines js, um einen Schreibmaschineneffekt zu erzielen

In diesem Artikelbeispiel wird der spezifische Co...

Probleme mit Index und FROM_UNIXTIME in MySQL

Null, Hintergrund Ich habe diesen Donnerstag viel...

Bidirektionale verknüpfte Liste der JavaScript-Datenstruktur

Eine einfach verkettete Liste kann nur vom Anfang...