Less.js: Version 3.10.x benötigt deutlich mehr Speicher und ist deutlich langsamer als 3.9.0

Erstellt am 12. Sept. 2019  ·  95Kommentare  ·  Quelle: less/less.js

Unsere Builds schlugen vor kurzem fehl, weil wir während des Build-Prozesses unseres Projekts etwa 80 Less-Builds parallel ausführen und die neue Version von Less.js so viel Speicher verbraucht, dass Node abstürzt. Wir haben den Absturz auf das Upgrade von Less.js von 3.9.0 auf 3.10.3 zurückgeführt.

Ich habe unser Less-Skript geändert, um die Dateien sequentiell zu kompilieren (zwei Dateien gleichzeitig zu erstellen) und die Speichernutzung von Node während des Vorgangs abgetastet und die folgenden Ergebnisse erhalten:

less graph

Less.js scheint jetzt 130% mehr Speicher zu verbrauchen und dauert etwa 100% länger, um für uns zu kompilieren.

Ich frage mich nur, ob Sie Less.js einem Benchmark unterzogen haben und ob Sie ähnliche Ergebnisse sehen

Hilfreichster Kommentar

Okay-Team! Ich werde den 3.x-Build veröffentlichen und irgendwann später, vielleicht nächste Woche, 4.0 veröffentlichen. Beide sollten jetzt die Performance-Fixes haben. Danke an alle, die beim Debuggen geholfen haben!

Alle 95 Kommentare

Das ist seltsam. Was ist Ihre Node-Version?

@PatSmuk360 Könnten Sie ein Speicherprofil von 3.10.0 testen und abrufen und sehen, ob es sich unterscheidet?

Wir verwenden die neueste Version von 10 (10.16.3).

Heap-Snapshot vor:

image

Heap-Snapshot nach:

image

Ich habe es auch mit Node 12.10.0 versucht und es scheint viel schlimmer zu sein, da es an einem Punkt im sequentiellen Build 587 MB Speichernutzung erreicht hat.

@PatSmuk360 Der Unterschied zwischen diesen Versionen besteht also darin, dass die Codebasis in die ES6-Syntax umgewandelt wurde. Was technisch gesehen keine bahnbrechende Änderung ist, weshalb es keine Hauptversion war.

ABER ... mein Verdacht ist, dass einige der Babel-Konvertierungen für Dinge wie die Syntax der Objekt- / Array-Spreads weniger effizient sind als die ausführlicheren ES5-Versionen. Aus diesem Grund habe ich gefragt, ob Sie 3.10.0 testen könnten, da ich ursprünglich ein transpiliertes Paket exportierte, das mit Node 6 und höher kompatibel war, aber eine Integration mit einer bestimmten Bibliothek brach , die die Klassensyntax nicht verarbeiten konnte. Also ging ich zu Node 4 ohne Klassenkonstrukte.

Wenn wir genau herausfinden können, welche ES5-Transformation nicht gut funktioniert, könnten wir diese Babel-Exporteinstellungen theoretisch auf einen leistungsfähigeren Export einstellen.

@PatSmuk360 Übrigens, was ist diese split Funktion, die so viel Zeit braucht ?

@matthew-dean Das scheint das String.prototype.split . Wenn Sie das Profil in Ihren Chrome-Devtools öffnen, können Sie alle Daten farbcodiert sehen. Ich versuche, das Profil so zu ändern, dass es auf https://cdn.jsdelivr.net/npm/[email protected]/dist/less.cjs.js als Quelle verweist, damit es einfacher ist, die Engpässe zu untersuchen. Gibt es eine Quellzuordnung für die Datei *.cjs.js bis *.js ? Die Datei https://cdn.jsdelivr.net/npm/[email protected]/dist/less.min.js.map scheint die Datei .min der ES6-Quelle zuzuordnen. Vielleicht können wir die Quellzuordnung an die Entwicklungstools füttern, damit wir herausfinden können, wo die Transpilation Engpässe verursacht.

Diese Zeile in bestimmten https://github.com/less/less.js/blob/cae5021358a5fca932c32ed071f652403d07def8/lib/less/source-map-output.js#L78 scheint eine hohe CPU-Zeit zu haben. Aber in Anbetracht der Operation, die es durchführt, scheint mir das nicht fehl am Platz.

Ich habe nicht viel Erfahrung mit Heap-Profilen, aber was mir auffällt, ist die Erhöhung um (closures), (system), (array), system / Context . Beim Versuch, dies mit dem CPU-Profil zu verbinden, scheint die Zunahme dieser Objekte zu einer massiven Zunahme der Zeit für das Sammeln von Datenmüll zu führen.

@kevinramharak Im Allgemeinen

@kevinramharak Re: die

Ich verwende less.min.js in einem Browser und 3.10.3 ist zweimal langsamer als 2.7.3, das ich zuvor verwendet habe. Sowohl in Chrome als auch in Firefox.

@PatSmuk360 Kannst du dir diese Filiale https://github.com/matthew-dean/less.js/tree/3.11.0

Kurz gesagt, Babels Transpilation auf ES5 ist ziemlich schrecklich und verwendet Tonnen von Object.defineProperty-Aufrufen, um Klassen zu transpilieren. Ich habe die Transpilation auf TypeScript umgestellt, das eine viel vernünftigere Ausgabe von Funktionsprototypen hat.

Das ist alles in Ordnung und gut, aber danach werden die Browsertests von Less nicht ausgeführt, da es das sehr alte und veraltete PhantomJS verwendet, und bisher konnte niemand (einschließlich mir) die Tests erfolgreich von PhantomJS migrieren auf Headless Chrome.

Aber ein Problem nach dem anderen: Wenn die dist-Quelle in diesem Zweig keine Speicherprobleme hat, könnten wir vielleicht das Durcheinander beim Browser-Testen angehen.

Ich habe es geschafft, Less-Browsertests zu Headless Chrome zu migrieren, aber in Bezug auf Leistung / Stabilität benötige ich viel Feedback von Benutzern, bevor die Zusammenführung sicher ist, da die Transpilationspipeline vollständig von Babel auf TypeScript umgestellt wurde.

Aktuelle Filiale(n) finden Sie hier: https://github.com/less/less.js/pull/3442

Immer noch 2x langsamer als 2.7.

@alecpl Das sind gute Informationen, aber ich möchte wirklich wissen, ob 3.11.0 eine Verbesserung gegenüber 3.10 ist.

