Material-ui: Können die Eingaben vereinfacht werden, um die Leistung zu verbessern?

Erstellt am 7. Jan. 2020  ·  70Kommentare  ·  Quelle: mui-org/material-ui

Wie von @eps1lon in #

Es gibt immer eine Spannung zwischen den genauesten Typen (die die besten Fehler und Editorvervollständigungen liefern) und der schnellen Typüberprüfung (das andere Ende des Spektrums ist any ).
Probleme wie https://github.com/microsoft/TypeScript/issues/34801 deuten darauf hin, dass Material-UI von einer Lockerung der Genauigkeit profitieren könnte, um etwas Leistung zurückzugewinnen.

Von den Repros, die ich bisher untersucht habe, scheint ein Großteil der Langsamkeit von der großen Anzahl von CSS-Eigenschaftsnamen zu kommen (siehe https://github.com/mui-org/material-ui/blob/master/packages/ material-ui-styles/src/withStyles/withStyles.d.ts). Da ich selbst kein aktiver CSS-Benutzer bin, habe ich einige naive Fragen:

1) Gehe ich richtig mit der Annahme, dass es unglaublich wertvoll ist, einen Namen und einen Typ für jede bekannte CSS-Eigenschaft zu haben, und wir nicht darauf verzichten könnten?
2) Der Typ CSSProperties scheint zu existieren, um "Pseudo-Selektoren und Medienabfragen" zu unterstützen, die - nach meiner begrenzten Lektüre - als Beutel mit zusätzlichen CSS-Eigenschaften bezeichnet werden.
a) Sind diese Taschen selbst rekursiv oder gibt es nur eine einzige zusätzliche Schicht? Das heißt, gehen Sie von width zu foo.width oder zu foo.bar.width usw.? Wenn es nur ein Level ist, verkürzt die Vereinfachung der Typen meinen lokalen Repro von 4,6 Sekunden auf 3,6 Sekunden (dh großer Gewinn).
b) Ich habe selbst mit den Typen herumgespielt und mir nichts Besseres einfallen lassen als BaseCSSProperties[keyof BaseCSSProperties] , aber - wie Sie wahrscheinlich wissen - ist das kein sehr nützlicher Typ. Es besagt im Grunde, dass jede CSS-Eigenschaft den Typ einer beliebigen (anderen) CSS-Eigenschaft haben kann - das ist nur geringfügig besser als any .
3) In StyleRules , wenn keine Eigenschaften vorhanden sind, erhalten Sie entweder CSSProperties oder () => CSSProperties (die ich schlampig "thunked CSSProperties" nenne), was Sinn macht - die CSSProperties könnte faul sein. Wenn es Eigenschaften gibt, erhalten Sie entweder CreateCSSProperties<Props> , was sinnvoll ist - die Props könnten erforderlich sein, um die CSSProperties zu berechnen - oder (props: Props) => CreateCSSProperties<Props> , was ich getan habe Ich verstehe nicht, weil es effektiv doppelt faul ist - Sie müssen die Props einmal eingeben, um die CreateCSSProperties und dann noch einmal, um einzelne Eigenschaften zu erhalten. Warum ist es "doppelt gedacht"?

Unabhängig davon vermute ich, muss aber noch beweisen, dass IsEmptyInterface für den Nutzen, den es bietet, zu teuer ist. Es ist jedoch gut möglich, dass ich die Vorteile nicht vollständig verstehe, daher wäre es hilfreich, mehr zu erfahren.

Können wir zusammenarbeiten, um die richtige Balance zwischen Genauigkeit und Perfektion zu finden? (Anmerkung: "Machen Sie den Compiler einfach schneller" ist offensichtlich eine praktikable Strategie, aber ich möchte die Eingaben an einen guten Ort bringen, bevor wir sie optimieren.) Danke!

performance typescript

Hilfreichster Kommentar

Ich habe heute angefangen, Material UI ( 4.9.4 ) zu meinem Projekt hinzuzufügen, und die Verlangsamung ist wirklich so bedeutend, dass ich sie nicht einmal in meinem Projekt verwenden kann. Soeben wurde eine einfache <Slider/> Komponente hinzugefügt, die mit withStyles() angepasst wurde.

Wir sprechen davon, von sofortigem TypeScript-Feedback in meiner IDE zu manchmal 5-10 Sekunden überzugehen (für Teile meines Codes, die jetzt nicht einmal mit der Material UI interagieren - es ist nur eine vollständige TypeScript-Verlangsamung in der Datei, die verwendet wird die Komponente). Irgendetwas muss mit diesen Typen (oder ja, übermäßig komplex) nicht stimmen , es scheint, als ob

Ich versuche, einen Weg zu finden, dass ich zumindest alle TypeScript-Sachen für @material-ui vorerst ausschließen kann (im Wesentlichen das gesamte Modul zu any ) - aber TypeScript scheint das nicht einfach genug zu machen.

Alle 70 Kommentare

Ich bin mit Material-UI-Typen nicht vertraut, aber versuche, diese Fragen zu beantworten.

  1. Ja, die vollständige Unterstützung aller CSS-Eigenschaften, die in den aktuellen Webstandards deklariert sind, ist nützlich.
  2. a) In unserem Fall verwenden wir nie eine Tiefe von mehr als 2, aber Fälle wie dieser sind durchaus möglich
    ```Typoskript
    const Styles = (Thema: Theme) =>
    createStyles({
    irgendwas: {
    '&:Hover-Taste': {
    Sichtbarkeit: 'sichtbar',-
    Deckkraft: 1,
                ':after': {
                    content: 'x',

                    [theme.breakpoints.up('lg')]: {
                        content: 'close',
                    },
                }
            },
        }
    });
```
b) I do not understand why `BaseCSSProperties[keyof BaseCSSProperties]` is needed there

  1. Ich denke, (props: Props) => CreateCSSProperties<Props> wird nicht benötigt, wir haben diesen Typ in unserer Version der Material-UI-Typen ausgeschlossen und es ist nichts Schlimmes passiert.

Es könnte sich lohnen, sich die Implementierung von Typen in Version 3.9.3 anzusehen, da in dieser Version die Typprüfung schnell genug war und die Eingabe gut war.

