Ihre Website ruckelt? Zeit für JavaScript-Profiling
\nKennen Sie diesen Schmerz: Die Website lädt, die Animationen sind flüssig, aber sobald der Nutzer aktiv mit der Seite interagiert, bleibt alles stehen. Knöpfe reagieren nicht, das Scrollen ruckelt und die Konsole schweigt. Kommt Ihnen das bekannt vor? Höchstwahrscheinlich liegt das Problem in der JavaScript-Leistung. Diese Sprache ist die Seele des modernen Webs, aber ohne die richtige Optimierung kann sie Ihr Meisterwerk in einen trägen Monstrosität verwandeln.
\nIn diesem Artikel halten wir keine langweiligen Vorträge. Wir nehmen echten Code, zerlegen ihn mit Hilfe des Profilings in seine Einzelteile und zeigen Ihnen, wie Sie das Maximum aus jedem Zyklus herausholen. Bereit, Ihre Website in einen Formel-1-Boliden zu verwandeln? Los geht's!
\n\nWarum JavaScript ruckelt: Die Wurzel des Übels
\nBevor Sie zu den Werkzeugen greifen, lassen Sie uns verstehen, was genau die Leistung raubt. Meistens sind drei Dinge schuld:
\n- \n
- Blockierung des Hauptthreads — JavaScript läuft in einem einzigen Thread (Event Loop). Wenn Sie eine schwere synchrone Operation starten, friert die Oberfläche ein, bis diese abgeschlossen ist. \n
- Speicherlecks — vergessene Event-Handler, geschlossene Referenzen und globale Variablen. Der Speicher wächst, die Website wird langsamer und stürzt dann ab. \n
- Ineffiziente Algorithmen — doppelte Schleifen über riesige Arrays, häufige DOM-Manipulationen, suboptimale Datenstrukturen. \n
Aber genug der Theorie. Lassen Sie uns ansehen, wie das in der Praxis aussieht.
\n\nProfiling-Werkzeuge: Ihr Lügendetektor
\nChrome DevTools — Das Taschenmesser des Profilers
\nÖffnen Sie eine beliebige Seite, drücken Sie F12 und gehen Sie zum Tab Performance. Drücken Sie die Aufnahmetaste, führen Sie eine Aktion auf der Seite aus (z. B. klicken Sie auf einen Button) und stoppen Sie die Aufnahme. Sie sehen eine Zeitleiste, in der jede Sekunde in Einzelbilder unterteilt ist. Rote Balken sind Ihre Feinde. Sie bedeuten, dass der Browser ein Einzelbild nicht innerhalb von 16,6 ms (60 FPS) rendern konnte.
\n// Beispiel: Eine einfache, aber problematische Funktion\nfunction heavyCalculation() {\n let result = 0;\n for (let i = 0; i < 100000000; i++) {\n result += Math.sqrt(i) * Math.sin(i);\n }\n return result;\n}\n\ndocument.getElementById('btn').addEventListener('click', () => {\n const start = performance.now();\n heavyCalculation(); // Die Oberfläche friert für 2-3 Sekunden ein!\n console.log('Zeit:', performance.now() - start);\n});\n\nStarten Sie das Profiling und klicken Sie auf den Button. Sie werden sehen, dass der Hauptthread für eine ganze Sekunde mit dem Aufruf von heavyCalculation beschäftigt ist. Das ist der Bottleneck.
Memory — Jagd auf Speicherlecks
\nGehen Sie zum Tab Memory und machen Sie einen Heap-Snapshot. Führen Sie dann eine Aktion auf der Seite mehrmals aus und machen Sie einen zweiten Snapshot. Vergleichen Sie diese. Wenn die Anzahl der Objekte eines Typs unaufhörlich steigt, haben Sie ein Speicherleck.
\n// Klassisches Speicherleck: Vergessener Event-Handler\nfunction createButton() {\n const btn = document.createElement('button');\n btn.textContent = 'Click me';\n document.body.appendChild(btn);\n \n // Der Handler hält eine Referenz auf btn, selbst wenn btn entfernt wird\n btn.addEventListener('click', function onClick() {\n console.log('Clicked');\n });\n \n // Button entfernen, aber der Handler bleibt im Speicher\n document.body.removeChild(btn);\n}\n\n\nOptimierungstechniken: Von der Theorie zur Praxis
\n1. Hauptthread entlasten mit async/await
\nWenn Sie eine schwere Aufgabe haben, blockieren Sie nicht den Thread. Verwenden Sie Web Workers oder teilen Sie die Aufgabe in Mikrotasks auf. Aber der einfachste Weg ist setTimeout mit einer Verzögerung von Null oder requestIdleCallback.
// Schlecht: Synchrones Laden\nfunction loadBigData() {\n const data = [];\n for (let i = 0; i < 1000000; i++) {\n data.push({ id: i, value: Math.random() });\n }\n render(data);