Das Seltsame daran ist, dass _theoretisch_ der ursprüngliche Less-Code mit Lebab konvertiert wurde, was das Gegenteil von Babel sein sollte. Das bedeutet, dass ES5 -> ES6 -> ES5 fast identisch sein sollte, aber das ist offensichtlich nicht der Fall. Ich muss also untersuchen (es sei denn, jemand anderes hat die Zeit, was eine willkommene Unterstützung ist), wie sich der ES6->ES5-Code vom ursprünglichen ES5-Code unterscheidet.

@alecpl

Also habe ich eine Vielzahl von Tests durchgeführt und die Zeit damit verbracht, Benchmarking von 3.11.0 vs. 3.10.3 vs. 3.9.0 vs. 2.7.3 in Headless Chrome durchzuführen

Ich habe keine Beweise dafür gefunden, dass der Less-Compiler für irgendeine Version langsamer ist, geschweige denn 2x langsamer. Es könnte immer noch wahr sein, dass 3.10.0 aufgrund der Transpilationseinstellungen mehr Speicher-Overhead hat, und vielleicht kann es zu einer Verlangsamung führen, wenn ein System hinsichtlich des Speicherplatzes eingeschränkt ist und mehr Speicher-Swaps oder mehr GC durchführt? Aber ich kann es nicht verifizieren.

Sie können sich selbst testen, wie Sie grunt benchmark im 3.11.0-Zweig ausführen. Sie können unterschiedliche Zahlen für einen einzelnen Lauf melden, aber wenn Sie genug laufen, sollten Sie sehen, dass die Zeiten ungefähr gleich sind. Also ich weiß nicht woher du deine Daten hast.

@PatSmuk360 Konnten Sie den Speicher-Overhead von 3.11.0 testen?

Ich baue deinen Code nicht selbst. Nodejs verwende ich nicht. Ich nehme einfach die Datei less.min.js aus dem Ordner dist für zwei verschiedene Versionen, die ich erwähnt habe, und verwende sie auf meiner Seite. Dann sehe ich in der Konsole Timings, die von Less-Code gedruckt werden. Mein weniger Code verwendet mehrere Dateien und die Ausgabedatei ist ungefähr 100 kB an minimiertem CSS. Das ist ein "real life" Benchmark. Ich spreche von Roundcube- Code.

Chrome ist viel schneller als Firefox, aber in beiden ist der Unterschied zwischen den Versionen ähnlich.

@alecpl Hmm .... vielleicht ist es ein besonderer Unterschied für diesen bestimmten Less-Code. Es stimmt, dass der Benchmark willkürlich ist. Wenn ich Zeit habe, füge ich diese Less-Dateien zum Benchmarking hinzu.

Dieses Problem wurde automatisch als veraltet markiert, da es in letzter Zeit keine Aktivität hatte. Es wird geschlossen, wenn keine weitere Aktivität stattfindet. Vielen Dank für Ihre Beiträge.

Wollte nur ein kurzes Update posten: Ich habe 3.11.1 ausprobiert und es war genauso langsam wie 3.10.3. Ich werde sehen, ob ich einen repräsentativen Benchmark für das Testen / Profilieren kann.

Ich habe auf 3.11.1 aktualisiert und habe jetzt die gleichen Speicherverbrauchsprobleme.
Ein bescheidenes Projekt benötigt ~600 MB RAM, um über Webpack und less-loader .

Ich habe eine Zeitachse für die Heap-Zuweisung erstellt, die zu diesem Ergebnis führt.

heap-timeline

Etwas verursacht verrückte riesige Zuweisungen, die von Ruleset am Leben gehalten werden.


[BEARBEITEN]
Ich mache ein Downgrade auf 3.9 und greife daraus eine Heap-Alloc-Timeline. Mal sehen, ob ich etwas radikal anderes entdecke.

@matthew-dean
Habe einen Hinweis für dich gefunden.

In 3.11 ist einer der aufgeführten Retainer für RuleSet der ImportManager.
In 3.9 ist dies _nicht der Fall_.

Wenn alles von ImportManager am Leben gehalten wird und ImportManager ein Singleton über den gesamten Kompilierungsprozess ist. Nun ja; das würde den Speicherverbrauch erheblich aufblähen, da nichts müllgesammelt werden kann. Nicht einmal zwischengeschaltete Regelsätze.

@rjgotten Hmm ...... wenn ein Objekt einen Verweis auf ein anderes Objekt hat, warum würde das GC verhindern? Ich meine, technisch gesehen behalten alle Objekte Verweise auf die öffentlichen API-Knoten über die Prototypkette. Es würde GC nur verhindern, wenn das Gegenteil der Fall ist, dh ein Objekt behält Verweise auf jede Regelsatzinstanz.

Du scheinst dich falsch verstanden zu haben.

Wenn "A ein Halter von B ist", bedeutet dies, dass A Verweise auf B behält, die die Garbage Collection von B verhindern. Als ich also schrieb, dass ImportManager als Retainer von Ruleset aufgeführt ist, habe ich genau das ausgedrückt, was Sie auch schlussfolgern: ImportManager enthält Verweise auf Ruleset-Instanzen, was die GC dieser Ruleset-Instanzen verhindert.

@rjgotten Oh tut es das? Ich frage mich, wie diese Veränderung da reingekommen ist. Starke Möglichkeit, dass ich schuld bin, oder es gibt etwas an der ES6-Refaktorierung, die es verursacht hat. Aber ja, das könnte es definitiv tun! Danke für die Untersuchung!

Okay, was ist mit dieser radikalen Idee.

Ich habe einen Zweig erstellt, in dem ich alles außer der ES6-Konvertierung ausgewählt habe. Das war nicht einfach und würde die ganze Arbeit zunichte machen, aber wenn eine Babelified / Typescript-Datei das vorhandene native JS nicht übertreffen kann, dann ist es es einfach nicht wert.

Ich habe keine Ahnung, wie wir den Git-Verlauf abgleichen werden, aber hier ist der Zweig -> https://github.com/less/less.js/tree/release_v3.12.0-RC1. Die Konvertierung zu knacken ist eine große Sache, daher denke ich, dass dieser Zweig ein echtes solides Benchmarking zum Vergleichen wäre.

Ich frage mich, wie diese Veränderung da reingekommen ist. Starke Möglichkeit, dass ich schuld bin, oder es gibt etwas an der ES6-Refaktorierung, die es verursacht hat. Aber ja, das könnte es definitiv tun! Danke für die Untersuchung!

Es ist sicherlich seltsam. Nach dem, was ich entziffern konnte, sieht es so aus, als würde ImportManager durch Gluecode/Polyfill, das durch die ES6-Konvertierung hinzugefügt wurde, irgendwie zu einem Retainer für Regelsätze werden.