Zuerst möchte ich mich bei Ihnen bedanken, dass Sie sich gemeldet haben und sich das angeschaut haben. Es ist unglaublich hilfreich, jemanden zu haben, der überprüft, welche Teile der Typen langsam sind oder nicht.

  1. Liege ich richtig in der Annahme, dass es unglaublich wertvoll ist, einen Namen und einen Typ für jede bekannte CSS-Eigenschaft zu haben, und wir nicht darauf verzichten könnten?

Es ist unmöglich, hier unvoreingenommen zu sein. Ich glaube nicht, dass wir es aufgeben können, wenn wir uns das breitere Ökosystem ansehen. Chrome-Devtools haben diese Funktion, reagieren selbst, tippt die style Requisite mit CSSProperties usw. Ich kann nicht sehen, wie ich von der IDE zum Browser wechsle und prüfe, ob es Textdekoration oder Schriftdekoration war oder Text-Transformation.

  1. […]
    Sind diese Taschen selbst rekursiv oder gibt es nur eine einzige zusätzliche Schicht?

Ich müsste die von uns verwendete CSS-in-JS-Lösung überprüfen. Technisch gesehen können Medienabfragen in CSS rekursiv sein. Ich wäre bereit, diese Rekursivität zu reduzieren und zu sehen, ob wir Berichte erhalten. Technisch verschachtelte Medienabfragen können mit dem Operator and abgeflacht werden. Wir sollten es jedoch auf zwei Ebenen beschränken: Eine für Medienabfragen und eine für Pseudo-Selektoren. Dies sollte noch IMO typgeprüft werden:

const styles = {
  root: {
    '<strong i="18">@media</strong> (max-width: 12cm)': {
      ':hover': {}
    }    
  }
}

Ist das etwas, was Sie selbst beim Schreiben von @oliviertassinari sehen?

  1. […]
    CSSProperties - oder (props: Props) => CreateCSSProperties, was ich nicht verstanden habe, weil es effektiv doppelt faul ist - Sie müssen die Props einmal übergeben, um die CreateCSSProperties zu erhalten und dann erneut, um einzelne Eigenschaften zu erhalten. Warum ist es "doppelt gedacht"?

Wenn das Argument selbst kein Eigenschaftenbeutel, sondern eine Funktion ist, erfordert es ein Thema. Die Stile können von zwei verschiedenen Arten von Eigenschaftenbeuteln abhängen: Das Thema (verfügbar über die Kontext-API von React) oder die Requisiten (direkt an die Komponente übergeben):

makeStyles({ root: { color: 'blue' }}); // A
makeStyles(theme => ({ root: { color: theme.color } })); // B
makeStyles({ root: props => ({ color: props.color})}); // C
makeStyles({ root: { color: props => props.color } }); // D: same as C, only exists for dev ergonomics
makeStyles(theme => ({ root: props => ({ color: props.color || theme.color }) })); // E: what you called "double-lazy"

Es geht weniger um faule Evaluation, um die Leistung zu verbessern, sondern darum, darauf warten zu müssen, dass Kontext und Requisiten verfügbar sind.

Unabhängig davon vermute ich, muss aber noch zeigen, dass IsEmptyInterface für den von ihm gebotenen Nutzen zu teuer ist. Es ist jedoch gut möglich, dass ich die Vorteile nicht vollständig verstehe, daher wäre es hilfreich, mehr zu erfahren.

Es gibt einen Fall, in dem dies verwendet wird:

Erwägen

const useStaticStyles = makeStyles({ root: { color: 'blue' } });
const useDynamicStyles= makeStyles({ root: { color: props =>  props.color } })
function Component() {
  const staticClasses = useStaticStyles(); // No error
  const throwingClasses = useDynamicStyles(); // $ExpectError
  const dynamicClasses = useDynamicStyles({ color: 'blue' });
}

Um die Aufrufsignatur der von makeStyles Funktion useSomeStyles ). Wir müssen überprüfen, welche Art von Tasche an makeStyles . Wir haben bereits einen Helfer, um die Arten von Requisiten abzuleiten, die in der Stiltasche verwendet werden . Wenn der Stilbeutel statisch ist, dh TS leitet den Typ {} . Dann überprüfen wir den abgeleiteten Typ der Props mit IsEmptyInterface und verwenden für einen Zweig eine Rufsignatur mit 0 Parametern und für den anderen Zweig verwenden wir eine Rufsignatur mit 1 Parameter, die gleich dem abgeleiteten Requisitentyp ist ( siehe StylesRequireProps und StylesHook .

Kurz gesagt: Wir vermeiden es, useStaticStyles({}) oder useStaticStyles(null as any) schreiben zu müssen. Es wurde in https://github.com/mui-org/material-ui/pull/14019 eingeführt, um . Ich denke, wir können die Rufsignatur kurzschließen. Vielleicht die Anrufsignatur überladen, anstatt bedingte Typen zu verwenden?

Das Problem mit dieser "Funktion" besteht darin, dass fortgeschrittene Benutzer kein Problem damit haben, null as any wenn sie verstehen, warum. Vielleicht ist sogar das Übergeben eines leeren Objekts in Ordnung, obwohl es nicht benötigt wird. Es ist jedoch sehr verwirrend/frustrierend, wenn es nicht an Material-UI oder TypeScript gewöhnt ist. Zumal das meiste Styling ohnehin nicht auf Requisiten basiert.

Es scheint, als ob der Typprüfer die meiste Zeit mit der Stylinglösung beschäftigt ist? Ich hätte erwartet, dass die Rufsignatur für unsere Komponenten, dh welche Requisiten möglich sind, die meiste Zeit in Anspruch nimmt.

Ich kann mehr Repositorys crawlen, um speziell die Verwendung von withStyles oder makeStyles . Bisher habe ich mich nur mit der Verwendung von Requisiten befasst.

Ist das etwas, was Sie selbst beim Schreiben von @oliviertassinari sehen?

@eps1lon Wir haben einige Vorkommen dieser Verschachtelung in der Codebasis (zB mit <strong i="8">@media</strong> (hover: none) ). Aber es ist nicht sehr häufig für die Kernkomponenten. Ich stelle mir vor, es ist das gleiche Userland. Es könnte definitiv ein Teil des Kompromisses sein.

@beholderrk

  1. Das habe ich mir gedacht, aber ich dachte, ich könnte genauso gut fragen.
  2. a) Tiefe zwei sollte ausdrückbar sein - es wird nur ein bisschen mehr Duplizierung geben als Tiefe eins.
    b) Ich habe eine ganze Weile gebraucht, um mich zurechtzufinden, und ich wünschte, ich könnte es persönlich statt in Textform erklären. Grundsätzlich besagt die Indexsignatur, dass alle Eigenschaften den gleichen Typ haben. Das kann nur funktionieren, wenn es einen Typ angibt, der für alle funktioniert. Eine Möglichkeit, dies zu tun, besteht darin, die Vereinigung aller Eigenschaftstypen zu konstruieren, BaseCSSProperties[keyof BaseCSSProperties] - dann hat jede Eigenschaft einen kompatiblen Typ. Angenommen, die einzigen Eigenschaften, die Sie in CSS haben könnten, wären name: string und width: number . Eine Möglichkeit, eine Indexsignatur anzugeben, die mit beiden Eigenschaften funktioniert, besteht darin, dass jede Eigenschaft ein string | number . Es ist nicht so toll - name wird nie ein number und width wird nie ein string - aber es funktioniert. Das eigentliche Problem ist, dass das, was Sie wollen, nicht wirklich ausgedrückt werden kann (zumindest, soweit wir das feststellen konnten - es könnte einen "cleveren" Hack geben, der dies tut). Sie möchten eigentlich sagen, dass Ihr Typ name: string , width: number oder x: CSSProperties , wobei x alles andere als name oder width - es fehlt das "alles außer". Ich hoffe, das ist etwas klarer.
  3. Es hörte sich so an, als hätte @eps1lon etwas dazu zu sagen, aber ich analysiere immer noch seine Antwort.

