Get to know MDN better
Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten. Erfahre mehr über dieses Experiment.
Es ist sehr wichtig, zu überlegen, wie Sie JavaScript auf Ihren Websites verwenden und wie Sie potenzielle Leistungsprobleme mindern können, die dadurch verursacht werden könnten. Auch wenn Bilder und Videos über 70 % der heruntergeladenen Bytes für die durchschnittliche Website ausmachen, hat JavaScript die größere Fähigkeit, negative Leistungsfolgen zu verursachen — es kann die Download-Zeiten, die Rendering-Leistung und die CPU- sowie die Batterienutzung erheblich beeinträchtigen. Dieser Artikel stellt Tipps und Techniken zur Optimierung von JavaScript vor, um die Leistung Ihrer Website zu verbessern.
| Grundlegende Software installiert und Grundkenntnisse in clientseitigen Webtechnologien. |
| Lernen, welche Auswirkungen JavaScript auf die Webleistung hat und wie man damit verbundene Probleme mindert oder behebt. |
Die erste Frage, die Sie beantworten sollten, bevor Sie mit der Optimierung Ihres Codes beginnen, ist: "Was muss ich optimieren?". Einige der unten diskutierten Tipps und Techniken sind gute Praktiken, die so gut wie jedem Webprojekt zugutekommen, während manche nur in bestimmten Situationen benötigt werden. Es ist wahrscheinlich unnötig, alle diese Techniken überall anzuwenden, und kann eine Zeitverschwendung sein. Sie sollten herausfinden, welche Leistungsoptimierungen in jedem Projekt tatsächlich benötigt werden.
Dazu müssen Sie die Leistung Ihrer Website messen. Wie der vorherige Link zeigt, gibt es mehrere verschiedene Möglichkeiten, die Leistung zu messen, einige davon beinhalten ausgeklügelte Performance APIs. Der beste Weg, um anzufangen, besteht jedoch darin, zu lernen, wie man Tools wie die eingebauten Browser-Netzwerk- und Leistungs- Werkzeuge verwendet, um zu sehen, welche Teile des Seitenladevorgangs lange dauern und optimiert werden müssen.
Das performanteste, am wenigsten blockierende JavaScript, das Sie verwenden können, ist JavaScript, das Sie überhaupt nicht verwenden. Sie sollten so wenig JavaScript wie möglich verwenden. Einige Tipps, die Sie beachten sollten:
Sie sollten Ihr JavaScript auch in mehrere Dateien aufteilen, die kritische und nicht kritische Teile repräsentieren. JavaScript-Module erlauben es Ihnen, dies effizienter zu tun als nur separate externe JavaScript-Dateien zu verwenden.
Dann können Sie diese kleineren Dateien optimieren. Minifizierung reduziert die Anzahl der Zeichen in Ihrer Datei und damit die Anzahl der Bytes oder das Gewicht Ihres JavaScripts. Gzipping komprimiert die Datei weiter und sollte verwendet werden, selbst wenn Sie Ihren Code nicht minifizieren. Brotli ist ähnlich wie Gzip, übertrifft jedoch im Allgemeinen Gzip-Kompression.
Sie können Ihren Code manuell aufteilen und optimieren, aber oft erledigt ein Modul-Bundler wie webpack dies besser.
Bevor wir uns mit den Tipps in diesem Abschnitt beschäftigen, ist es wichtig, darüber zu sprechen, wo im Prozess des Browser-Seitenrenderings JavaScript behandelt wird. Wenn eine Webseite geladen wird:
Hinweis: Dies ist eine sehr vereinfachte Darstellung dessen, was passiert, aber es gibt Ihnen eine Vorstellung.
Der Schlüsselschritt hier ist Schritt 3. Standardmäßig sind JavaScript-Parsing und -Ausführung renderblockierend. Das bedeutet, dass der Browser die Verarbeitung jeglichen HTML-Codes, der nach dem JavaScript erscheint, solange blockiert, bis das Skript bearbeitet wurde. Infolgedessen werden auch Styling und Darstellung blockiert. Das bedeutet, dass Sie sorgfältig überlegen müssen, nicht nur, was Sie herunterladen, sondern auch, wann und wie dieser Code ausgeführt wird.
Die nächsten Abschnitte bieten nützliche Techniken zur Optimierung des Parsens und der Ausführung Ihres JavaScripts.
Wenn ein Skript wirklich wichtig ist und Sie befürchten, dass es die Leistung beeinträchtigt, weil es nicht schnell genug geladen wird, können Sie es im <head> des Dokuments laden:
Das funktioniert gut, ist aber renderblockierend. Eine bessere Strategie ist es, rel="preload" zu verwenden, um einen Vorlader für kritisches JavaScript zu erstellen:
Der Preload <link> holt das JavaScript so schnell wie möglich, ohne die Darstellung zu blockieren. Sie können es dann überall dort verwenden, wo Sie es auf Ihrer Seite wollen:
oder in Ihrem Skript, im Fall eines JavaScript-Moduls:
Hinweis: Vorladen garantiert nicht, dass das Skript geladen ist, sobald Sie es einbinden, aber es bedeutet, dass es früher heruntergeladen wird. Die renderblockierende Zeit wird dadurch immer noch verkürzt, auch wenn sie nicht vollständig entfernt wird.
Andererseits sollten Sie das Parsen und die Ausführung von nicht-kritischem JavaScript auf später verschieben, wenn es benötigt wird. Alles direkt zu laden, blockiert die Darstellung unnötig.
Zuerst können Sie das Attribut async zu Ihren <script>-Elementen hinzufügen:
Dadurch wird das Skript parallel zum DOM-Parsing abgerufen, sodass es gleichzeitig bereit ist und die Darstellung nicht blockiert.
Hinweis: Es gibt ein weiteres Attribut, defer, das bewirkt, dass das Skript nach dem Parsen des Dokuments ausgeführt wird, aber bevor das DOMContentLoaded-Ereignis ausgelöst wird. Dies hat einen ähnlichen Effekt wie async.
Sie könnten auch einfach das JavaScript überhaupt nicht laden, bis ein Ereignis auftritt, bei dem es benötigt wird. Dies könnte über DOM-Scripting geschehen, zum Beispiel:
JavaScript-Module können dynamisch mit der import()-Funktion geladen werden:
Wenn der Browser Ihr JavaScript ausführt, organisiert er das Skript in Aufgaben, die sequenziell ausgeführt werden, wie das Ausführen von Fetch-Anfragen, das Steuern von Benutzerinteraktionen und Eingaben durch Event-Handler, das Ausführen von JavaScript-gesteuerter Animation und so weiter.
Die meisten davon laufen im Haupt-Thread, mit Ausnahmen einschließlich JavaScript, das in Web Workers läuft. Der Haupt-Thread kann nur eine Aufgabe gleichzeitig ausführen.
Wenn eine einzelne Aufgabe länger als 50 ms benötigt, um ausgeführt zu werden, wird sie als lange Aufgabe klassifiziert. Wenn der Nutzer versucht, mit der Seite zu interagieren, oder eine wichtige Benutzeroberflächen-Aktualisierung angefordert wird, während eine lange Aufgabe ausgeführt wird, wird seine Erfahrung beeinträchtigt. Eine erwartete Antwort oder visuelle Aktualisierung wird verzögert, was dazu führt, dass die Benutzeroberfläche träge oder unempfindlich erscheint.
Um dieses Problem zu mildern, müssen Sie lange Aufgaben in kleinere Aufgaben aufteilen. Dies gibt dem Browser mehr Gelegenheiten, wichtige Benutzerinteraktions-Handhabungen oder UI-Rendering-Aktualisierungen durchzuführen — der Browser kann sie potenziell zwischen jeder kleineren Aufgabe ausführen, statt nur davor oder danach. In Ihrem JavaScript könnten Sie dies tun, indem Sie Ihren Code in separate Funktionen aufteilen. Dies macht auch aus mehreren anderen Gründen Sinn, wie z.B. einfacherer Wartung, Debugging und Schreiben von Tests.
Zum Beispiel:
Diese Art von Struktur hilft jedoch nicht bei der Blockierung des Haupt-Threads. Da alle fünf Funktionen in einer Hauptfunktion ausgeführt werden, führt der Browser sie alle als eine einzige lange Aufgabe aus.
Um dies zu bewältigen, tendieren wir dazu, regelmäßig eine "yield"-Funktion auszuführen, um den Code dazu zu bringen, dem Haupt-Thread nachzugeben. Dies bedeutet, dass unser Code in mehrere Aufgaben aufgeteilt wird, zwischen deren Ausführung der Browser die Möglichkeit erhält, hochpriorisierte Aufgaben wie das Aktualisieren der Benutzeroberfläche zu handhaben. Ein häufiges Muster für diese Funktion verwendet setTimeout(), um die Ausführung in eine separate Aufgabe zu verschieben:
Dies kann innerhalb eines Task-Runner-Musters verwendet werden, um dem Haupt-Thread nach jeder ausgeführten Aufgabe nachzugeben:
Um dies weiter zu verbessern, können wir Scheduler.yield() dort verwenden, wo verfügbar, um diesem Code zu erlauben, weiterhin vor anderen weniger kritischen Aufgaben in der Warteschlange ausgeführt zu werden:
Animationen können die wahrgenommene Leistung verbessern, indem sie Schnittstellen flüssiger erscheinen lassen und Benutzern das Gefühl geben, dass Fortschritte gemacht werden, wenn sie auf das Laden einer Seite warten (zum Beispiel Lade-Spiralen). Größere Animationen und eine größere Anzahl von Animationen erfordern jedoch naturgemäß mehr Verarbeitungsleistung, um bearbeitet zu werden, was die Leistung beeinträchtigen kann.
Der offensichtlichste Animationsrat ist, weniger Animationen zu verwenden — schneiden Sie alle nicht essentiellen Animationen aus oder überlegen Sie, ob Sie Ihren Benutzern eine Präferenz geben, um Animationen auszuschalten, zum Beispiel wenn sie ein Gerät mit geringer Leistung oder ein mobiles Gerät mit begrenzter Batterieleistung verwenden.
Für essentielle DOM-Animationen sollten Sie, wenn möglich, CSS-Animationen statt JavaScript-Animationen verwenden (die Web Animations API bietet eine Möglichkeit, direkt in CSS-Animationen mit JavaScript einzugreifen). Den Browser zu verwenden, um direkt DOM-Animationen auszuführen, anstatt Inline-Stile mit JavaScript zu manipulieren, ist viel schneller und effizienter. Siehe auch CSS-Leistungsoptimierung > Umgang mit Animationen.
Für Animationen, die nicht in JavaScript behandelt werden können, beispielsweise das Animieren eines HTML-<canvas>, sollten Sie Window.requestAnimationFrame() statt älterer Optionen wie Window.setInterval() verwenden. Die requestAnimationFrame()-Methode ist speziell dafür entwickelt worden, Animationsbilder effizient und konsistent zu handhaben, für eine flüssige Benutzererfahrung. Das Grundmuster sieht folgendermaßen aus:
Eine nette Einführung in Canvas-Animationen finden Sie unter Grafiken zeichnen > Animationen und ein tiefergehendes Beispiel unter Objektaufbau-Praxis. Sie finden auch eine vollständige Reihe von Canvas-Tutorials im Canvas-Tutorial.
Ereignisse können für den Browser teuer zu überwachen und zu handhaben sein, insbesondere wenn Sie ein Ereignis kontinuierlich ausführen. Zum Beispiel könnten Sie die Position der Maus mit dem mousemove-Ereignis verfolgen, um zu prüfen, ob sie sich noch in einem bestimmten Bereich der Seite befindet:
Sie könnten ein <canvas>-Spiel auf Ihrer Seite ausführen. Solange sich die Maus im Canvas befindet, möchten Sie ständig Mausbewegungen und Cursorposition überprüfen und den Spielzustand aktualisieren — einschließlich des Punktestands, der Zeit, der Position aller Sprites, Kollisionserkennungsinformationen usw. Sobald das Spiel vorbei ist, benötigen Sie all das nicht mehr, und tatsächlich wäre es eine Verschwendung von Rechenleistung, weiterhin auf dieses Ereignis zu hören.
Es ist daher eine gute Idee, Ereignislistener zu entfernen, die nicht mehr benötigt werden. Dies kann mit removeEventListener() erfolgen:
Ein weiterer Tipp ist, wann immer möglich Ereignisdelegation zu verwenden. Wenn Sie Code haben, der als Antwort auf die Interaktion eines Benutzers mit einem beliebigen der vielen Kindelemente ausgeführt werden soll, können Sie einen Ereignislistener auf deren Eltern setzen. Ereignisse, die auf einem beliebigen Kindelement ausgelöst werden, werden zu ihrem Elternteil hochgebubbelt, sodass Sie den Ereignislistener nicht einzeln auf jedem Kind ansetzen müssen. Weniger zu verfolgende Ereignislistener bedeuten eine bessere Leistung.
Details dazu finden Sie unter Ereignisdelegation und ein nützliches Beispiel dazu.
Es gibt mehrere allgemeine Best Practices, die Ihren Code effizienter machen.
Reduzieren Sie DOM-Manipulationen: Das Zugreifen auf und das Aktualisieren des DOM ist rechnerisch aufwändig, daher sollten Sie die Menge an Arbeit minimieren, die Ihr JavaScript damit durchführt, insbesondere beim Ausführen von kontinuierlicher DOM-Animation (siehe Umgang mit JavaScript-Animationen oben).
Batch-DOM-Änderungen: Für wesentliche DOM-Änderungen sollten Sie diese in Gruppen zusammenfassen, die zusammen durchgeführt werden, anstatt jede einzelne Änderung sofort auszuführen. Dies kann die Menge der Arbeit, die der Browser tatsächlich erledigt, reduzieren und auch die wahrgenommene Leistung verbessern. Es kann die Benutzeroberfläche flüssiger aussehen lassen, wenn mehrere Aktualisierungen auf einmal erledigt werden, anstatt ständig kleine Aktualisierungen vorzunehmen. Ein nützlicher Tipp hier ist — wenn Sie ein großes Stück HTML auf die Seite hinzufügen müssen, bauen Sie das gesamte Fragment zuerst (typischerweise innerhalb eines DocumentFragment) und fügen Sie es dann in einem Zug dem DOM hinzu, anstatt jedes Element einzeln hinzuzufügen.
Vereinfachen Sie Ihr HTML: Je einfacher Ihr DOM-Baum ist, desto schneller kann er mit JavaScript zugegriffen und manipuliert werden. Überlegen Sie sorgfältig, was Ihre Benutzeroberfläche benötigt und entfernen Sie unnötigen Ballast.
Reduzieren Sie die Menge an Schleifen-Code: Schleifen sind teuer, reduzieren Sie daher die Nutzung von Schleifen in Ihrem Code, wo immer möglich. In Fällen, in denen Schleifen unvermeidlich sind:
Vermeiden Sie das vollständige Durchlaufen der Schleife, wenn es unnötig ist, indem Sie break oder continue-Anweisungen nach Bedarf verwenden. Wenn Sie beispielsweise Arrays nach einem bestimmten Namen durchsuchen, sollten Sie abbrechen, sobald der Name gefunden wurde; es gibt keinen Grund, weitere Schleifen-Durchläufe auszuführen:
Arbeiten, die nur einmal benötigt werden, außerhalb der Schleife erledigen. Das mag offensichtlich klingen, ist aber leicht zu übersehen. Nehmen Sie das folgende Snippet, das ein JSON-Objekt abruft, das Daten enthält, die auf irgendeine Weise verarbeitet werden sollen. In diesem Fall wird der fetch()-Vorgang bei jedem Schleifen-Durchlauf durchgeführt, was eine Verschwendung von Rechenleistung ist. Das Abrufen, das nicht von i abhängt, könnte außerhalb der Schleife verschoben werden, sodass es nur einmal durchgeführt wird.
Führen Sie Berechnungen außerhalb des Haupt-Threads aus: Früher haben wir darüber gesprochen, wie JavaScript im Allgemeinen Aufgaben auf dem Haupt-Thread ausführt und wie lange Operationen den Haupt-Thread blockieren können, was potenziell zu einer schlechten UI-Leistung führt. Wir haben auch gezeigt, wie langwierige Aufgaben in kleinere Aufgaben unterteilt werden können, um dieses Problem zu mildern. Eine weitere Möglichkeit, solche Probleme zu lösen, besteht darin, Aufgaben vollständig vom Haupt-Thread zu entfernen. Es gibt einige Möglichkeiten, dies zu erreichen:
Der Bauplan für ein besseres Internet.
Besuche die gemeinnützige Muttergesellschaft der Mozilla Corporation, die Mozilla Foundation.
Teile dieses Inhalts sind ©1998–2026 von einzelnen mozilla.org-Mitwirkenden. Inhalte sind verfügbar unter einer Creative-Commons-Lizenz.