Ich frage mich, ob es hier eine Lösung gibt, die auf halbem Weg endet. Dh den ES6-Build für Node.js beibehalten, aber auch ein transpiliertes Browser-Target haben. Es wäre ein enormer Verlust, die Code-Klarheit zu beseitigen, die die ES6-Konvertierung hinzufügt. 😢

@rjgotten

Es wäre ein enormer Verlust, die Code-Klarheit zu beseitigen, die die ES6-Konvertierung hinzufügt.

Es kann aus zwei Gründen nicht so schlimm sein, wie es scheint:

  1. Die Rollup-Konfiguration existiert noch und könnte aus einem Commit gezogen werden, wenn jemand sie recherchieren möchte.
  2. Ich arbeite seit einiger Zeit aktiv an einem TypeScript-basierten Less 4.0. Ich verbringe lieber meine Zeit damit, als diesen Leistungsrückgang aufzuspüren. Es ist ein grundlegender Refaktor, also keineswegs naheliegend, aber aufgrund der Natur von TS ist es unwahrscheinlich, dass es diese einmaligen Objektmutationen gibt, die an Referenzen festhalten und GC verhindern. Und der Code ist viel klarer zu befolgen . Das gibt es also.

Es scheint _bit_ schwerfällig zu sein, alles auf ES5 zurückzusetzen, nur um dieses Problem zu beheben, aber es ist verständlich, da ein Neuschreiben im Gange ist. Dennoch sollten wir uns überlegen, wie lange wir mit dieser Entscheidung leben müssen. Wie @rjgotten erwähnte, würden wir viel Code-Klarheit verlieren, und wenn v4 noch in weiter Ferne ist, dann würde ich sagen, lasst uns versuchen, ein bisschen mehr zu untersuchen, bevor wir die nukleare Option ES5 wählen – besonders seit diesem Problem (während a schlecht) scheint für die meisten Benutzer kein Dealbreaker zu sein.

Gibt es jemanden, der diese Erfahrung gemacht hat und bereit wäre, seinen Code zu teilen? Es wäre großartig, wenn wir anhand eines realen Projekts einen Benchmarking durchführen könnten, damit wir sicher sein können, ob Änderungen helfen oder nicht. Wenn wir das bekommen könnten, wäre ich bereit zu helfen, den Engpass einzugrenzen.

@matthew-dean, nebenbei, haben Sie versucht, mit Babel im losen Modus zu kompilieren, um zu sehen, ob ein vernünftiger aussehender Code erzeugt wurde?

@seanCodes Ich bin dafür, die nukleare Option nicht zu

Eine Vermutung, die ich habe, ist, dass ein Teil der Destrukturierungslogik viele Boilerplates zur Objekterstellung enthält.

Im Grunde müsste sich jemand freiwillig melden, um dieses Problem zu besitzen.

@matthew-dean, nebenbei, haben Sie versucht, mit Babel im losen Modus zu kompilieren, um zu sehen, ob ein vernünftiger aussehender Code erzeugt wurde?

@seanCodes Der Code wird mit TypeScript kompiliert, nicht mit Babel. Meine Idee war, nach und nach JSDoc-Typen hinzuzufügen, um die Typprüfung zu verstärken, aber der TS in v4 ist genug umgeschrieben, ich bin mir nicht sicher, ob das notwendig ist. Also könnte jemand mit Babel vs. TypeScript (und jeweils unterschiedlichen Einstellungen) experimentieren, um zu sehen, ob Babel performanteren Code produziert. Seien Sie sich dieses Problems bewusst, das durch die anfängliche Erstellung eines Nicht-ES5-Builds für Node.js verursacht wurde: https://github.com/less/less.js/issues/3414

@seanCodes Außerdem fand ich es immer noch schwierig, den Leistungsunterschied zu ÜBERPRÜFEN. Niemand hat eine PR / Schritte erstellt, um definitiv den Leistungsunterschied zu BEWEISEN. Es gibt eine Reihe von Anekdoten in diesem Thread, aber ohne reproduzierbaren Code oder Schritte bin ich mir nicht sicher, wie jemand dies untersucht. Idealerweise gibt es einen PR, der ein Profiling-Tool (über Chrome-Debugger oder anderweitig) startet, um eine Zahl auf einem System auszugeben, die über eine Reihe von Tests gemittelt wird. Da dies also bisher nicht 100% reproduzierbar ist, soweit irgendjemand Reproduktionsschritte anbieten konnte, wollte ich persönlich auch nicht in dieses Kaninchenloch gehen. (Mit anderen Worten, das Feedback von "Ich habe den Chrome-Debugger verwendet" ist keine Reihe von Reproduktionsschritten. Es ist nützlich, es zu wissen, aber es hilft niemandem bei der Untersuchung. Wir müssen wissen, was wir verfolgen und warum / welches Ergebnis ist erwartet.)

Wenn also Leute mit der aktuellen Codebasis die Leistung von Less verbessern wollen, braucht es wahrscheinlich mehrere Freiwillige und eine Person, um dieses Problem zu lösen.

Persönlich habe ich keinen großen Leistungsunterschied wie bei _speed_ gesehen, aber der Unterschied im Speicherverbrauch ist erstaunlich und scheint mit der Menge der Importe zu korrelieren, was meine kursorische Heap-Analyse ebenfalls mit dem Problem zu tun zu haben scheint.

Wenn das richtig ist, sollte ~Sie~ jedermann in der Lage sein, ein brauchbares Testprojekt zusammenzustellen, solange es aus vielen importierten Dateien besteht, von denen jede einige Regelsätze enthält, um auch den Unterschied zu sehen.

@rjgotten

Wenn das richtig ist, sollten Sie in der Lage sein, ein Testprojekt mit vielen importierten Dateien zusammenzustellen, von denen jede einige Regelsätze enthält, und auch den Unterschied sehen.

Das "Du" ist hier das Wichtigste. 😉

Das "Du" ist hier das Wichtigste. 😉

Unglückliche Wortwahl. Ich meine das im allgemeinen Sinne - dh "jeder".
Ich würde selbst weiter graben, aber ich habe derzeit schon zu viele Teller drehen.

@rjgotten Können Sie mir eine bessere Vorstellung davon geben, was "viele importierte Dateien" sein könnten? Würden 100 separate Dateien dies tun oder sprechen wir von 1000?

Und wie ist Ihnen das Problem zum ersten Mal aufgefallen? Ist ein Build aufgrund von Speicherverbrauch fehlgeschlagen oder haben Sie sich zufällig die Speichernutzung angesehen? Oder haben Sie bemerkt, dass Ihre Maschine langsamer wird?