Eine bekanntermaßen gute Baseline wäre sehr hilfreich. Hast du zufällig einen Link?
Edit: habs gefunden.

@eps1lon Freue mich , Teil des Gesprächs zu sein. Schnelle, korrekte Typen sind für alle gut. 😄

  1. Kein Argument hier - ich dachte nur, ich würde früher fragen, weil es das ganze Gespräch kurzgeschlossen hätte.
  2. Zwei Schichten scheinen machbar (mit der bemerkenswerten Einschränkung, dass die Typen immer noch weitgehend nutzlos sind). Ich schau mal, ob ich etwas entwerfen kann.
  3. Aufgrund meines Mangels an Kontext war es nicht klar, dass Themen und Requisiten unterschiedlich waren. Wenn ja, dann macht die Struktur Sinn. Danke fürs klarstellen.

In Bezug auf isEmptyInterface könnten Sie den Eigenschaftenparameter einfach auf (zB) useStaticStyles optional machen? Es wäre weniger korrekt in dem Sinne, dass Anrufer sie weglassen könnten, wenn sie erwartet werden, aber es wäre viel billiger, die Eingabe zu überprüfen. Wie gesagt, ich habe keine Zahlen oder ähnliches für dich - es sind nur Spekulationen meinerseits.

Was denkst du zu 2(b)? Es scheint, als ob dieser Typ nicht viel Wert liefert, da er im Grunde sagt, dass jeder Eigenschaftsname akzeptiert wird und der Rückgabetyp eines von vielen Dingen sein kann.

Was isEmptyInterface betrifft, könnten Sie den Eigenschaftenparameter einfach auf (zB) useStaticStyles optional machen?

Ich würde gerne zuerst mit dem Überladen der Anrufsignatur experimentieren und sehen, ob dies Auswirkungen hat. Dann versuchen wir, es weniger laut zu machen, indem wir es immer optional machen. Es scheint sicherer als üblich zu sein, es weniger solide zu machen, da es in fast allen Anwendungsfällen nur einmal aufgerufen wird, sodass Sie den Fehler wahrscheinlich nur einmal machen und er ziemlich schnell auftaucht. Es wird jedoch schwierig, es zu verkaufen, wenn es uns nicht viel Leistung bringt. Ich werde das für das ursprüngliche Problem erstellte Repository verwenden (https://github.com/microsoft/TypeScript/issues/34801#issue-514055289).

Was denkst du zu 2(b)? Es scheint, als ob dieser Typ nicht viel Wert liefert, da er im Grunde sagt, dass jeder Eigenschaftsname akzeptiert wird und der Rückgabetyp eines von vielen Dingen sein kann.

Habe das aus Versehen übersprungen. Ich werde es mir nach dem IsEmptyInterface-Experiment ansehen.

@eps1lon Stimme voll und ganz zu - behalte isEmptyInterface wenn das Eliminieren kein wesentlicher Perf-Gewinn ist.

Mit #19320 haben wir einige komplexe bedingte Typen beseitigt, IsEmptyInterface denen die Funktionsüberladung das gleiche erreicht hat (Entfernung von

Ich möchte hinzufügen, dass ich derzeit zwischen TS 3.2.4 und 3.7.4 hin und her wechsle. Unsere Typentestsuite läuft in 3.7.4 50% langsamer als in 3.2.4 (~90s vs. 50s).

Ich werde weiter untersuchen, ob wir die Tiefe von CSSProperties begrenzen und die Unterstützung für Medienabfragen und Pseudoselektoren vollständig entfernen können. Diese nicht getippt zu haben, ist jedoch nicht wirklich eine Option. Der Typprüfer sollte diese in angemessener Zeit überprüfen können.

Möglicherweise ist die Typenprüfung der eigentliche Flaschenhals. Vielleicht können wir untersuchen, in welcher Version die Perf getroffen wurde.

Wenn Sie mir die Befehle senden, die Sie in 3.2.4 und 3.7.4 ausführen, kann ich ein lokales Profil erstellen. Die Erfahrung deutet jedoch darauf hin, dass sich die Ursache wahrscheinlich als zusätzliche, wünschenswerte Überprüfung herausstellen wird, die seit 3.2.4 hinzugefügt wurde. (Und ich gehe davon aus, dass "0s" ein Tippfehler ist - wahrscheinlich "40s" oder "50s"?)

In Bezug auf CSSProperties stimme ich zu, dass die Beibehaltung der Eigenschaftsnamen und -typen äußerst wertvoll ist. Ich denke jedoch, dass es mehr gibt, als sie in angemessener Zeit zu überprüfen - das erste Problem besteht darin, dass das Typsystem nicht die gewünschte Form ausdrücken kann. Ich denke, wir werden wahrscheinlich einige Zeit damit verbringen, an einer allgemeinen Lösung des Problems zu arbeiten - kann ich davon ausgehen, dass Sie daran interessiert sind, an dieser Diskussion teilzunehmen?

Wir haben Skripte zum Vergleichen mehrerer Versionen des Compilers. Wenn Sie also einen relativ stabilen Test identifizieren können, den Sie von uns ausführen möchten, können wir die Verlangsamung im Laufe der Zeit darstellen.

(Und ich gehe davon aus, dass "0s" ein Tippfehler ist - wahrscheinlich "40s" oder "50s"?)

Entschuldigung, es sind 50er Jahre.

Wenn Sie mir die Befehle senden, die Sie in 3.2.4 und 3.7.4 ausführen, kann ich ein lokales Profil erstellen.

Es ist nur yarn typescript im Stammverzeichnis, das den gleichen Befehl in jedem Arbeitsbereich ausführt, der ihn implementiert. Zum Beispiel testet yarn workspace @material-ui/styles run typescript unsere Typen mit tslint und dtslint 's $ExpectError . In 3.7.4 sind wir auf einige Fehler gestoßen und mussten unsere Tests anpassen (siehe #19242)

Das erste Problem besteht darin, dass das Typsystem die gewünschte Form nicht wirklich ausdrücken kann.

Das habe ich vermutet. Es sieht so aus, als ob die Art und Weise, wie wir eine "konkrete" Form mit einem Objekt mit einer Indexsignatur mischen, nur ein Workaround ist.

Kann ich davon ausgehen, dass Sie daran interessiert sind, sich an dieser Diskussion zu beteiligen?

Bestimmt. Ich werde etwas mehr Zeit mit nicht-rekursiven CSSProperties verbringen und dann noch ein paar Tests schreiben, um zu veranschaulichen, wonach wir in diesen Typen suchen. Ich würde vermuten, dass andere CSS-in-Js-Styling-Lösungen auf ähnliche Leistungsengpässe stoßen.

Ich werde diese Befehle morgen ausprobieren (ich denke, ich sollte erwähnen, dass ich in der Pazifikzeit bin und US-Feiertage beobachte).

Es sieht so aus, als ob die Art und Weise, wie wir eine "konkrete" Form mit einem Objekt mit einer Indexsignatur mischen, nur ein Workaround ist.

Danke, ich habe mich schwer getan, wie ich das am besten ausdrücken kann. Ja, Sie haben Recht, dass die Indexsignatur nicht das tut, was Sie wollen. Wir haben einige Gedanken zu einer möglichen Variante, müssen jedoch die Auswirkungen auf die Leistung untersuchen.

Ich würde vermuten, dass andere CSS-in-Js-Styling-Lösungen auf ähnliche Leistungsengpässe stoßen.

Besonders gern. Wir hoffen, dass alles, was wir für Sie tun, verallgemeinert werden kann, um das gesamte Ökosystem zu verbessern.

Ich habe das Gefühl, etwas Offensichtliches zu verpassen, aber ich stecke derzeit fest. Zuerst habe ich Windows aufgegeben - die Dinge scheinen unter Linux besser zu funktionieren. Lassen Sie es mich wissen, wenn Sie darauf eingehen möchten. Zweitens kann ich yarn typescript zum Laufen bringen - sauber, soweit ich das beurteilen kann -, aber es scheint eher tslint als reines tsc auszuführen. Wenn ich tsc auf derselben tsconfig.json ausführe (ich teste speziell mit Stilen), erhalte ich ~ 40 Fehler. Was mache ich falsch? Für Profilerstellungszwecke wäre es sehr hilfreich, das Repro auf einen einzigen tsc-Aufruf zu reduzieren.

Bei @amcasey yarn typescript geht es nicht um Kompilierung, sondern um das Testen unserer Typen. Wir verwenden ein ähnliches Setup wie das im DefinitelyTyped-Repository verwendete. TypeScript-Dateien in packages/* sind fast immer nur eine Ansammlung von Anweisungen, die entweder bestehen oder fehlschlagen sollten, die wir mit $ExpectError abfangen.

Ich denke, der beste "reale" Testfall ist die Verwendung von tsc in unseren Dokumenten über yarn workspace docs run tsc -p tsconfig.json nachdem Sie skipLibCheck: true und noEmit: true zu ./docs/tsconfig.json hinzugefügt haben

--- a/docs/tsconfig.json
+++ b/docs/tsconfig.json
@@ -3,6 +3,8 @@
   "include": ["types", "src/pages/**/*"],
   "compilerOptions": {
     "allowJs": false,
-    "noUnusedLocals": true
+    "noUnusedLocals": true,
+    "noEmit": true,
+    "skipLibCheck": true
   }
 }

@eps1lon Danke für die Klarstellung. Ich bin nicht begeistert, dass Tslint langsamer wurde, aber ich möchte mich auf eine Variable nach der anderen konzentrieren. Ich werde den von Ihnen vorgeschlagenen Docs-Build mit verschiedenen Versionen von Typoskript ausführen und sehen, ob etwas herausspringt. Danke!

Dieses Setup ist perfekt. Ich sehe, dass sich die Prüfzeit zwischen 3,3 und 3,4 verdoppelt.

| Version | Zeit überprüfen |
|-|-|
| 3.2 | 16.71s |
| 3.3 | 16.79s |
| 3.4 | 35,25s |
| 3,5 | 21.40s |
| 3,6 | 23.10s |
| 3,7 | 27,39s |

Ich werde noch ein bisschen weitergraben, aber mir wurde gesagt, dass die 3.3-Implementierung von bedingten Typen unvollständig war, die 3.4-Implementierung langsam war und die 3.5-Implementierung gut ist. Dies ist also leider wahrscheinlich zu erwarten.

Insbesondere vermute ich, dass diese Änderung die in diesem Fehler beschriebene Verlangsamung verursacht hat.

Ich finde es bedenklich, dass zwischen 3,5 und 3,7 die Zeit, die für die Durchführung des Checks benötigt wurde, um 6 Sekunden verlängert wurde. Das sieht ziemlich massiv aus.

@embeddedt Diese Zahlen stammen aus einzelnen Läufen mit jeder Version, daher gibt es wahrscheinlich ziemlich viel Rauschen. Ich werde mich jedoch umsehen und sehen, ob ich etwas finde.

Ich habe es auf einer Linux-VM neu erstellt und 3.7 war durchweg 20-25% langsamer als 3.5.

Dies hat sich als ziemlich schwierig zu halbieren erwiesen, da aufeinanderfolgende Läufe desselben Builds um ~5% variieren und der Unterschied zwischen 3,5 und 3,6 oder zwischen 3,6 und 3,7 nur ~10% beträgt.

Eine verdächtige Sache, die mir aufgefallen ist, ist, dass styled-components separate .d.ts-Dateien für TS >= 3.7 bereitstellt, sodass der Vergleich möglicherweise nicht Äpfel mit Äpfeln ist.

Zu meiner großen Überraschung scheinen die neuen styled-components Typen schneller zu sein. Der Vergleich von Äpfeln mit Äpfeln wird die Untersuchung dennoch erleichtern.

Mir ist keine schlaue Lösung eingefallen, daher werde ich die Kompilierungszeit für Merge zusammenführen und nach Spitzen suchen. Ich hoffe, morgen Zahlen zu haben.

@amcasey Vielen Dank für Ihre Bemühungen, dies zu untersuchen! Wirklich schön zu sehen, wie Mitglieder des TS-Teams und Material UI zusammenarbeiten. Ich bin über dieses Github-Problem gestolpert, um herauszufinden, warum unsere Editor-Erfahrung mit Material UI so langsam ist (wir verwenden es in zwei Projekten bei der Arbeit). Kann definitiv bestätigen, dass wir einen ziemlich signifikanten Einfluss auf Intellisense und Benutzerfreundlichkeit in VsCode sehen.

An dieser Stelle würden wir gerne ein wenig Typsicherheit in unserem JSS gegen schnelles Feedback für den Rest der Bibliothek eintauschen. Manchmal dauert es 8-10 Sekunden, bis der Typescript-Server Codeänderungen einholt

Selbst bei drei Durchläufen sind die Daten sehr verrauscht. Allerdings scheint es bei https://github.com/microsoft/TypeScript/commit/ad322a561a301ae357da051b9221b2222c13be36 einen spürbaren Rückgang der Laufzeit zu geben, bei https://github.com/microsoft/TypeScript /commit/480b73915fdd805952fd355e4cf3e1bc803e0878 und danach ein allgemeiner Aufwärtstrend (obwohl er für mich zu einheitlich aussieht und ich Umweltfaktoren vermute) einschließlich eines bestimmten Anstiegs bei https://github.com/microsoft/TypeScript/commit/c5e6d95e930048a033868d72440ec.929690a Ich werde mich auf die ersten beiden konzentrieren, bis ich weitere Tests durchführe, um den allgemeinen Aufwärtstrend zu bestätigen (wie könnte es bei jedem Commit gleichmäßig schlimmer werden?).

Der Aufwärtstrend hält einer Überprüfung stand, und ich habe keine Ahnung, woran das liegen könnte. Vielleicht liegen die diskreten Verlangsamungen so nah beieinander, dass sie durch das Rauschen wie eine einzelne Kurve aussehen.

Ich habe bis zu 10 Runs pro Commit erhöht und jetzt gibt es vier unterschiedliche Regressionen im geneigten Bereich. :Lächeln:

https://github.com/microsoft/TypeScript/commit/26caa3793e310e271ddee8adc1804486e5b0749f (~700ms)
https://github.com/microsoft/TypeScript/commit/250d5a8229e17342f36fe52545bb68140db96a2e (~500ms)
https://github.com/microsoft/TypeScript/commit/7ce793c5b8c621af5ce50af0ca3958c7bd6541bf (~1300ms)
https://github.com/microsoft/TypeScript/commit/28050d5c47c6cd7627555f12cf13b1062f80322a (~400ms)

(Die Gesamtzeit bis zum Beginn der Regressionen betrug ~33 s.)

Nur um die Erwartungen ein wenig zu dämpfen: Es ist sehr wahrscheinlich, dass sich einige dieser Regressionen als wertvolle zusätzliche Schecks herausstellen und selbst wenn wir alle diese Schecks kostenlos bekommen würden, würden wir immer noch nur 20% Rabatt "viel zu lange" nehmen ".

Edit: Ich habe die Links aktualisiert. Da ich durch die Zeit rückwärts ging, war ich verwirrt und markierte die Zusammenführung _vor_ jeder Regression.

@eps1lon Jemand in diesem @ts-ignore hilfreich sein könnte. Grundsätzlich wird davon ausgegangen, dass beim Erkennen eines Fehlers die oberste Priorität des Benutzers darin besteht, gute Informationen über den Fehler zu erhalten. Daher ist es möglich, dass eine Menge zusätzlicher Arbeit geleistet wird. Wenn diese Informationen anschließend gelöscht werden (wegen @ts-ignore ), dann ist diese Zeit einfach verschwendet. (Leider ist es nicht einfach zu erkennen, dass ein Fehler nicht erkannt werden muss.) Eine alternative Strategie besteht darin, explizite Typzusicherungen (einschließlich any ) hinzuzufügen, bis der Compiler aufhört, sich zu beschweren.

@eps1lon Jemand in diesem @ts-ignore hilfreich sein könnte.

Wir hatten nur eine einzige Verwendung in docs/ . Ich habe es trotzdem entfernt, nur für den Fall: #19504

Um ehrlich zu sein, klingt es so, als ob @ts-ignore in diesem Fall ein Anti-Muster wäre. Es gibt Ihnen nicht nur keine nützlichen Informationen, zB welche Art von Fehler wir haben, sondern es ist auch ein Perf-Engpass.

Soweit ich das beurteilen kann, ist @ts-ignore nur in .js Dateien nützlich, die einer Typprüfung unterzogen werden.

Hmm, das erklärt mit ziemlicher Sicherheit nicht, warum die PR-Fehlermeldungen zur Verbesserung der Leistung zurückgegangen sind. Sieht aber auf jeden Fall nach einer Verbesserung aus. 😄

Ich bin ziemlich neu in der Welt von TypeScript, insbesondere wenn es um Styling-in-JS-Lösungen geht, aber ich habe diesen Thread im letzten Monat in Ruhe verfolgt und war neugierig auf die Gedanken der Leute zu einer möglichen Problemumgehung unter zumindest kurzfristig.

Ich gehe davon aus, dass einige Benutzer (ich selbst einer) das eingebaute Styling-System nicht intensiv nutzen oder ganz vermeiden. Ich tue das hauptsächlich, weil ich mit einfachem CSS oder Sass viel vertrauter bin und nicht wirklich Zeit habe, mich mit der effektiven Verwendung des JS-Styling-Systems zu beschäftigen. Ich bevorzuge es, einfach meine eigenen Klassennamen zu erstellen, eine separate Stylesheet-Datei zu schreiben, die Klassennamen in meinen React-Komponenten zu verwenden und weiterzumachen. Im Wesentlichen gestalte ich so, als ob ich einfaches HTML schreiben würde.

Ist es jedoch möglich/praktisch, ein Flag hinzuzufügen, das die Typprüfung für die teuren Teile des Stylingsystems deaktiviert (möglicherweise durch bedingte Aktionen wie type CSSProperties = any )? Ich kenne die Statistiken für die Anzahl der Personen, die das Stilsystem verwenden, im Vergleich zu denen, die es nicht verwenden, nicht, aber ich denke, dass es nicht wirklich viel schaden kann (vorausgesetzt, dass eine Überprüfung hinzugefügt wurde, um die Eingaben mit diesem Flag zu testen). , und es wäre eine schnelle Möglichkeit, die Leistung für mindestens ein Benutzersegment zu verbessern.

Wollte nur die allgemeine Idee erwähnen; schieße es gerne ab. :leicht_smiling_face:

@embeddedt Im Allgemeinen ist das explizite Markieren von etwas als any eine gute Möglichkeit, die Typprüfung für dieses Symbol zu deaktivieren. Trotzdem kann ich mich nicht erinnern, ob Sie einfach eine vorherige Deklaration überlisten können oder eher, wie Sie vorschlagen, Compiler-Unterstützung benötigen, um Probleme mit doppelten Deklarationen zu vermeiden.

Neue Zahlen (andere Maschine, andere Zeitmetrik):

| Version | Gesamtzeit |
|-|-|
| 3.5.3 | 32,5s |
| 3.7.5 | 35,9s |
| Meister | 29,9s |

Einige der oben geposteten Probleme sind noch offen, aber wir sind im Grunde wieder bei 3,5 (für diesen Benchmark). Natürlich ist es immer noch viel langsamer, als wir es gerne hätten, aber die nächsten Änderungen werden wahrscheinlich auf der Material-UI-Seite stattfinden.

Getestet 3.8.1 in unserer Testsuite und es scheint, als wären sie so schnell wie die vorherigen mit 3.2.4 (3.7 war deutlich langsamer).

Ehrlich gesagt kann ich nicht glauben, wie viel Leistung wir zurückgewinnen konnten, ohne die neue Funktionalität aufzugeben. :smile: Ich denke, es könnte etwas mehr Spiel geben (zB https://github.com/microsoft/TypeScript/pull/36754), aber ich vermute immer noch, dass die wirkungsvollste Änderung eine Vereinfachung der CSSProperties-Typen wäre. Hatten Sie überhaupt die Gelegenheit, damit herumzuspielen? Es scheint, als ob zumindest eine Teilmenge von Benutzern (zB @embeddedt) gerne auf eine Typprüfung im Austausch für einen Perf-Win verzichten würde.

Es scheint, als ob zumindest eine Teilmenge von Benutzern (zB @embeddedt) gerne auf die Typprüfung im Austausch für einen Perf-Win verzichten würde

Hat nicht gerade jemand aus dem TS-Team getwittert, dass es für jeden User, der strengere Typen will, einen gibt, der lockerere will? :Lächeln:

Für mich geht es nicht wirklich um Typprüfung (Browser-Devtools haben viel bessere Möglichkeiten, Ihr CSS zu überprüfen). Es geht mehr darum, dass die automatische Vervollständigung verfügbar ist.

Ich werde mit verschiedenen "Versionen" herumspielen und sehen, wie sie sich machen.

@amcasey Ich glaube nicht, dass die rekursive Natur von CSSProperties (in Styled-Komponenten CSSObject genannt) das Hauptproblem ist. Sonst wäre ihre Perf genauso schlecht wie unsere. Siehe https://github.com/eps1lon/mui-types-perf/pull/6 und die Benchmark-Protokolle .

Es könnte eher ein Problem mit der Menge an "Überladung" sein, die wir tun. styled-components erlaubt nur ein statisches Objekt, während wir eine Thunk-Version sowie jede Eigenschaft als Thunk zulassen. Ich bin mir aber nicht sicher.

Ich würde gerne die Typsignatur vereinfachen (da dies IMO auch für Entwickler einfacher zu verstehen ist), aber ich wurde ausdrücklich gebeten, die JSS-Implementierung abzugleichen. Jetzt, da wir es unterstützen, können wir nicht einfach zurückrollen. Vor allem, wenn der Gewinn im Bereich von 20 % liegt. Ich glaube nicht, dass das einen Bruch rechtfertigt.

Können die Typen bedingt weniger genau gemacht werden (basierend auf einer Benutzereinstellung)? Das sollte keinen vorhandenen Code beschädigen (da die Einstellung standardmäßig deaktiviert sein kann) und Benutzern wie mir, die die komplexen Typen nicht benötigen, ermöglichen, schnell eine Leistungssteigerung zu sehen.

würde es Benutzern wie mir, die die komplexen Typen nicht benötigen, ermöglichen, schnell eine Leistungssteigerung zu sehen.

Es ist nicht einmal bestätigt, dass Sie einen spürbaren Unterschied erzielen würden. Ich habe 15% Perf-Siege gesehen, aber es ist fraglich, ob dies erkennbar ist.

Die "Benutzereinstellung", die ich sehen konnte, ist das Patchen des Pakets bei der Installation. Wir haben nicht die Bandbreite, um mehrere Versionen der Typisierungen zu verwalten.

@eps1lon Entschuldigung, ich denke, meine Frage war möglicherweise unklar. Ich denke, dass CSSProperties in Ordnung ist (obwohl es natürlich schneller wäre, wenn es kleiner wäre) - ich hatte tatsächlich gehofft, dass es Platz geben könnte, die Untertypen in https://github.com/mui-org . zu vereinfachen diesen Typ in any ändern würden?

Bearbeiten: Auf meiner Box macht dies das Kompilieren des docs Projekts um 15% schneller (29,7 Sekunden auf 25,5 Sekunden), aber ich kenne die Auswirkungen auf die Bearbeitungserfahrung nicht.
Bearbeiten 2: Sobald Sie das Falten im rekursiven Teil des Typs aufgegeben haben, können Sie einfach BaseCreateCSSProperties und jede andere Eigenschaft hat den Typ any (dh Sie dürfen behalten die echten Typen der CSS-Eigenschaften).
Edit 3: Edit 2 funktioniert nicht, weil die Eigenschaften zu oft überprüft werden (dh beliebige Eigenschaftsnamen sind in Objektliteralen nicht erlaubt).

Ihr Punkt zu Vervollständigungen vs. Typprüfung war super interessant, weil ich die Hypothese hatte, dass einige Typautoren so denken könnten. @DanielRosenwasser Ich denke, wir haben uns "a" | "b" | string unterzubringen - hat das irgendwohin geführt?

Beachten Sie auch, dass styled-components (wir glauben) eng damit verbundene Probleme mit der Checker-Leistung hat.

Um den Typ genauer angeben zu können, habe ich https://github.com/microsoft/TypeScript/issues/36782 hinterlegt.

Sieht so aus, als ob emotion im selben Boot

Ich habe heute angefangen, Material UI ( 4.9.4 ) zu meinem Projekt hinzuzufügen, und die Verlangsamung ist wirklich so bedeutend, dass ich sie nicht einmal in meinem Projekt verwenden kann. Soeben wurde eine einfache <Slider/> Komponente hinzugefügt, die mit withStyles() angepasst wurde.

Wir sprechen davon, von sofortigem TypeScript-Feedback in meiner IDE zu manchmal 5-10 Sekunden überzugehen (für Teile meines Codes, die jetzt nicht einmal mit der Material UI interagieren - es ist nur eine vollständige TypeScript-Verlangsamung in der Datei, die verwendet wird die Komponente). Irgendetwas muss mit diesen Typen (oder ja, übermäßig komplex) nicht stimmen , es scheint, als ob

Ich versuche, einen Weg zu finden, dass ich zumindest alle TypeScript-Sachen für @material-ui vorerst ausschließen kann (im Wesentlichen das gesamte Modul zu any ) - aber TypeScript scheint das nicht einfach genug zu machen.

@lostpebble Geschieht das Gleiche, wenn Sie etwas anderes als withStyles , um den Schieberegler anzupassen, z. B. CSS-Module?

@lostpebble Wir haben derzeit keine unterstützte Möglichkeit, einen bestimmten Satz von Typen auszuschließen. Wenn Sie wirklich, wirklich wollen, können Sie mit Pfadzuordnungen experimentieren. Sie könnten eine Pfadzuordnung wie "@material-ui/*": ["simplemui"] versuchen und dann eine simplemui.d.ts mit erstellen

declare const x: any;
export = x;

Das würde effektiv alle Material-UI-Typen zu any . Es ist definitiv ein Hack und nichts, was ich empfehlen kann, aber es könnte Ihre Bearbeitungserfahrung freigeben.

Ich denke, wir haben einige gute Verbesserungen vorgenommen (irgendwo im Bereich von 30%), aber es sieht so aus, als ob wir im Moment nur die Eingaben lockerer machen könnten.

Dazu bedarf es unbedingt konkreter Vorschläge zB mit welchem ​​falschen Code würden Sie in Ordnung sein, um vom Typchecker akzeptiert zu werden. Dann müssten wir ein Benchmarking durchführen und sehen, ob dies eine sinnvolle Delle darstellt.

Sie müssen verstehen, dass absichtlich eingeführte Regressionen für die Betreuer eine Menge Arbeit bedeuten, da wir dies den Bibliotheksbenutzern erklären müssen und insgesamt ziemlich stressig sind.

Dies hat für mich im Moment keine Priorität, es sei denn, jemand hat umsetzbare Informationen. Sonst muss ich zu viel Zeit in sehr wenig Rendite investieren.

In meinem Fall für makeStyles(theme => createStyles(...)) , Rückgabe von Record<ClassKey, any> von createStyles(...) fast ~halbiert~ (in meinem Code und Computer ungefähr ~1200ms -> 750ms~ 1400ms → 1100ms) encodedSemanticClassifications-full: elapsed time wird im tsserver-Protokoll angezeigt (es sieht nicht nach einem teuren Job aus, wartet aber vielleicht darauf, dass die Typprüfung abgeschlossen ist).

export default function createStyles<ClassKey extends string, Props extends {}>(
  styles: StyleRules<Props, ClassKey>,
): Record<ClassKey, any>;

createStyles(...) überprüft die Stilstruktur, sodass wir die Typprüfung für Argument-Typ-der-massiven-Union von makeStyles vs. Rückgabe-Typ-von-massive-Union von createStyles überspringen können.

~(Und den gesamten makeStyles-Code auskommentieren: 650ms)~

@ypresto createStyles wird nur für Typoskriptversionen ohne const Behauptungen benötigt. Wenn Sie { display: 'block' as const } in Ihrer Codebasis verwenden können (ts >= 3.4), dann verwenden Sie dies über createStyles .

@eps1lon Wir haben das bemerkt und versucht, den Wechsel in docs vorzunehmen , aber die Ergebnisse waren nicht beeindruckend.

@eps1lon mit const und ohne createStyles zeigt IntelliSense keine kontextsensitiven Kandidaten mehr an :cry:

@ypresto Es sollte. Hast du ein Beispiel-Code-Snippet?

@amcasey

Das Hinzufügen von as const zum äußeren Objekt oder der Eigenschaft tötet es effektiv. Ich möchte es nicht auf jedem Grundstück platzieren.

const useStyles = makeStyles(theme => ({
  root: {
    // no IntelliSense
  }
} as const))

Auch ohne createStyles hat es eine kleine Einschränkung für die String-Vervollständigung.

const useStyles = makeStyles(theme => ({
  root: {
    direction: '|', // no IntelliSense at | (works with createStyles)
    direction: | // IntelliSense works at |
  }
}))

@ypresto Mit "tötet es" meinst du "dass es genauso funktioniert wie createStyles "?

Es ist mühsam, es überall zu platzieren, aber nicht mehr, als createStyles überall hinzubringen.

@amacleay Ich meinte kills IntelliSense : bete:.

Entschuldigung, ich habe Ihre Kommentare übersehen. Ich werde das mal versuchen.

Ich habe keine Ahnung warum, aber das sind 1100ms → 750ms, interessanterweise:

 export const DropArea: React.FC<CardProps & {
   active?: boolean
   description: string
   icon?: React.ReactNode
-}> = ({ active, description, icon, children, ...props }) => {
+}> = ({ children, ...props }) => {
   const classes = useStyles()
+  const active = false
+  const icon: React.ReactNode = null
+  const description = ''
   return (
     <Card {...props} className={clsx(classes.root)} variant="outlined">

Das Entfernen von CardProps & aus FC ist fast das gleiche Ergebnis. Vielleicht liegt es daran, dass CardProps PaperProps erweitert, was die großen HTMLAttributes erweitert.

UPDATE & WICHTIG: Es stellte sich heraus, dass das Ersetzen von CardProps durch HTMLAttributes<HTMLDivElement> auch die Zeit reduziert (nicht gemessen).

Schließlich habe ich den größten gefunden, 750ms → 130ms:

Entfernen von style={...} aus zwei Typografien.

-<Typography variant="subtitle2" component="div" noWrap style={{ width: '26ch' }}>...</Typography>
+<Typography variant="subtitle2" component="div" noWrap>...</Typography>
-<Typography variant="caption" component="div" noWrap style={{ width: '20ch' }}>...</Typography>
+<Typography variant="caption" component="div" noWrap>...</Typography>

Aber wieso? Das Hinzufügen des gleichen Stils zu <div> beeinträchtigt die Leistung nicht. Vielleicht ist OverridableComponent zu kompliziert...?

(Ich verwende TypeScript 3.8.3, @material-ui/core 4.9.1)

AFAIK behandelt Material-UI lokale Stile auf Komponenten anders als React für HTML-Elemente.

@embeddedt Auf der React.CSSProperties was der Stileigenschaft von div entspricht.

@ypresto Ich stehe korrigiert. Verzeihung.

Hallo Leute, ich bin mir nicht sicher, ob es sich lohnt, dafür ein neues Problem zu eröffnen, daher werde ich es hier posten, da es sich auf die Korrektheit/Leistung von Typen bezieht. Lassen Sie mich wissen, ob ich stattdessen ein Problem eröffnen soll.
Wenn ich der Dokumentation zum Hinzufügen einer benutzerdefinierten Schriftart folge, erhalte ich den folgenden Tippfehler:
Type 'string' is not assignable to type 'FontFaceFontDisplayProperty'

Es ist seltsam, weil die Eingaben von csstype 2.6.9 gültig erscheinen und andere Attribute in Ordnung sind (mit MUI 4.9.5).

const sourceSansPro = {
  fontFamily: "'Source Sans Pro'",
  fontStyle: "normal",
  fontDisplay: "swap", // won't work
  fontWeight: 400,
  src: `
    url('/static/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf') format("truetype")
  `
};

Themeneigenschaft:

  overrides: {
    MuiCssBaseline: {
      "@global": {
        "@font-face": [sourceSansPro]
      }
    }

Typ ist type FontFaceFontDisplayProperty = "auto" | "block" | "fallback" | "optional" | "swap";

@eric-burel Dies ist ein Problem mit der automatischen Typerweiterung von Typoskripten. Versuchen

- fontDisplay: "swap", // won't work
+ fontDisplay: "swap" as "swap",

Danke, es funktioniert, und ich habe ein neues Konzept "Typerweiterung" gelernt :) Es ist seltsam, dass fontStyle zum Beispiel nicht betroffen ist, es ist nicht die einzige CSS-Eigenschaft, die als Enumeration definiert ist, aber das erste Mal, wenn ich darauf klicke .

Bearbeiten: ok mein Fehler, es ist gut dokumentiert: https://material-ui.com/guides/typescript/#using -createstyles-to-defeat-type-widening

Schließlich habe ich den größten gefunden, 750ms → 130ms:

Entfernen von style={...} aus zwei Typografien.

-<Typography variant="subtitle2" component="div" noWrap style={{ width: '26ch' }}>...</Typography>
+<Typography variant="subtitle2" component="div" noWrap>...</Typography>
-<Typography variant="caption" component="div" noWrap style={{ width: '20ch' }}>...</Typography>
+<Typography variant="caption" component="div" noWrap>...</Typography>

Aber wieso? Das Hinzufügen des gleichen Stils zu <div> beeinträchtigt die Leistung nicht. Vielleicht ist OverridableComponent zu kompliziert...?

(Ich verwende TypeScript 3.8.3, @material-ui/core 4.9.1)

Haben Sie festgestellt, dass dies die Build-Zeit beeinflusst oder nur die Zeit, die benötigt wird, damit Intellisense nützlich ist? Ich bekomme das Build-Problem (nicht genügend Arbeitsspeicher) und ein Teil unseres TS-Codes hat eine Menge style={someStyle} für die Komponenten festgelegt. Ich frage mich, ob das Teil unseres Problems ist.

@yatrix7 , im Allgemeinen würde ich erwarten, dass sich diese langen

Untersuche ich das derzeit jemand? Ich weiß, dass es in früheren Versions-Upgrades einige Verbesserungen in Bezug auf die Zeit für die Typüberprüfung von Typoskripten gegeben hat. Es ist jedoch immer noch langsam.
Hätte nichts dagegen, das selbst zu prüfen.

Hätte nichts dagegen, das selbst zu prüfen.

Das wäre toll. Uns sind derzeit keine umsetzbaren Elemente bekannt, an denen wir arbeiten könnten. Hinweise auf Engpässe sind daher willkommen.

Für jetzt einige Benchmarking hinzugefügt, um die Untersuchung zu erleichtern :

@FabianKielmann Auf der TS-Seite habe ich an Perf-Untersuchungstools gearbeitet, von denen ich hoffe, dass sie bald ausgereift genug für Material-UI sind.

Wenn Sie etwas Zeit dafür haben, können Sie auch etwas wie https://github.com/microsoft/TypeScript/issues/38583 ausprobieren

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen