performance-auswertung

Performance Probleme im JavaScript Code finden

Von am 03.03.2025

Auch den besten JavaScript-Developern passieren Fehler. Schnell lernt man die Dev-Tools zu schätzen und man wird effektiv und effizient beim Durchspringen des Codes auf der Suche nach Fehlern. Es gibt jedoch Situationen, in denen man auf andere Werkzeuge aus dem Werkzeugkasten der Browser Dev-Tools zurückgreifen muss. In diesem Artikel möchte ich anhand eines Beispiels demonstrieren, wie man mit dem Performance Analyzer ineffizienten Code identifiziert.

Es kann auch dich treffen

Dieses Kapitel enthält eine Erzählung basierend auf einem wahren Ereignis, die die Relevanz des Problems darstellen soll. Gerne kann dieses Kapitel übersprungen werden.

Ich habe an einer großen technischen Migration einer Web-Applikation gearbeitet. Nach unzähligen Änderungen, selbst Gitlab war mit der Anzeige der Changes überfordert, war der Moment gekommen einen ersten Build auf einer Testumgebung zu deployen. Ein Pipeline-Step nach dem anderen wird erfolgreich abgeschlossen. Der Server startet. Aufgeregt navigiere ich zur Website und stelle erfreut fest, dass sie schnell lädt. Alles sieht gut aus. Doch dann friert mein Browser-Fenster ein und ich kann die Website nicht mehr bedienen.

Was verursacht das Feststecken des Browsers? Alle Changes durchforsten ist aussichtslos. Es sind zu viele und lokal tritt das Problem ohnehin nicht auf. Glücklicherweise gibt es genau dafür den Performance Analyzer.

Anleitung

Haben Sie bereits Code, der den Browser zum Einfrieren bringt? Glückwunsch! Ansonsten können Sie das folgende Code Beispiel verwenden.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Performance Problem</title>
</head>
<body>
  <h1>Performance Problem</h1>
  <p>Check the console for the results</p>

  <script>
    function sayHello() {
      console.log('Hello World!');
    }
    sayHello();
  </script>

  <script>
    function isSubdomainOfFhstpAcAt(url) {
      return new RegExp('^(.+.)*fhstp.ac.at$').test(url);
    }
    const urlsToTest = [
      'mfg.fhstp.ac.at',
      'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.google.at'
    ];
    for (const url of urlsToTest) {
      console.log(`Checking if ${url} is a subdomain of fhstp.ac.at ...`);
      console.log(isSubdomainOfFhstpAcAt(url));
    }
  </script>
</body>
</html>

Öffnen sie nun einen leeren Tab und öffnen Sie die Dev-Tools (Taste F12). Klicken Sie auf den Tab “Performance” (siehe Grafik 1).

Grafik 1: Screenshot “Performance” Tab der Chrome Dev-Tools

Ganz links sehen Sie den Button “Record”. Klicken Sie ihn, um das Aufnahmen der Performance Analyse zu starten. Laden Sie nun Ihre Website. Nach einiger Zeit oder wenn, die Website wieder normal läuft, können Sie die Aufnahme stoppen. Sie sollten eine Auswertung wie in Grafik 2 sehen. Im Abschnitt “Summary” erkennen Sie, dass tatsächlich das Ausführen der Skripte am meisten Zeit beansprucht hat. Dasselbe lässt sich auch dem Zeitstrahl und der Visualisierung des Main-Threads darüber entnehmen. Im Abschnitt “Main” sehen Sie welche Tasks auf dem Main-Thread ausgeführt wurden und wie lange sie gedauert haben.

Grafik 2: Screenshot Auswertung

Interessant ist der Klick auf den Task “Parse HTML” (siehe Grafik 3). In der Bottom-up Ansicht sieht man welche Schritte dieser Task ausgeführt hat. Das Ausführen der Funktion “sayHello” war nicht der Grund für das Performance Problem. Hier werden 0,1ms „Self time“ also Zeit für diesen Step ohne Child-Steps angezeigt. Stattdessen ist eindeutig, dass vier Sekunden für das Ausführen einer Regex in der Funktion “isSubdomainOfFhstpAcAt“ verwendet wurden ????. Wir haben den Übeltäter gefunden! Wenn man sich nun die Regex genauer ansieht, erkennt man, dass es sich hierbei um einen Fall von „catastrophic backtracking“ handelt.

Grafik 3: Bottom-up Analyse des Task “Parse HTML”

The comments are closed.