Häufige Javascript-Fehler, die die Leistung stark beeinträchtigen? [geschlossen]

10

Bei einem kürzlich von mir besuchten UI / UX-MeetUp gab ich Feedback zu einer Website, auf der Javascript (jQuery) für die Interaktion und Benutzeroberfläche verwendet wurde - es waren ziemlich einfache Animationen und Manipulationen, aber die Leistung auf einem anständigen Computer war schrecklich.

Es erinnerte mich tatsächlich an viele Websites / Programme, die ich mit demselben Problem gesehen habe, bei denen bestimmte Aktionen die Leistung absolut zerstören. Dies geschieht hauptsächlich in Situationen (oder zumindest in Situationen, in denen Javascript fast als Flash-Ersatz dient). Dies steht in krassem Gegensatz zu einigen der von mir verwendeten Webapps, die weitaus mehr Javascript und Funktionalität bieten, aber sehr reibungslos funktionieren (COGNOS von IBM ist eines, an das ich auf Anhieb denken kann).

Ich würde gerne einige der häufigsten Probleme kennen, die bei der Entwicklung von JS nicht berücksichtigt werden und die Leistung der Website beeinträchtigen.

Nic
quelle
Wahrscheinlich dasselbe wie bei jedem anderen Programm: Mehr Arbeit als nötig erledigen und immer wieder dieselbe Arbeit erledigen, oft hunderte Male.
1
@delnan das ist sehr wahr, aber es scheint, dass es in JS viel häufiger ist. Wahrnehmung vielleicht?
Nic
1
Wenn man über JavaScript spricht, wird es etwas passe, von "der Site" zu sprechen. Es ist überall und wird heutzutage für alles verwendet.
Adam Crossland
@Adam Crossland Sie haben absolut Recht - in demselben Fall habe ich einem Entwickler mit einer nativen App geholfen, die sich ebenfalls stark auf jQuery stützte.
Nic
1
Nicht gerade eine Antwort auf Ihre Frage, daher mache ich einen Kommentar: Ich habe Situationen erlebt, in denen JavaScript viel gerendert hat, und es war tatsächlich die Rendering-Engine des Browsers, die die Sekunden verbraucht hat. Um einen Leistungsengpass zu beheben, würde ich daher zuerst nach unnötigen Rendering-Vorgängen suchen.
user281377

Antworten:

8

Ein häufiger Leistungskiller ruft .lengtheine HTMLCollection innerhalb einer forSchleife auf:

function foo(collection) {
    for (var index = 0; index < collection.length; index++) {
        // do something awesome here
    }
}

Dieses Anti-Muster bewirkt, dass die Größe der Sammlung bei jedem Durchlauf durch die Schleife berechnet wird. Der bessere Ansatz besteht darin, die Länge außerhalb der Schleife zu berechnen:

function foo(collection) {
    var collectionLen = collection.length;
    for (var index = 0; index < collectionLen; index++) {
        // do something awesome here
    }
}
Adam Crossland
quelle
3
Kommt auf den Browser an. Nehmen Sie diesen Benchmark als Beispiel: In FF 5 läuft der "normale" fast zur gleichen Zeit wie die "optimierte" Version. Und selbst in wirklich alten und trägen Browsern wird so etwas wahrscheinlich kein Engpass sein, wenn der JS tatsächlich etwas Interessantes mit den Elementen macht.
1
Hmm! Vielleicht machen die hochoptimierenden JIT-Compiler von heute dieses Stück Weisheit überflüssig.
Adam Crossland
4
Ich bin hier kein wirklicher Experte, aber aus der ECMA-Spezifikation geht hervor, dass die Länge nur eine Eigenschaft des Array-Objekts ist. Wenn Sie es also aufrufen, wird nur der Wert zurückgegeben, anstatt alle Elemente zu zählen. Keine Ahnung, ob alle Implementierungen der Spezifikation entsprechen, aber wenn dies der Fall ist, verbessert Ihr Code die Leistung überhaupt nicht.
Jacek Prucia
4
@JacekPrucia Er sagte, Sammlung , nicht Array - normalerweise würde dies in echtem Code eine Liste von DOM-Elementen bedeuten, die von Funktionen wie zurückgegeben werden document.getElementsByTagName. Die Funktion gibt ein Live zurück, nodeListdas bei jedem .lengthZugriff auf die Eigenschaft die Länge neu berechnet .
Yi Jiang
2
@ JacekPrucia Benchmark ist eine Leistungsverbesserung. Immobiliensuche ist nicht billig.
Raynos
4

Nein, das Problem kommt nicht von JS, das als Flash-Ersatz verwendet wird. Wenn Sie davon nicht überzeugt sind, dokumentieren Sie sich über Actionscript: Es ist sehr nah an JS.

Als Performance-Killer gibt es mehrere schlechte Praktiken:

  • Fügen Sie den Ereignishandler an ein kontinuierliches Ereignis an, z. B. Scrollen, Bewegen der Maus oder ähnliches. Dies hat zwei Nachteile: Wenn das Ereignis nicht ausreichend ausgelöst wird, ist Ihre Anwendung nicht reaktiv. Wenn es zu viel ausgelöst wird, haben Sie eine enorme CPU-Auslastung für nichts.
  • Synchrone AJAX-Anrufe tätigen. Javascript ist kein Multithread-Programm. Wenn ein Teil von JS auf etwas wartet, wird Ihre Anwendung eingefroren. Verwenden Sie besser asynchrone AJAX-Aufrufe und verwenden Sie auf die gleiche Weise setTimeout / setInterval, um eine lange Berechnungsphase aufzuteilen und Ihre Anwendung reaktiv zu halten.
  • Hohe Algorithmuskomplexität wie in allen anderen Sprachen.
deadalnix
quelle
Ich habe mehr als ein paar Apps gesehen, die versucht haben, Vollbrowser-Bilder zu drehen, zu vereinfachen oder zu animieren, und dabei kläglich versagt haben - daher stammt der Kommentar zum Flash-Ersatz :)
Nic
Da das erste A in AJAX für asynchron steht, ist es technisch gesehen nicht AJAX, wenn es synchron ist, aber Ihr Punkt ist immer noch gut.
Karl Bielefeldt
Ja richtig, es ist nicht ausschließlich AJAX. Aber trotzdem muss dies vermieden werden: D
deadalnix
3

Ich gab einige Rückmeldungen zu einer Website, die Javascript (jQuery) für ihre Interaktion und Benutzeroberfläche verwendete - es waren ziemlich einfache Animationen und Manipulationen, aber die Leistung auf einem anständigen Computer war schrecklich.

Das größte Problem bei der Leistung ist die Verwendung von Abstraktionen auf hoher Ebene (wie jQuery), ohne das zugrunde liegende DOM-Modell und das CSS3-Animationsmodell (oder Canvas oder SVG) zu verstehen.

Wenn Sie nicht wissen , wie es ohne die Abstraktionen zu tun , dann haben Sie absolute Null Wissen, was Techniken sind schnell oder langsam.

Lerne JavaScript, lerne das DOM. Sobald Sie diese beiden kennen und wissen, was Ihre Abstraktionen unter der Haube tun, können Sie sie effizient nutzen. Natürlich ist die Abstraktion die meiste Zeit zu langsam und wird einfach manuell ohne Bibliothek ausgeführt.

Raynos
quelle
1

Das Schöne und der Nachteil von Javascript ist, dass es äußerst flexibel ist. Davon abgesehen können Sie tatsächlich Dinge tun, die Sie in vielen Fällen wahrscheinlich nicht tun sollten.

Aufgrund der Codeüberprüfungen, an denen ich beteiligt war, beziehen sich die Hauptprobleme in der Regel auf das CSS-Rendering. Für neuere JS-Entwickler sehen wir tendenziell viel zu viele Variablen, die im globalen Bereich verwendet werden.

Außerdem können unsachgemäße Schließungen häufig zu Speicherlecks führen. Die meisten modernen Javascript-Frameworks verhindern jedoch solche Probleme, solange Ihr Code dem Framework folgt.

Es grunzt
quelle
0

Hier ist ein kurzer Link, den ich vor ungefähr einem Jahr über das Schreiben eines besseren Abfragecodes gefunden habe: http://net.tutsplus.com/tutorials/javascript-ajax/10-ways-to-instant-increase-your-jquery-performance /.

Eine Sache, die ich gerade in einem Mitarbeitercode gefunden habe, der die Leistung beeinträchtigte, war das Zwischenspeichern von Daten, die nicht zwischengespeichert werden mussten.

Beispiel:

var table = $("#data").dataTable(.....);

DataTables ist ein jQuery-Plug-In, mit dem wir schöne Raster erstellen. Wie auch immer, die Tabelle enthielt fast 5.000 Zeilen. Durch Anwenden des DataTables-Plug-Ins und anschließendes Speichern in der Tabellenvariablen warnten sowohl FireFox als auch IE, dass ein Skript zu lange dauerte. Moral der Geschichte, zwischenspeichern Sie die Daten nur, wenn Sie müssen.

Tyanna
quelle
1
Klingt so, als wäre DataTables eher ein wirklich ineffizientes / schlechtes Plugin als ein Problem beim Caching. 5k ist nichts.
Raynos
@ Raynos: Er sagte 5k Zeilen , nicht 5 Kilobyte Daten. Eine "Reihe" könnte eine sehr große Sache sein.
Chris Farmer
@ChrisFarmer Wenn eine "Zeile" eine sehr große Sache ist, dann haben Sie ein anderes Problem.
Raynos
-1

Soweit ich gehört habe, sind forLoops rechnerisch schneller als jQuerys $.each().

These
quelle
3
Ist das eine Scherzantwort?
Raynos