Ich habe noch nicht versucht, dies zu replizieren, aber ich hoffe immer noch, zu erfahren, wonach ich genau suchen muss, damit ich nicht auf Vermutungen und Überprüfungen zurückgreifen muss.

100 oder so würden es tun. Das ist ungefähr die Größe des realen Projekts, bei dem mir das Problem aufgefallen ist.

Ich habe es zum ersten Mal bemerkt, als ein Build auf unserer Unternehmens-CI-Umgebung fehlgeschlagen ist. Wir führen diese in Docker-Containern mit konfigurierten Speicherbeschränkungen aus.

@rjgotten Haben wir das Speicherproblem bei 3.11.3 immer noch? Ich habe jegliches Caching (Referenzieren) des AST innerhalb von Importen in einer früheren Version entfernt. löst das das?

@matthew-dean Ja, das Problem ist am 3.11.3 noch vorhanden.

Ich werde versuchen, einen Proof of Concept zu erstellen, aber ich habe viel auf dem Teller. Ich habe das auf meine To-Do-Liste gesetzt, sobald ich etwas mehr Zeit habe.

@matthew-dean Ich möchte dies an einem relativ großen Projekt testen, das zuvor gescheitert ist. Muss ich etwas wissen? Soll ich diesen Zweig verwenden, https://github.com/less/less.js/tree/release_v3.12.0-RC1 ?

@nfq Sie können es versuchen, aber die vorherrschende Weisheit in diesem Thread besteht darin, die ES6-Konvertierung nicht zu sprengen, was dieser Zweig tut, und stattdessen mehr Informationen zu erhalten, um das Problem richtig zu diagnostizieren.

Übrigens habe ich versucht, das Objekt less während der Kompilierung zu untersuchen, um alle persistenten Objekte zu finden, und konnte keine finden. ️

Ich habe auch Leistungsprobleme. Für dieselbe Testsuite:

| Version | Zeit |
| -- | -- |
| v3.9.0 | ~1.6s |
| v3.10.0~v3.11.1 | ~3,6s |
| v3.11.2+ | ~12s |

Abgesehen von 3.9.0 → 3.10.0, die hier besprochen werden, scheint es bei v3.11.2 eine erhebliche Leistungseinbuße zu geben. Diese Änderung im Changelog scheint verdächtig zu sein:

3498 Baum-Caching im Import-Manager entfernen (#3498)

Gleiche für mich.

Timings für identische Builds (alle auf Knoten 10.19.0):

  • v3.9: 29,9 Sek.
  • v3.10: 76,0 Sek.
  • v3.12: 89,3 Sek.

@jrnail23

Haben Sie ein Repo, das diese Ergebnisse demonstrieren kann?

@matthew-dean Ich habe eine für https://github.com/less/less.js/issues/3434#issuecomment -672580467: https://github.com/ecomfe/dls-tooling/tree/master/packages/ less-plugin-dls (Es ist ein Monorepo, das ein Less-Plugin enthält.)

Tut mir leid, @matthew-dean, das tue ich nicht. Diese Ergebnisse stammen aus dem Produkt meines Arbeitgebers.

Diese Ergebnisse stammen aus dem Produkt meines Arbeitgebers.

Aus dem gleichen Grund kann ich auch keine Dateien bereitstellen. 😞

@rjgotten @jrnail23 @Justineo - Nur neugierig, haben Sie eine Reihe von Fällen, in denen der gleiche Import mehrmals in verschiedene Dateien importiert wird?

In meinem Fall haben wir ein Plugin, das eine @import Anweisung einfügt und eine Reihe benutzerdefinierter Funktionen bereitstellt. Die importierte Datei importiert andere Teile des Projekts, die schließlich 1000+ weniger Variablen erzeugen.

@matthew-dean, wir haben eine base.less Datei, die allgemeine Dinge importiert (zB Farbvariablen, Typografie usw.).
Ein kurzes Greifen unserer App zeigt, dass eine base.less Referenz (dh <strong i="8">@import</strong> (reference) "../../../less/base.less"; ) von 66 anderen komponenten-/funktionsspezifischen less Dateien importiert wird und einige dieser Dateien möglicherweise Importieren Sie auch andere komponenten-/funktionsspezifische weniger Dateien (die selbst auf base.less verweisen können).
Interessanterweise haben wir anscheinend noch eine weitere less Datei, die sich (wahrscheinlich versehentlich?) als Referenz importiert.

@rjgotten @jrnail23 @Justineo - Nur neugierig, haben Sie eine Reihe von Fällen, in denen der gleiche Import mehrmals in verschiedene Dateien importiert wird?

Für mich ist das ein 'Ja'. Das Projekt, bei dem ich zum ersten Mal Probleme hatte, ist eine skinfähige Lösung, die eine zentralisierte Variablendatei verwendet, die in allen anderen enthalten ist. Darüber hinaus verwenden wir ein komponentenbasiertes Design, bei dem wir über Mixin-Fabriken verfügen, die z. B. bestimmte Arten von Schaltflächen, Schriftsymbole usw. produzieren und Teile davon auch in mehrere Dateien importieren.

Grundsätzlich; jeder abhängige ist so eingerichtet, dass er seine Abhängigkeiten strikt importiert, und wir verlassen uns auf den Less-Compiler, um die Importe zu deduplizieren und in die richtige Reihenfolge zu bringen und die korrekte CSS-Ausgabe sicherzustellen.

@rjgotten

Ich habe es gepostet und gelöscht (weil ich dachte, ich hätte es herausgefunden, aber ich konnte es immer noch nicht reproduzieren), es gibt immer noch keine Schritte, um zu reproduzieren, was die Leute berichten, auch nicht über welchen Prozess.

Sogar so etwas Einfaches:

In 3.11 ist einer der aufgeführten Retainer für RuleSet der ImportManager.

Ich kann keine Beweise dafür finden, aber ich weiß auch nicht, wie Sie es feststellen konnten. Ich bin mit Chrome DevTools nicht vertraut genug, um zu wissen, wie man so etwas wie das, was von was beibehalten wird, bestimmen kann, und das ist ein vage genug Thema, bei dem Google mir nicht geholfen hat. Hängen die Leute zum Beispiel an den Node-Prozess an? Im Browser ausführen und Haltepunkte setzen? Was sind die Schritte?

Kurz gesagt, in dem Jahr, in dem diese Ausgabe veröffentlicht wurde, enthält keiner der Berichte Schritte zur Reproduktion. Ich bin sicher, all diese Anekdoten bedeuten ETWAS, aber wie hast DU festgestellt, was DU gefunden hast? Oder können Sie sich ein Setup vorstellen, das dies demonstriert? Ich würde gerne helfen, es herauszufinden, aber ich weiß nicht, wie ich es reproduzieren soll.

@Justineo Welche Schritte haben Sie in Ihrem

@Justineo Da Sie auf das Entfernen des Cache hingewiesen haben (was vielleicht eine schlechte Idee war), können Sie diesen Zweig testen und sehen, ob er Ihrer Build-Geschwindigkeit hilft? https://github.com/less/less.js/tree/cache-restored

Nur um ein paar Updates zu den heutigen Experimenten / Tests zu geben:

Grunts shell:test Mal

  • Weniger 3,9 -- 1,8 s
  • Weniger 3,12 (Babel-transpiliert auf ES5) – 9,2 s
  • Weniger 3,12 (Babel-transpiliert auf ES6) -- 3,1 s
  • Weniger 3.12 (TypeScript-transpiliert auf ES5) -- 3.2s

Ich denke also, kurz und lang ist, dass transpilierter Code immer langsamer ist, und wir waren naiv, anders zu denken. Ich bin etwas überrascht, da die Transpilation in der JavaScript-Welt mittlerweile so "Standard" ist. Gibt es noch andere Untersuchungen, die dies belegen?

@Justineo Welche Schritte haben Sie in Ihrem

npm run test ergibt die verstrichene Gesamtzeit. Und in anderen Projekten erleben wir OOM beim Wechsel auf 3.12.

Wenn wir uns TypeScript-generierten Code ansehen, erhalten wir etwa:

Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var node_1 = tslib_1.__importDefault(require("./node"));
var variable_1 = tslib_1.__importDefault(require("./variable"));
var property_1 = tslib_1.__importDefault(require("./property"));
var Quoted = /** <strong i="6">@class</strong> */ (function (_super) {
    tslib_1.__extends(Quoted, _super);
    function Quoted(str, content, escaped, index, currentFileInfo) {
        var _this = _super.call(this) || this;
        _this.escaped = (escaped == null) ? true : escaped;
        _this.value = content || '';
        _this.quote = str.charAt(0);
        _this._index = index;
        _this._fileInfo = currentFileInfo;
        _this.variableRegex = /@\{([\w-]+)\}/g;
        _this.propRegex = /\$\{([\w-]+)\}/g;
        _this.allowRoot = escaped;
        return _this;
    }

vs:

var Node = require('./node'),
    Variable = require('./variable'),
    Property = require('./property');

var Quoted = function (str, content, escaped, index, currentFileInfo) {
    this.escaped = (escaped == null) ? true : escaped;
    this.value = content || '';
    this.quote = str.charAt(0);
    this._index = index;
    this._fileInfo = currentFileInfo;
    this.variableRegex = /@\{([\w-]+)\}/g;
    this.propRegex = /\$\{([\w-]+)\}/g;
};

Ich vermute also, dass sich all diese zusätzlichen Funktionsdefinitionen und -aufrufe im Laufe der Zeit summieren? Es sei denn, dies ist ein Ablenkungsmanöver, aber ich weiß nicht, worauf ich das außer der Transpilation sonst noch zurückführen soll. Was ich nicht verstehe, ist, warum TS keinen Code erzeugen kann, der dem Original näher kommt.

AKTUALISIEREN:

Wenn ich versuche, die 3.9-Tests auf das Niveau von 3.12 zu bringen, dann erhalte ich im Wesentlichen 1.2s vs. 1.3s. Ich bin mir bei diesem Unterschied nicht mehr sicher, da sich die Tests geändert haben. Es müsste gegen genau die gleichen weniger Dateien ausgeführt werden.

@Justineo @rjgotten Ich habe ein paar TypeScript- Optimierungen vorgenommen, um vielleicht einen effizienteren Build zu erstellen. Möchten Sie diesen Zweig aufbauen und ausprobieren? https://github.com/less/less.js/tree/cache-restored

@matthew-dean 👍 Danke! Ich werde es heute später ausprobieren.

Ich habe den cache-restored Zweig getestet und er ist viel schneller als v3.11.2+, ungefähr mit der gleichen Geschwindigkeit wie v.3.1.0~3.11.1.

@Justineo

Ich habe den Cache-restore-Zweig getestet und er ist viel schneller als v3.11.2+, bei ungefähr der gleichen Geschwindigkeit wie v.3.1.0~3.11.1.

Nun, das ist vielversprechend. Lass uns Feedback von @rjgotten @jrnail23 und anderen in diesem Thread bekommen. Diese Cache-Entfernung erfolgte, nachdem dieser Thread gepostet wurde (3.11.2); Tatsächlich war dies ein Versuch, einen Teil des Speicher-Overheads zu entfernen, aber in Fällen, in denen Sie dieselbe Datei mehrmals importieren, hätte dies die Dinge definitiv verschlimmern können.

Kurz gesagt, ich bin mir des ursprünglichen Problems oder seiner Ursache immer noch nicht sicher (außer ETWAS, das bei der Codekonvertierung passiert ist), und ich würde gerne wissen, ob dieser Zweig noch diese Probleme hat, aber wie ich bereits erwähnt habe , es gibt keine klaren Repro-Schritte, daher bin ich mir nicht sicher.

@matthew-dean, ich habe ein bisschen Probleme beim Versuch, den cache-restored Zweig zu verwenden (ich bin mir nicht ganz klar, was getan werden muss, um ihn lokal zu verwenden, da npm link fehlschlägt mich).
Können Sie eine Canary/Pre-Release-Version veröffentlichen, die ich ausprobieren kann?

@jrnail23

Ich denke, das hat funktioniert. Versuchen Sie, Less zu entfernen und mit npm i [email protected]+84d40222 installieren

@matthew-dean, ich habe diese Version gerade ausprobiert und sie ist immer noch schlecht für mich.
Für neue Webpack-Builds (kein Caching) dauert es 62,4 Sekunden für v3.9, aber 121 Sekunden für v3.13.1.
Für zwischengespeicherte Builds dauert v3.9 30 Sekunden und v3.13.1 dauert 83-87 Sekunden.

@jrnail23 Können Sie versuchen, alle Knotenmodule zu entfernen und [email protected]+b2049010 installieren ?

Abzüglich 3,9 Benchmark:
Screen Shot 2020-12-05 at 2 36 09 PM

Abzüglich 4.0.1-alpha.0:
Screen Shot 2020-12-05 at 1 12 26 PM

Abzüglich 4.0.1-alpha.2:
Screen Shot 2020-12-05 at 2 35 20 PM

@Justineo @rjgotten Kannst du das auch versuchen?

@jrnail23 @Justineo @rjgotten

Beachten Sie, dass dies ein 4.0-Build ist, sodass Sie möglicherweise auf Fehler stoßen, wenn Ihr Code diese grundlegenden Änderungen enthält:

  • Klammern sind für Mixin-Aufrufe erforderlich (zB .mixin; ist nicht erlaubt)
  • Der standardmäßige mathematische Modus von Less ist jetzt parens-division, also müssen Schrägstriche (als Mathematik gedacht) in Klammern stehen

Obwohl ich jetzt viel optimistischer bin, dass ich das Problem basierend auf den neuesten Benchmarks behoben habe, muss ich noch herausfinden, warum dieses Problem aufgetreten ist. Wenn die Leistung für alle anderen hält, kann ich einen Überblick darüber geben, wie ich das Problem schließlich eingegrenzt habe und was ich gefunden habe. Mit anderen Worten, ich glaube, ich habe herausgefunden, _wo_ das Problem ist/war, aber nicht unbedingt warum.

Das Ergebnis der gleichen Testsuite wie https://github.com/less/less.js/issues/3434#issuecomment -672580467:

| Version | Zeit |
| -- | -- |
| v3.9.0 | ~1.6s |
| v3.10.0~v3.11.1 | ~3,6s |
| v3.11.2+ | ~12s |
| 4.0.1-alpha.2+b2049010 | ~1.6s |

Ich kann bestätigen, dass sich das Leistungsniveau für meine spezifische Testsuite bis auf v3.9.0 verbessert hat. Sehr geschätzt Matt! Ich bin mir zwar nicht sicher, ob es im Mathe-Modus eine Pause gibt. Dies zu ändern kann dazu führen, dass viele unserer Anwendungen kaputt gehen, so dass wir möglicherweise bei v3.9.0 hängen bleiben, selbst wenn das Leistungsproblem behoben ist.

@Justineo

Ich bin mir zwar nicht sicher, ob es im Mathe-Modus eine Pause gibt.

Sie können explizit im math=always Modus kompilieren, um das vorherige mathematische Verhalten zu erhalten. Es ist nur eine andere Standardeinstellung.

Aufschlüsselung des Problems

TL;DR - Vorsicht vor dem Klassenmuster

Das Problem lag in der Transpilation von Klassen sowohl in Babel als auch in TypeScript. (Mit anderen Worten, beide hatten die gleichen Leistungsprobleme mit dem transpilierten Code, wobei Babel etwas schlechter war.) Jetzt, vor Jahren, als das Klassenmuster eingeführt wurde, wurde mir gesagt – und bis zu diesem Problem glaubte ich – dass Klasse Vererbung in JavaScript ist syntaktischer Zucker für funktionale Vererbung.

Kurz gesagt, ist es nicht. _(Edit: naja.... es ist und es ist nicht. Es hängt davon ab, was Sie mit "Vererbung" meinen und wie Sie es definiert haben, wie Sie gleich sehen werden.... dh es gibt mehrere Muster zu Erstellen Sie "Vererbung" in der Prototypkette in JavaScript, und Klassen stellen nur ein Muster dar, aber dieses Muster unterscheidet sich etwas von allen anderen, daher benötigen TS / Babel Hilfscode, um dieses Muster mit speziellen Funktionen "nachzuahmen".)_

Weniger Code sah so aus:

var Node = function() {
  this.foo = 'bar';
}

var Inherited = function() {
  this.value = 1;
}
Inherited.prototype = new Node();

var myNode = new Inherited();

Angenommen, Sie wollten dies mit "modernem" JS neu schreiben. Tatsächlich können Sie diesen Prozess automatisieren, was ich getan habe, aber so oder so hätte ich es genauso geschrieben, nämlich:

class Node {
  constructor() {
    this.foo = 'bar';
  }
}
class Inherited extends Node {
  constructor() {
    super();
    this.value = 1;
  }
}
var myNode = new Inherited();

Das gleiche, oder? Nicht wirklich. Der erste erzeugt ein Objekt mit einer Eigenschaft von { value: 1 } und in seiner Prototypkette hat es ein Objekt von { foo: 'bar' } .

Die zweite Methode erzeugt ein Objekt mit einer Struktur wie { value: 1, foo: 'bar' } , da sie den Konstruktor sowohl für Inherited als auch für Node { value: 1, foo: 'bar' } .

Für den _user_ ist dies nun wirklich egal, da Sie in jedem Fall von myNode aus value und foo zugreifen können. _Funktionell_ scheinen sie sich gleich zu verhalten.

Hier gebe ich reine Spekulation ein

Soweit ich mich in Artikeln über JIT-Engines wie V8 erinnere, sind Objektstrukturen tatsächlich sehr wichtig. Wenn ich eine Reihe von Strukturen wie { value: 1 } , { value: 2 } , { value: 3 } , { value: 4 } erstelle, erstellt V8 eine interne statische Darstellung dieser Struktur. Sie speichern die Struktur + Daten im Wesentlichen einmal und dann die Daten noch dreimal.

ABER wenn ich jedes Mal andere Eigenschaften hinzufüge, wie: { a: 'a', value: 1 } , { b: 'b', value: 2 } , { c: 'c', value: 3 } , { d: 'd', value: 4 } , dann sind das 4 verschiedene Strukturen mit 4 Datensätzen , auch wenn sie aus demselben Satz von Originalklassen erstellt wurden. Jede Mutation eines JS-Objekts deoptimiert die Datensuche, und ein Klassenmuster, das in Funktionen umgesetzt wird, verursacht (vielleicht) eindeutigere Mutationen. (Ich habe ehrlich gesagt keine Ahnung, ob dies für die native Klassenunterstützung in Browsern gilt.)

AFAIK, es stimmt auch, dass die Suche nach einzelnen Eigenschaften umso länger dauert, je mehr Eigenschaften Sie für ein Objekt haben.

Auch für Endbenutzer ist dies selten von Bedeutung, da JS-Engines so schnell sind. Buuuuut sagen Sie, Sie pflegen eine Engine, die Eigenschaften / Methoden für viele Objekte so schnell wie möglich erstellt und nachschlägt. (Ding ding ding.) Plötzlich summieren sich diese kleinen Unterschiede zwischen der Art und Weise, wie TypeScript / Babel Objekte "erweitert", und der nativen funktionalen prototypischen Vererbung sehr schnell.

Ich habe eine einfache Implementierung eines Node und einer Vererbungsfunktion geschrieben, wobei ich die alte Less-Syntax und das mit TS transpilierte Klassenmuster verwendet habe. Von Anfang an verbraucht der geerbte Knoten 25 % mehr Speicher/Ressourcen, und das, BEVOR Instanzen des geerbten Knotens erstellt wurden.

Betrachten Sie nun, dass einige Knoten von anderen Knoten erben. Das heißt, die In-Memory-Darstellung der Klassen beginnt sich zu vervielfachen, ebenso wie ihre geerbten Instanzen.

Auch das ist Spekulation

Ich muss betonen, dass all dies mit Vorsicht zu genießen ist, denn ich habe noch nie gehört, dass eine Umstellung auf den Unterricht so katastrophal für die Leistung ist. Was meiner Meinung nach passiert, ist, dass Less eine spezielle Kombination von Objekt-/Instanz-Lookups verwendet, die das JIT ernsthaft deoptimiert. _(Wenn ein JavaScript-Engine-Experte weiß, warum transpilierte Klassen in diesem Fall so viel schlechter abschneiden als native JS-Vererbungsmethoden, würde ich es gerne wissen.)_ Ich habe versucht, ein Leistungsmaß zum Erstellen von Tausenden von geerbten Objekten mit beiden Methoden zu erstellen, und Ich konnte nie einen konstanten Unterschied in der Leistung feststellen.

Bevor Sie also mit "Klassen in JavaScript sind schlecht" weggehen, könnte es ein anderes wirklich unglückliches Muster in der Less-Codebasis sein, gepaart mit dem Unterschied zwischen transpilierten Klassen und nativem JS, die diesen Leistungsabfall verursacht haben.

Wie ich es endlich herausgefunden habe

Ehrlich gesagt habe ich das Klassenmuster nie vermutet. Ich wusste, dass der ursprüngliche ES5-Code schneller lief als der Reverse-Babelified-Code, aber ich vermutete etwas in Bezug auf Pfeilfunktionen oder verbreitete Syntax irgendwo. Ich hatte immer noch den aktuellen ES5-Zweig, also beschloss ich eines Tages, lebab erneut auszuführen und nur diese Transformationen zu verwenden: let,class,commonjs,template . Da stellte ich fest, dass es wieder Performance-Probleme hatte. Ich wusste, dass es sich nicht um String-Templating oder Let-to-Var handelte; Ich dachte, dass die Requires-to-Imports vielleicht etwas bewirken, also habe ich eine Weile damit gespielt. Das hat die Klassen verlassen. Also habe ich aus einer Ahnung heraus alle erweiterten Klassen wieder auf funktionale Vererbung umgeschrieben. Bam, die Leistung war wieder da.

Eine warnende Geschichte

So! Lektion gelernt. Wenn Ihr Projekt auf altem ES5-Code basiert und Sie sich nach dieser "modernen" Babel- oder TypeScripted-Güte sehnen, denken Sie daran, dass Sie, was immer Sie transpilieren, nicht geschrieben haben.

Ich war immer noch in der Lage, Klassen in etwas "klassenähnlicheres" umzuschreiben, mit einem etwas besser wartbaren Muster , aber mehr oder weniger das ursprüngliche funktionale Vererbungsmuster von Less-Knoten

Sie können explizit im math=always-Modus kompilieren, um das vorherige mathematische Verhalten zu erhalten. Es ist nur eine andere Standardeinstellung.

Dies ist mir bewusst. Wir haben viele Less-Codebasen in vielen verschiedenen Teams, sodass Break-Changes selbst in den Standardkompilierungsoptionen die Kommunikationskosten erhöhen würden. Ich bin mir nicht sicher, ob die Vorteile den Bruch wert sind.

Vielen Dank für die ausführliche Aufschlüsselung!

Ich habe die Verwendung von Object.assign in der kompilierten Ausgabe gesehen, was bedeutet, dass es nur in Browsern funktioniert, die die native ES-Syntax class sei denn, jetzt sind Polyfills erforderlich. Können wir also einfach die native Syntax verwenden, ohne auf ES5 zu transpilieren, wenn wir beabsichtigen, die Unterstützung für ältere Umgebungen (zB IE11, Node 4, ...) einzustellen?

Gleichzeitig denke ich, dass es besser ist, wenn wir den Fix für Leistungseinbußen und die Breaking Changes trennen können, das heißt, den Performance-Fix in v3 zu landen und die Breaking-Changes nur in v4 aufzunehmen.

@matthew-dean
Die Tatsache, dass ES-Klassen der Schuldige sind, ist wahnsinnig beängstigend.
Danke für die ausführliche Aufschlüsselung.

Geht zu zeigen: _Komposition über Vererbung_ 😛

Obwohl FYI; Wenn Sie eine sauberere protypische Vererbungskette wünschen, sollten Sie es wirklich etwas anders machen als in Ihrem Beispiel.
Wenn Sie Object.create wie folgt verwenden:

var Node = function() {
  this.foo = 'bar';
}
Node.prototype = Object.create();
Node.prototype.constructor = Node;

var Inherited = function() {
  Node.prototype.constructor.call( this );
  this.value = 1;
}
Inherited.prototype = Object.create( Node.prototype );
Inherited.prototype.constructor = Inherited;

var myNode = new Inherited();

dann glätten Sie die Eigenschaften auf die Instanzen selbst, die dann dieselbe Form haben; die Prototypen haben eine gemeinsame Form; _und_ Sie vermeiden es, die Prototypketten für jeden Eigenschaftszugriff hochzukriechen. 😉

@Justineo

Ich habe die Verwendung von Object.assign in der kompilierten Ausgabe gesehen, was bedeutet, dass es nur in Browsern funktioniert, die die native ES-Klassensyntax unterstützen, es sei denn, Polyfills sind jetzt erforderlich. Können wir also einfach die native Syntax verwenden, ohne auf ES5 zu transpilieren, wenn wir beabsichtigen, die Unterstützung für ältere Umgebungen (zB IE11, Node 4, ...) einzustellen?

Ich denke nicht, dass das ganz richtig ist, dh Object.assign landete kurz vor der Klassenimplementierung, aber Ihr Punkt ist verstanden. Ich hatte nur gehofft, [Something].prototype.property immer wieder zu schreiben :/

Technisch ist immer noch alles transpiliert, also keine Ahnung. Das ursprüngliche Ziel war eine besser wartbare / lesbare Codebasis. Wenn Sie in einer Umgebung ein Polyfill Object.assign benötigen, ist es so. Es wäre eine Version von etwas, das Less nicht unterstützt.

Gleichzeitig denke ich, dass es besser ist, wenn wir den Fix für Leistungseinbußen und die Breaking Changes trennen können, das heißt, den Performance-Fix in v3 zu landen und die Breaking-Changes nur in v4 aufzunehmen.

Ich habe darüber nachgedacht, und ich denke, das ist auch ein berechtigter Punkt. Ich versuche nur, dass mein Kopf nicht explodiert, indem ich 3 Hauptversionen von Less baue / pflege.

@rjgotten AFAIK das ist, was ein Klassenmuster tun soll, genau so, wie Sie es definiert haben. Es sei denn, ich sehe keinen entscheidenden Unterschied. Also 🤷‍♂️. Ich werde nicht versuchen, das Vererbungsmuster des Knotens von Less erneut zu ändern, wenn es gut funktioniert (außer ich kann diesen Object.assign Aufruf entfernen , wie

@Justineo @rjgotten Kannst du das versuchen: [email protected]+b1390a54

Habe es gerade probiert:

| Version | Zeit |
| -- | -- |
| v3.9.0 | ~1.6s |
| v3.10.0~v3.11.1 | ~3,6s |
| v3.11.2+ | ~12s |
| 4.0.1-alpha.2+b2049010 | ~1.6s |
| 3.13.0-alpha.10+b1390a54 | ~4,7s |

Ps. Getestet mit Node.js v12.13.1.

Ich bin was.

Hatte nicht die Zeit, separate Benchmarks einzurichten.
Aber aus Sicht des Integrationstests sind hier einige Zahlen aus der Praxis: die kumulativen Ergebnisse eines Webpack-Projekts in Produktionsqualität, das Less verwendet.

Version | Zeit | Spitzenspeicher
:------------|--------:|------------:
3,9 | 35376ms | 950 MB
3.11.3 | 37878ms | 920 MB
3.13.0-alpha.10+b1390a54 | 34801ms | 740 MB
3.13.1-alpha.1+84d40222 | 37367ms | 990 MB
4.0.1-alpha.2+b2049010 | 35857ms | 770 MB

Für mich liefert die 3.13.0 die _besten_ Ergebnisse...

3.11.3 scheint auch nicht die außer Kontrolle geratene Speichernutzung zu haben, die ich zuvor mit der Version 3.11.1 gesehen habe.
Aber die Betaversionen 4.0.1 und 3.13.0 sind noch besser.

Die 3.13.1, die den Cache wiederhergestellt hat, hilft nicht dabei, meine Compile-Zeiten in der realen Welt zu verbessern und bläst nur den Speicherverbrauch auf.

@rjgotten Ja, ich denke, das Problem ist, dass die Leute in diesem Thread verschiedene Dinge messen und jeder bisher im Wesentlichen private Daten hat, die nicht repliziert werden können (ohne sich an Less-Benchmarking zu unterwerfen oder das in eine PR zu übersetzen). Less hat einen Benchmark-Test, den ich gegen verschiedene Klone des Repos verwenden könnte, um für mich Unterschiede in der Parse- / Evaluierungszeit zu überprüfen, aber wo Caching (derzeit) nicht gilt.

Hier ist ein veröffentlichter Build mit den Vererbungsänderungen im Baum und mit wiederhergestelltem Parse-Baum-Cache: [email protected]+e8d05c61

Testfall

https://github.com/ecomfe/dls-tooling/tree/master/packages/less-plugin-dls

Ergebnisse

| Version | Zeit |
| -- | -- |
| v3.9.0 | ~1.6s |
| v3.10.0~v3.11.1 | ~3,6s |
| v3.11.2+ | ~12s |
| 4.0.1-alpha.2| ~1.6s |
| 3.13.0-alpha.10| ~4,7s |
| 3.13.0-alpha.12 | ~1.6s |

Node.js-Version

v12.13.1


Für mich scheint diese Version einwandfrei zu funktionieren. Ich werde meine Kollegen bitten, es auszuprobieren und zu überprüfen.

Funktioniert alpha.10 mir etwas schlechter als das

Version | Zeit | Spitzenspeicher
:------------|--------:|------------:
3,9 | 35376ms | 950 MB
3.11.3 | 37878ms | 920 MB
3.13.0-alpha.10+b1390a54 | 34801ms | 740 MB
3.13.0-alpha.12+e8d05c61 | 36263ms | 760 MB
3.13.1-alpha.1+84d40222 | 37367ms | 990 MB
4.0.1-alpha.2+b2049010 | 35857ms | 770 MB

@matthew-dean, es sieht so aus, als ob mein Code noch nicht mit den 4.0.1-alpha.2+b2049010 Änderungen kompatibel ist. Ich werde sehen, ob ich meine Probleme lösen kann und versuche es.

@rjgotten Ja, der Unterschied scheint für Ihren Testfall gering zu sein.

Ich denke, das Ergebnis davon ist, dass ich sowohl eine 3.x- als auch eine 4.0-Version vorbereiten könnte. Ich habe es nicht gejuckt, 4.0 mit diesem ungelösten Problem voranzutreiben. Zum Glück sieht es so aus.

Der andere Punkt, den ich tun werde, ist, ein Problem für jeden zu öffnen, das darin besteht, eine CI-Pipeline einzufügen, die weniger fehlschlägt, wenn sie unter einen bestimmten Benchmark-Schwellenwert fällt.

@jrnail23 Es wäre großartig, wenn Sie die [email protected]+e8d05c61 versuchen?

@matthew-dean, ich bekomme folgendes für meinen Build:

  • v3.9: 98 Sekunden
  • v3.10.3: 161 Sekunden
  • v3.13.0-alpha.12: 93-96 Sekunden

Es sieht also so aus, als wären Sie wieder da, wo Sie sein möchten! Gute Arbeit!

Gute Arbeit!

Ja, ich werde Zweiter; Dritter; und viertens das.
Dies war eine üble, üble Leistungsregression, die wirklich viel Mühe kostete, um sie zu beseitigen.

Job _sehr gut_ gemacht.

Okay-Team! Ich werde den 3.x-Build veröffentlichen und irgendwann später, vielleicht nächste Woche, 4.0 veröffentlichen. Beide sollten jetzt die Performance-Fixes haben. Danke an alle, die beim Debuggen geholfen haben!

Übrigens bin ich gerade dabei, die Less.js-Codebasis in TypeScript umzuwandeln, und plane, die Gelegenheit zu nutzen, um Leistungsoptimierung / Refactoring durchzuführen. Ich bin offen für Hilfe, wenn jemand Interesse hat! https://github.com/matthew-dean/less.js/compare/master...matthew-dean :weiter

Gibt es etwas Bestimmtes, wo Sie ein paar zusätzliche Augen bevorzugen würden? Die PR ist sehr groß, daher weiß ich nicht wirklich wo ich anfangen soll

@kevinramharak Das ist eine

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen