+ All Categories
Home > Software > JavaScript Performance

JavaScript Performance

Date post: 12-Aug-2015
Category:
Upload: sebastian-springer
View: 275 times
Download: 0 times
Share this document with a friend
Popular Tags:
73
JavaScript Performance
Transcript
Page 1: JavaScript Performance

JavaScript Performance

Page 2: JavaScript Performance

WHO AM I?

• Sebastian Springer

• aus München

• arbeite bei Mayflower

• https://github.com/sspringer82

• @basti_springer

• Consultant, Trainer, Autor

Page 3: JavaScript Performance

Wie öffnet ihr eure Dev Tools im Browser?

• Was sind Dev Tools?

• Tastenkombination

• Mausklick (maximal 2)

Page 4: JavaScript Performance

Was erwartet euch?

Best Practices: Wie kann ich Probleme von vornherein vermeiden?

Performance Optimierung: Was mache ich, wenn meine Applikation langsam ist?

Page 5: JavaScript Performance

Performance

Es gibt nicht die eine JavaScript Performance. Wie sich eine Applikation benimmt, hängt von zahlreichen Komponenten ab.

Die wichtigsten sind Netzwerk, CPU, Memory und Rendering.

Page 6: JavaScript Performance

Performance verbessern

Branko Spoljar / pixelio.de

Karl-Heinz Laube / pixelio.de

Page 7: JavaScript Performance

Vorgehensweise

Ein kleiner Ausflug:

Andreas Hermsdorf / pixelio.de

Page 8: JavaScript Performance

Vorgehensweise

Analyse

Bewertung

Durchführung

Kontrolle

Thorben Wengert / pixelio.de

Page 9: JavaScript Performance

Analyse

Tim Reckmann / pixelio.de

Page 10: JavaScript Performance

Developer Tools

Page 11: JavaScript Performance

Analyse

Meist weiß man, wo die Applikation langsam ist. Ansonsten werden CPU, Memory, Rendering und Netzwerk überprüft.

Konkrete Messwerte für den späteren Vergleich festhalten.

Profile-Daten können gespeichert, geladen und verglichen werden.

Page 12: JavaScript Performance

Bewertung

bschpic / pixelio.de

Page 13: JavaScript Performance

Bewertung

Meist findet man mehrere Problemstellungen, hat jedoch nicht genügend Ressourcen. Also Kosten-Nutzen-

Abwägung durchführen. Cheap Wins zuerst durchführen, gravierende Umbauten mit

wenig Benefits eher nicht durchführen.

Erwartete Verbesserung oder Zielmetrik festhalten.

Page 14: JavaScript Performance

BewertungMaßnahme Aufwand Nutzen

GZIP Compression — +

Concat & Uglify + ++

DOM verkleinern ++ +

DOM Operationen gruppieren ++ ++

… … …

Page 15: JavaScript Performance

Durchführung

I-vista / pixelio.de

Page 16: JavaScript Performance

Durchführung

Anpassung des Quellcodes. Es sollte auf jeden Fall ein Versionskontrollsystem (git, svn) eingesetzt werden. So

können die Stände verglichen und falls nötig zurückgesetzt werden.

Tests nicht vergessen!

Page 17: JavaScript Performance

Kontrolle

Tim Reckmann / pixelio.de

Page 18: JavaScript Performance

Kontrolle

Die Messwerte der Analyse werden mit den aktuellen Werten der Applikation verglichen.

Im Anschluss steht die Entscheidung, ob weitere Verbesserungen erforderlich sind oder ob weitere Maßnahmen keinen erheblichen Mehrwert bieten.

Page 19: JavaScript Performance

Performance

Netzwerk CPU

Memory Rendering

Page 20: JavaScript Performance

Netzwerk

Klicker / pixelio.de

Page 21: JavaScript Performance

Netzwerk

Anfragen vom Client an den Server über HTTP. Browser haben nur eine gewisse Anzahl an parallelen

Requests pro Subdomain.

Page 22: JavaScript Performance

Netzwerk

https://developer.chrome.com/devtools/docs/network

Navigation Timing API: https://developer.mozilla.org/en-US/docs/Navigation_timing

Page 23: JavaScript Performance

Netzwerk

Page 24: JavaScript Performance

Netzwerk• Stalled/Blocking: Zeit, bevor die Anfrage gesendet wird.

• Proxy Negotiation: Verbinden mit Proxy.

• DNS Lookup: Hostnamen auflösen.

• Initial Connection: TCP Handshake, SSL Negotiation

• SSL: SSL Handshake

• Request Sent: Versenden der Anfrage.

• Waiting (TTFB): Initiale Antwort des Servers.

• Content Download: Herunterladen der Antwort.

Page 25: JavaScript Performance

Netzwerk• Anzahl der Requests reduzieren

• Größe der Responses reduzieren

• gzip aktivieren

• DNS Lookups reduzieren (wenige unterschiedliche Hosts)

• Caching

Page 26: JavaScript Performance

CPU

Tim Reckmann / pixelio.de

Page 27: JavaScript Performance

CPU

Prozessor-Ressourcen, die benötigt werden, um den JavaScript-Quellcode auszuführen.

Die meiste Performance geht aber durch DOM-Operationen verloren.

Page 28: JavaScript Performance

CPU

JavaScript Engines weisen zahlreiche Optimierungen auf. Häufig liegen die Probleme nicht an der Ausführung des

JavaScript-Quellcodes.

Page 29: JavaScript Performance

Hidden ClassesOptimierung des Browsers, um schneller auf Eigenschaften

von Objekten zuzugreifen.

Page 30: JavaScript Performance

Maschinencode Generierung

point.x

# ebx = the point object cmp [ebx,<hidden class offset>],<cached hidden class> jne <inline cache miss> mov eax,[ebx, <cached x offset>]

Gibt es für die Eigenschaft eine Hidden Class, wird diese verwendet. Ansonsten wird der Cache Miss behandelt. Dann

wird der Wert für die Eigenschaft ausgeliefert.

Page 31: JavaScript Performance

Garbage Collection

Aufräumen des Speichers. Zwei Speicherbereiche. Mit unterschiedlichen Algorithmen.

GC benötigt Zeit, hält die Applikation komplett an. Das kann zu Ruckeln in Applikationen führen.

Page 32: JavaScript Performance

Timeline

Die Timeline der Chrome Developer Tools gibt einen ersten Überblick über CPU und Memory Daten und ist ein guter

Ausgangspunkt für die Analyse von Performance-Problemen.

Page 33: JavaScript Performance

Timeline

Page 34: JavaScript Performance

CPU

Das CPU-Profile gibt genaueren Aufschluss darüber, welche Routinen wie viele Ressourcen benötigt haben. Drei

verschiedene Darstellungsarten:

- Chart: Flame Chart - Heavy (Bottom up): Tablle mit den teuersten Routinen oben - Tree (Top Down): Baumdarstellung

Page 35: JavaScript Performance

CPU

Page 36: JavaScript Performance

CPU - ChartEine Funktion hat immer die gleiche Farbe. Erleichtert die

Mustererkennung. Simulieren Callstacks jeweils mit Verweis auf die

entsprechende Codestelle.

Name: Funktionsname Self time: Zeit der Funktion selbst

Total time: Zeit der Funktion und aller Unterfunktionen Aggregated self time: Summe der self time aller Aufrufe

Aggregated total time: Summe der total time aller Aufrufe

Page 37: JavaScript Performance

CPU

Page 38: JavaScript Performance

CPU

Page 39: JavaScript Performance

Call Graphs?

code2flow: experimentelles Tool zur Generierung von Call Graphs

https://github.com/scottrogowski/code2flow

Page 40: JavaScript Performance

https://github.com/scottrogowski/code2flow/blob/master/jqueryexample.png

Call Graph für jQuery

Page 41: JavaScript Performance

Memory

Jan von Bröckel / pixelio.de

Page 42: JavaScript Performance

Memory

Arbeitsspeicher, der durch die Applikation verbraucht wird. JavaScript-Objekte, Repräsentationen von DOM-Elementen,

Page 43: JavaScript Performance

Heap Snapshot

Radka Schöne / pixelio.de

Page 44: JavaScript Performance

Heap Snapshot

• Summary: Zusammenfassung

• Comparison: Vergleich zweier Snapshots

• Containment: Übersicht über die Objektstruktur

• Statistics: Verteilung des Speichers auf Objekttypen

Verschiedene Views:

Abbild des aktuellen Speichers.

Page 45: JavaScript Performance

Heap Snapshot

Shallow Size: Speicher, den ein Objekt selbst benötigt.

Retained Size: Speicher, den ein Objekt und die nur von ihm referenzierten Objekte benötigen.

Distance: Kürzester Weg durch die Memory Hierarchie.

Page 46: JavaScript Performance
Page 47: JavaScript Performance

Record Heap Allocations

Tim Reckmann / pixelio.de

Page 48: JavaScript Performance

Record Heap Allocations

Wie der Snapshot, nur über Zeit gesehen. Zum Auffinden von Memory Leaks.

Page 49: JavaScript Performance
Page 50: JavaScript Performance

Rendering

Burkard Vogt / pixelio.de

Page 51: JavaScript Performance

Rendering

Reflow: Neuberechnung der Positionen und Geometrie von DOM-Elementen.

Blockierende Operation.

Wann passieren Reflows: DOM-Elemente hinzufügen/entfernen, Klassen anpassen, …

Page 52: JavaScript Performance
Page 53: JavaScript Performance

bschpic / pixelio.de

Best Practices

Page 54: JavaScript Performance

Best Practices

Was kann man bereits bei der Entwicklung beachten, um Performance-Probleme zu vermeiden?

Page 55: JavaScript Performance

WebworkersKomplexe Berechnungen verzögern die Ausführung und

Blockieren die Applikation. Mit HTML5 kommen Webworker: Kindprozesse im Browser.

Kommunikation über Nachrichten.

Workerprozess hat Zugriff auf: navigator, location, xhr, timing,

Kein Zugriff auf: DOM, window, document, parent

Page 56: JavaScript Performance

Webworkersvar worker = new Worker('worker.js');worker.postMessage('Hello Worker'); worker.addEventListener('message', function (data) { console.log(data);});

index.js

worker.jsself.addEventListener('message', function (data) { self.postMessage('Hello Main'); });

Page 57: JavaScript Performance

Variablen und Datenstrukturen

Lokale Variablen nutzen, ist schneller als Property-Zugriff und Array-Zugriff.

Objekte und Properties cachen.

Je tiefer ein Array strukturiert ist, desto langsamer wird der Zugriff.

Page 58: JavaScript Performance

Prototypen und Methodenfunction Calculator() { this.add = function () {}}

function Calculator() {}Calculator.prototype.add = function () {};

vs

Für jede Instanz wird ein neues Funktionsobjekt erzeugt und eine neue Closure generiert, was alles Speicherplatz

benötigt.

Page 59: JavaScript Performance

Prototypen und Wertefunction Calculator() { this.a = 1; this.b = {};}

function Calculator() { this.b = {};} Calculator.prototype.a = 1;

vs

Initialisierungslogik muss nicht jedes Mal durchlaufen werden.

Page 60: JavaScript Performance

ClosuresEine Closure ist eine Funktion und ihr erstellender Kontext. Benötigt also für die Funktion und den erstellenden Kontext

Speicher.

Quelle für Memoryleaks.

DOM-Elemente zeigen auf Closures und umgekehrt. GC kann nicht aufräumen.

Sobald eine Callback-Funktion registriert wird, kann sie nicht durch den GC freigegeben werden. Callbacks sollten

deregistriert werden.

Page 61: JavaScript Performance

function async() { var msg = 'Hello World'; setTimeout(function() { console.log(msg); }, 1000); }

Inner Funktion mit Closure

function async() { setTimeout(function() { var msg = 'Hello World'; console.log(msg); }, 1000); }

Inner Funktion ohne Closure

function sayHello() { var msg = 'Hello World'; console.log(msg);} function async() { setTimeout(sayHello, 1000);}

Statische Funktion

Schnell

Langsam

Page 62: JavaScript Performance

ClosuresZugriff auf Variablen wird langsamer durch zusätzliche

Scopes. Je weiter nach außen, desto langsamer wird es.

function createFunctionWithClosure() { var b = 'b'; return function () { var c = 'c'; a; b; c; }; }

createFunctionWithClosure(); c > b > a

Page 63: JavaScript Performance

Kein with

Die Scope Chain wird modifiziert. Es wird teurer, auf Variablen zuzugreifen.

var a, x, y; var r = 10; with (Math) { a = PI * r * r; x = r * cos(PI); y = r * sin(PI / 2);}

Page 64: JavaScript Performance

Browser Memory Leaks

Expando Properties: Beliebige Eigenschaften auf DOM-Objekten ,die z.B. zirkuläre Referenzen halten können.

Obj A > Obj B > Obj A

Im besten Fall komplett vermeiden.

Page 65: JavaScript Performance

Arbeit in Schleifen reduzieren

Jedes Statement in einer Schleife wird pro Schleifendurchlauf ausgeführt.

Funktionsdefinitionen oder Ähnliches vermeiden.

Möglichst statischen Code außerhalb und wirklich nur das Nötigste in der Schleife halten.

for (var i = 0; i < arr.length; i++) {}

var length = arr.length; for (var i = 0; i < length; i++) {}

Page 66: JavaScript Performance

Rendering

DOM einfach und flach halten.

Möglichst wenige CSS Regeln.

Für komplexes Rendering - position: absolute oder position: fixed

Einfache CSS Selektoren.

Page 67: JavaScript Performance

Wenige DOM-Zugriffe

DOM-Zugriffe nur wenn erforderlich. Zusammenfassen von DOM-Zugriffen.

Elemente wiederverwenden.

Page 68: JavaScript Performance

Unnötige Variablen vermeiden

var name = firstname + ' ' + lastname;console.log(name);

console.log(firstname + ' ' + lastname);

vs.

Jede Variable benötigt Speicherplatz. Der GC bekommt Arbeit.

Page 69: JavaScript Performance

JavaScript spät laden

JavaScript im Fuß der Seite laden.

JavaScript möglichst asynchron laden.

Alternative ist <script defer=“true” src=“”></script> JS wird nach dem Parsen geladen.

<script async src=“”></script> JS wird parallel zum Parsen geladen.

Page 70: JavaScript Performance

JavaScript on demand laden

RequireJS erlaubt nachträgliches Laden von Dateien zur Laufzeit.

Auch mit Browserify ist Lazy Loading möglich.

Page 71: JavaScript Performance

Achtung

Keine Premature Optimization - die richtigen Optimierungen erst, wenn man sie braucht.

Keine Mikrooptimierung

Der Quellcode soll lesbar und wartbar bleiben.

Page 72: JavaScript Performance

Fragen?

Rainer Sturm / pixelio.de

Page 73: JavaScript Performance

KONTAKT

Sebastian Springer [email protected]

Mayflower GmbH Mannhardtstr. 6 80538 München Deutschland

@basti_springer

https://github.com/sspringer82


Recommended