Material-ui: [RFC] v5-Styling-Lösung 💅

Erstellt am 24. Aug. 2020  ·  105Kommentare  ·  Quelle: mui-org/material-ui

Dieser RFC ist ein Vorschlag zum Ändern der Styling-Lösung von Material-UI in Version 5.

TL: DR;

Was ist das Problem?

  • Die Wartung und Entwicklung einer großartigen Styling-Engine nimmt viel Zeit in Anspruch. Wir haben es aus erster Hand erlebt. In den letzten 12 Monaten haben wir es vorgezogen, Zeit in unser zentrales Wertversprechen zu investieren: die UI-Komponenten, anstatt die Style-Engine zu verbessern. Die Arbeit daran hat hohe Opportunitätskosten.
  • Wir hatten Probleme mit der Unterstützung dynamischer Stile für die Komponenten. Die Leistung unserer Implementierung von benutzerdefinierten dynamischen Stilen (basierend auf Requisiten) ist nicht besonders gut (siehe die Leistungsbenchmarks unten). Dies schränkt die Qualität der Entwicklererfahrung, die wir anbieten können, ernsthaft ein. Es ist ein Blocker zur Verbesserung unserer API in Bezug auf Anpassbarkeit oder einfache Schreibstile. Zum Beispiel wird es freischalten: Style Utils Requisiten , Farbvariante und benutzerdefinierte Variante .
  • Die gesamte React-Community hat nicht für die Verwendung von JSS in großem Maßstab gestimmt (JSS ist großartig und wird immer noch verwendet). Vor 3 Jahren haben wir auf die beste verfügbare Option gewettet . Wir müssen erkennen, dass jetzt bessere Optionen verfügbar sind. Wir können uns schneller bewegen und besseres DX / UX freischalten, indem wir auf einer populäreren, vorhandenen Styling-Lösung aufbauen.
  • Viele Entwickler verwenden Styled-Komponenten, um die Stile der Material-UI zu überschreiben. Endbenutzer haben zwei CSS-in-JS-Bibliotheken in ihrem Bundle. Nicht gut. Es wäre besser, wenn wir verschiedene Adapter für verschiedene CSS-in-JS-Bibliotheken anbieten könnten. (Mögliche Probleme: Möglicherweise müssen wir die Kernstile neu schreiben, um sie an die Syntax der verwendeten Engine anzupassen. 🤷‍♀️)

Was sind die Anforderungen?

Für welche Styling-Engine wir uns auch entscheiden, wir müssen die folgenden Faktoren berücksichtigen:

  • Leistung: Je schneller desto besser, aber wir sind bereit, etwas Leistung zu handeln, um den DX zu verbessern.
  • Bündelgröße : Unter unseren aktuellen
  • Support Concurrent Mode: @material-ui/styles hat teilweise Unterstützung, während ich schreibe.
  • unterstütze SSR
  • einfache Anpassung
  • dynamisches Styling ermöglichen
  • gute Community-Größe
  • Themen
  • flache Spezifität
  • RTL
  • Typoskript

Es wäre schön, wenn es Folgendes unterstützen könnte:

Welche Möglichkeiten haben wir?

  • gestylte Komponenten
  • Emotion
  • JSS (derzeit in Material-UI verpackt)
  • Styletron
  • Aphrodite
  • Fela
  • sonst?

Vergleich

Performance

Hier sind Benchmarks mit dynamischen Stilen mehrerer gängiger Bibliotheken (beachten Sie, dass die Material-UI v4 nur statische Stile mit guter Leistung verwendet ):

PR als Referenz: https://github.com/mnajdova/react-native-web/pull/1

Aufgrund der Leistung denke ich, dass wir Folgendes eliminieren sollten: JSS (derzeit in @ material-ui / styles verpackt), styletron und fela. Das würde uns verlassen mit:

  • gestylte Komponenten
  • Emotion
  • Aphrodite
  • JSS
  • React-Styletron
  • Fela

Dynamische Requisiten

Aufgrund der offenen Fragen scheint Aphrodite keine dynamischen Requisiten zu unterstützen: https://github.com/Khan/aphrodite/issues/141
was meiner Meinung nach bedeutet, dass wir diese auch aus unseren Optionen streichen sollten, was uns Folgendes lässt:

  • gestylte Komponenten
  • Emotion
  • Aphrodite
  • React-Styletron

npm

Während styled-components und emotion beide Bibliotheken sehr beliebt sind, liegt react-styletron zu der Zeit oder beim Schreiben mit rund 12500 Downloads pro Woche weit zurück (dies ist meiner Meinung nach ein starker Grund Warum wir es beseitigen sollten, als ob wir uns dafür entscheiden würden, muss die Community wieder zwei verschiedene Styling-Engines in ihren Apps haben.

Hier ist die Liste, die nach der Anzahl der wöchentlichen Downloads zum Zeitpunkt des Schreibens geordnet ist:



Beachten Sie, dass das Bilderbuch von Emotionen abhängig ist.

  • gestylte Komponenten
  • Emotion
  • React-Styletron

Unterstützt den gleichzeitigen Modus

  • Emotion: JA . Seit v10 ist es streng im Modus kompatibel, basierend auf dem Ankündigungsbeitrag . Ich habe es an einem einfachen Projekt getestet, das wie erwartet funktioniert.
  • gestylte Komponenten: Teilweise . Es gibt mindestens einen Fehler mit globalen Stilen im strengen Modus.

SSR

Sterne

  • Styled-Komponenten: 30,6k
  • Emotion: 11.4k
  • JSS : 5,9k

Verkehr auf der Dokumentation

SimilarWeb geschätzte Sitzungen / Monat:

  • sass-lang.com : ~ 476K / Monat (zum Vergleich)
  • styled-components.com: ~ 239K / Monat
  • emotions.sh: ~ 59K / Monat
  • cssinjs.org : <30.000 / Monat (zum Vergleich)

Benutzerfeedback

Basierend auf der Umfrage verwenden 53,8% Prozent die Material-UI-Stile (JSS), was keine Überraschung ist, da es sich um die Engine handelt, die von Material-UI stammt. Wir können jedoch feststellen, dass 20,4% bereits gestylte Komponenten verwenden. Dies ist eine große Zahl, wenn man bedenkt, dass wir keine direkte Unterstützung dafür haben. Emotionen werden von rund 1,9 Prozent der Entwickler verwendet, die derzeit an der Umfrage teilnehmen.

Mit diesen Zahlen möchten wir die Unterstützung für gestylte Komponenten verbessern, daher sollten wir dies berücksichtigen.

Browser-Unterstützung

  • Emotion: moderne immergrüne Browser + IE11
  • Styled-Komponenten: Nicht für Version 5 dokumentiert, aber die vorherigen Versionen unterstützen Folgendes

Bündelgröße

Was ist die beste Option?

Standardmotor

Selbst wenn wir uns entscheiden, mehrere Engines zu unterstützen, müssten wir uns standardmäßig für eine einsetzen und eine in den Demos dokumentieren lassen.

gestylte Komponenten

Vorteile:

  • Hat die größte Community, die Leute lieben es, sie zu nutzen.
  • Die Leistung ab Version 5 ist gut.

Nachteile:

  • Dies bedeutet, dass alle Komponentenstile mit der API styled werden müssen. Für Entwickler bedeutet dies, dass sie immer Wrapper-Komponenten haben, wenn sie neu formatieren müssen.
  • Mangel an vollständiger gleichzeitiger Unterstützung, was später zu Blockern führen kann.

Emotion

Vorteile:

  • Relativ große Gemeinschaft wächst.
  • Gute Leistung.
  • Der gleichzeitige Modus + SSR wäre sofort möglich.
  • Die CSS-Requisite kann für Überschreibungen nützlich sein.
  • Unterstützung der Quellkarte.
  • Ein bisschen kleiner.

Nachteile:

Unterstützt mehrere

Wir können versuchen, mehrere CSS-in-JS-Lösungen zu unterstützen, indem wir unsere internen Adapter für sie bereitstellen. Einige Dinge, die wir berücksichtigen müssen, sind, dass wir möglicherweise doppelte Arbeiten an den Stilen haben, da die Syntax zwischen ihnen unterschiedlich ist (zumindest jss im Vergleich zu gestylten Komponenten / Emotionen). Wir werden das Themenobjekt wiederverwenden, egal welche Lösung wir wählen.

Die weniger aufwändige Unterstützung hierfür kann durch die Verwendung von styled , da die Benutzer möglicherweise eine Webpack-Konfiguration durchführen, um zu entscheiden, welche verwendet werden soll - (dies ist nur eine Überlegung).

Zusätzliche Kommentare

Deterministische Klassennamen für die Komponenten, auf die für benutzerdefinierte Stile abgezielt werden kann

In Bezug darauf, wie die Klassen aussehen und wie Entwickler sie ansprechen können, möchte ich einen Vergleich dessen zeigen, was wir derzeit haben und wie das Problem mit dem neuen Ansatz gelöst werden kann.

Als Beispiel nehme ich die Slider-Komponente. So sieht das generierte DOM derzeit aus:

Jede der Klassen hat eine sehr gut beschreibende Semantik, und die Benutzer können diese Klassen verwenden, um die Stile der Komponente zu überschreiben.

Auf der anderen Seite erzeugen Emotionen, Stilkomponenten oder eine ähnliche Bibliothek einen Hash als Klassennamen. Damit wir dies lösen und den Entwicklern die gleiche Funktionalität für das Targeting von Klassen bieten können, fügt jede der Komponenten Klassen hinzu, auf die die Entwickler basierend auf den Requisiten zielen können.

Dies würde bedeuten, dass abgesehen von den durch Emotionen erzeugten Klassen jede Komponente noch die Klassen hat, die wir zuvor hatten, wie MuiSlider-root & MuiSlider-colorPrimary . Der einzige Unterschied wäre, dass diese Klassen jetzt sein werden wird lediglich als Selektor verwendet, anstatt die Stile für die Komponenten zu definieren. Dies könnte wie ein Hook implementiert werden - useSliderClasses

Fazit

Unabhängig davon, für welche Lösung wir uns entscheiden würden, würden wir die API styled , die von beiden unterstützt wird. Dies ermöglicht uns später eine einfachere Unterstützung für gestaltete + nicht gestaltete Komponenten (wahrscheinlich mit Webpack-Aliasnamen, z. B. für die Verwendung von preact).

Nachdem wir die beiden Optionen untersucht haben, die wir am Ende hatten, schlägt das Kernteam vor, mit Emotionen zu arbeiten . Einige Schlüsselelemente:

Kleine Migrationskosten zwischen gestalteten Komponenten und Emotionen

Entwickler, die bereits gestylte Komponenten verwenden, sollten in der Lage sein, Emotionen fast mühelos zu verwenden.

Es gibt verschiedene Möglichkeiten, andere Überschreibungen als Wrapper-Komponenten hinzuzufügen

Die Unterstützung von cx + css durch Emotionen kann für Entwickler von Vorteil sein, wenn sie es als Alternative zum Hinzufügen von Stilüberschreibungen verwenden, wenn sie keine Wrapper-Komponenten erstellen möchten.

Der gleichzeitige Modus wird mit Sicherheit unterstützt: +1:

Ein großes Lob an eingehendere Untersuchung dieses Themas. Bisher haben wir im Code von @emotion nichts befürchten könnte, dass der gleichzeitige Modus nicht funktioniert.
Wir haben uns auch createGlobalStyle von gestylten Komponenten als Vergleich mit der globalen Komponente von Emotion angesehen. Es erledigt den größten Teil seiner Arbeit während des Renderns (von Natur aus problematisch für den strengen / gleichzeitigen Modus) und verwendet useEffect nur zum Entfernen von Stilen in seiner Bereinigungsfunktion. createGlobalStyle muss vollständig neu geschrieben werden, bevor es im gleichzeitigen Modus verwendet werden kann. Es ist nicht in Ordnung, während des Renderns Stile hinzuzufügen, wenn dieses Rendern niemals festgeschrieben wird. Es sieht so aus, als hätte jemand im letzten Monat versucht, es mit einigen weiteren Änderungen neu zu schreiben, daher müssen wir diesen Fortschritt verfolgen.

Wie wird mit der Spezifität umgegangen?

In den Dokumenten von Emotion wird empfohlen, CSS in einer einzelnen Klasse zusammenzusetzen, anstatt zu versuchen, Stile aus mehreren Klassennamen zu nutzen. In Version 5 werden unsere vorhandenen globalen Klassennamen ohne damit verbundene Stile angewendet. Die Komposition von Komponenten im Emotionsstil kombiniert die Stile automatisch zu einer einzigen Klasse. Dadurch werden möglicherweise Probleme mit der Reihenfolge der Stylesheets behoben, die zumindest innerhalb der von Material-UI definierten Stile liegen, da die Stile jeder Komponente von einem einzelnen Klassennamen gesteuert werden: +1:.
Wir hätten also die globalen Klassennamen (die Entwickler auf verschiedene Arten für Anpassungen verwenden können) und dann einen einzelnen (durch Emotionen) generierten Klassennamen pro Element, der alle darin fließenden CSS-Quellen konsolidiert.
Die Spezifität wird dann durch Emotionen basierend auf der Reihenfolge der Komposition behandelt.
Alle Kompositionen, die Emotionen verwenden (ob Renderzeit- oder Definitionszeitkomposition), führen zu einer einzelnen Klasse für das Element.
Styled-Komponenten funktionieren in Bezug auf die Renderzeit-Komposition NICHT auf diese Weise (die Definition-Zeit-Komposition wird in einer einzigen Klasse zusammengefasst). Dieselbe Zusammensetzung in gestalteten Komponenten führt dazu, dass mehrere Klassen auf dasselbe Element angewendet werden und die Spezifität nicht so funktioniert, wie ich es beabsichtigt hätte.

Alternativen


Was denkst du darüber?

discussion

Hilfreichster Kommentar

Als Betreuer von Emotion sprechen - das klingt großartig 🚀

Wir sollten auch in der Lage sein, bald einen neuen Major zu veröffentlichen, der keine Revolution sein wird, nur einige Aufräumarbeiten, allgemeine Verbesserungen, Haken unter der Haube und Verbesserungen der TS-Typen (bessere Inferenz und Leistung).

Oh, und umgeschriebener Parser! Dadurch werden einige Randfehler in Emotion und Styled-Components beseitigt (wie derzeit verwenden beide denselben Parser). Es ist sowohl kleiner als auch schneller.

Alle 105 Kommentare

Nur zu ein paar Korrekturen:

Die gesamte React-Community hat gegen die Verwendung von JSS in großem Maßstab gestimmt.

Ich würde stattdessen vorschlagen, dass die React-Community nicht für JSS gestimmt hat. Vielleicht wurde es nicht so gut vermarktet wie andere Lösungen?

Wir haben nicht auf das richtige Pferd gewettet.

Wir wetten auf das einzige Pferd - es war ein Einpferderennen. Keine der anderen zu diesem Zeitpunkt verfügbaren Lösungen hat alle Kriterien erfüllt.

Emotion klingt großartig! Ich liebe es, TS-Unterstützung zu erhalten, z. B. Autocomplete und alle Vorteile des Tippens - mit CSS-in-JS - beim Erstellen von UI- oder Styling-Komponenten. Ist das noch möglich?

Das letzte bisschen hat mich erwischt! Ich würde gerne helfen, indem ich dies hinter einer Beta-Flagge mache oder einige Funktionen weiterentwickle:

Alle Kompositionen, die Emotionen verwenden (ob Renderzeit- oder Definitionszeitkomposition), führen zu einer einzelnen Klasse für das Element.
Styled-Komponenten funktionieren in Bezug auf die Renderzeit-Komposition NICHT auf diese Weise (die Definition-Zeit-Komposition wird in einer einzigen Klasse zusammengefasst).

Ich habe auch festgestellt, dass das Themenobjekt gleich bleiben wird, was meiner Meinung nach der absolut beste Weg ist, eine Anwendung zu thematisieren! Ich habe nichts anderes zu sagen: erstaunt:

Vielen Dank für die großartige Arbeit an M-UI. Ich liebe die Richtung, in die das Projekt geht.

Der Übergang zu einer standardisierteren Art des Stylings ist der richtige Weg. Ich weiß, dass das Team und die Community die Probleme lösen werden, und v5 wird - nach den Klängen - noch großartiger! :Rakete:

Als jemand, der sowohl gestylte Komponenten als auch Emotionen verwendet hat, kann ich bestätigen, dass der Übergang zwischen ihnen einfach und schmerzlos ist.

+ Emotion ist typskriptfreundlicher

Als Betreuer von Emotion sprechen - das klingt großartig 🚀

Wir sollten auch in der Lage sein, bald einen neuen Major zu veröffentlichen, der keine Revolution sein wird, nur einige Aufräumarbeiten, allgemeine Verbesserungen, Haken unter der Haube und Verbesserungen der TS-Typen (bessere Inferenz und Leistung).

Oh, und umgeschriebener Parser! Dadurch werden einige Randfehler in Emotion und Styled-Components beseitigt (wie derzeit verwenden beide denselben Parser). Es ist sowohl kleiner als auch schneller.

Was ist mit Änderungen, welche Option führt zu weiteren Änderungen (falls vorhanden)?

Sie sind sich nicht sicher, ob es einen Unterschied macht, aber wurden die Benchmarks mit den Babel-Plugins von Emotion und / oder Style-Component durchgeführt? Sie helfen, die Dinge weiter zu optimieren.

Nach meinem Verständnis hatte MUI zuvor angegeben, dass es sich um ein gestyltes Modell handelt. Dies ist also eine Überraschung. Ich denke, Emotion ist eine großartige Bibliothek, aber da derzeit mehr Menschen Styled verwenden, ist es wichtig, dass Sie Wege finden, ihnen gute Optionen zu bieten, wenn sie nicht zu Emotion migrieren möchten

@ ee0pdt Emotion ist sehr, sehr ähnlich wie gestylt. Ich denke, das ist ein Teil der gesamten Wahl für Emotion gegenüber gestylten Komponenten. Es gibt klare Vorteile, und die Migrationsverschuldung ist gering bis gar nicht.

Und es gibt einen ganzen Abschnitt über die Unterstützung beider, indem Entwicklern die Wahl gelassen wird. Das könnte ein langer Weg sein, aber andererseits würde die Standardisierung uns wahrscheinlich in Zukunft mehr helfen. Die vollständige Parallelität und keine Wrapper-Komponenten sind für mich ein Deal-Breaker. Ich verstehe, dass andere vielleicht etwas gestyltes wollen, und das sollte berücksichtigt werden. Ich würde lieber auf Standardisierung drängen

Warum wurde eine Styletron-Reaktion ausgeschlossen? Es wird eine ganze Metrik ausgelassen, die nicht berücksichtigt wurde, nämlich der Speicherverbrauch. Die Standard-Styletron-Engine (und Fela) ist atomar. Es ist zwar etwas langsamer, spart aber viel Speicher. Nachdem Sie viele Reaktionsseiten gesehen haben, tun Sie nichts und gehen nach einer Weile auf> 1 GB. Das ist ein bisschen besorgniserregend. Der Browser friert danach ein.

Mit einem atomaren Framework verbessert sich die Leistung im Laufe der Zeit global und komponentenübergreifend, da jede atomare "Klasse" zwischengespeichert wird. Wahrscheinlich auch nicht im Test reflektiert.

Zufrieden mit beidem, solange es SSR unterstützt

Ich habe gerade meine Stimme von der ursprünglichen Ausgabe der Komponenten zurückgezogen: sweat_smile: - Ich habe zuerst gelernt, Emotionen durch das Storybook zu kennen, aber It will mean that all components styles need to be created using the styled API, which means for developers they will always have wrapper components if they need to re-style. hat mich dazu gebracht, zu wechseln.

Vielen Dank an alle für das schnelle Feedback. Hier finden Sie Antworten auf einige der Kommentare / Fragen.

Was ist mit Änderungen, welche Option führt zu weiteren Änderungen (falls vorhanden)?

@ sag1v mit styled-components vs emotion führt keine mehr oder weniger bahnbrechenden Änderungen ein, die wir behandeln müssen. Die allgemeinen Änderungen betreffen, wie die Überschreibungen innerhalb des Themas aussehen würden:

// previosly
root: {
  contained: {
    '&$disabled': { // <-- this part will need to be transformed
      color: 'red',
    },
  },
  containedPrimary: {
    color: 'blue',
  },
}

// after
root: {
  contained: {
     '&.Mui-disabled': {
      color: 'red',
    },
  },
}

Da die Stilsyntax zwischen emotion & styled-components identisch ist, macht dies keinen Unterschied.

Sie sind sich nicht sicher, ob es einen Unterschied macht, aber wurden die Benchmarks mit den Babel-Plugins von Emotion und / oder Style-Component durchgeführt? Sie helfen, die Dinge weiter zu optimieren.

@ hc-codersatlas nein, aber die Perfs sind sowieso zwischen den Top-Wenigen, also glaube ich nicht, dass es einen Unterschied machen würde. Guter Anruf hart!

Warum wurde eine Styletron-Reaktion ausgeschlossen? Es wird eine ganze Metrik ausgelassen, die nicht berücksichtigt wurde, nämlich der Speicherverbrauch. Die Standard-Styletron-Engine (und Fela) ist atomar. Es ist zwar etwas langsamer, spart aber viel Speicher. Nachdem Sie viele Reaktionsseiten gesehen haben, tun Sie nichts und gehen nach einer Weile auf> 1 GB. Das ist ein bisschen besorgniserregend. Der Browser friert danach ein.

Mit einem atomaren Framework verbessert sich die Leistung im Laufe der Zeit global und komponentenübergreifend, da jede atomare "Klasse" zwischengespeichert wird. Wahrscheinlich auch nicht im Test reflektiert.

Meine Kommentare darüber, warum styletron-react ausgeschlossen wurde, können etwas irreführend sein. Die PR-Beschreibung wird sofort aktualisiert. Die Perfektion ist gut, aber das größte Problem, das ich mit Styletron habe, ist die Community: https://www.npmtrends.com/styletron-react-vs-@emotion/core -vs-styled-components Während sowohl Emotion- als auch Styled-Komponenten sind über 2000000 Downloads in den letzten 6 Monaten, Styletron ist rund 15000.

Auch atomares CSS kann Probleme mit Überschreibungen verursachen, da jeder Klassenname nur eine Styler-Regel enthält.

Ich habe eine Frage, ob wir uns entscheiden, Emotionen zu verwenden, die wir unten in den Code über alle Dateien einfügen möchten.
/ ** @jsx jsx * /
Dies ist das JSX-Pragma. Das JSX-Pragma ist standardmäßig React.createElement

Sie müssen es hinzufügen, wenn Sie die Eigenschaft css in Emotion verwenden. Für die styled API sowie die reguläre className API benötigen Sie diese nicht.

Es ist möglich, das Hinzufügen von JSX-Pragma zu überspringen, es erfordert jedoch ein zusätzliches Babel-Setup und eine schlechtere Unterstützung durch das Tool. Beispielsweise kann TS Ihre CSS-Requisite nicht so genau überprüfen wie bei Verwendung von JSX-Pragma. Weitere Informationen finden Sie hier: https://github.com/emotion-js/emotion/pull/1941/files#diff -9abe25e5d2b00958d4b9849f5f20c139R5

@ Mnajdova danke. Ich hatte nur gehofft, dass die Speichernutzung mehr als nur für Styletron bürgt. Was Downloads oder Community betrifft - "nur" Uber verwendet Styletron :) also keine Sorge. In erster Linie für Emotionen gestimmt.

Wäre cool, wenn es ein Babel-Plugin oder ähnliches gäbe, das statische Stile in echte CSS-Klassen umwandeln kann. Es gibt bereits eine ähnliche Bibliothek namens compiled . Die meisten Stile sind realistisch statisch.

Um nützlich zu sein, benötigt Fela eine Reihe von Plugins wie fela-plugin-rtl , fela-plugin-prefixer die die Leistung noch verschlechtern (https://github.com/microsoft/fluentui/pull/12289). Then Und dann Sie werden wahrscheinlich mit Emotion enden (https://github.com/microsoft/fluentui/pull/13547), da es manchmal doppelt so schnell sein kann wie Fela 📦

Meine einzige Sorge ist, dass ich css thingy von Emotion verwenden muss. Das ist eine große rote Fahne, basierend auf meiner Erfahrung. Ich musste so etwas aus einer großen Codebasis entfernen und machte keinen Spaß. Warum? Weil es eine Abstraktion ist, die mehr Probleme mit sich bringt als die, die langfristig gelöst wird.

Meistens versuchen wir, die Funktion styled verwenden, aber wir sind mit der Funktion makeStyles ziemlich zufrieden, um in einigen Fällen einige Klassen zu generieren.

Hoffentlich gibt es für diese beiden APIs keine bahnbrechende Änderung, und ich bin nicht gezwungen, das Makro css .

Meine einzige Sorge ist, CSS-Ding von Emotion verwenden zu müssen.

@yordis Du wirst definitiv nicht gezwungen sein, die css Requisite zu benutzen. Ich vermute, dass sich die Verwendungszwecke von makeStyles und withStyles ändern werden. Hoffentlich kann der Umfang der erforderlichen Änderungen größtenteils auf ein Codemod für die Importe beschränkt werden. Ich denke nicht, dass der in makeStyles oder withStyles verwendete Ansatz praktisch ist, um die Verwendung von Emotionen zu unterstützen. Daher würde ich erwarten, dass die fortlaufende Unterstützung dieser APIs über ein separates Paket erfolgt (so dass " @ material-ui / core "hat keine JSS-Abhängigkeit mehr), die nach der Veröffentlichung von v5 wahrscheinlich nur noch eine minimale Wartung erhalten würde (die Details zu makeStyles und withStyles sind nicht genau festgelegt Dies ist jedoch nur meine Spekulation über die Auswirkungen einer emotionalen Weiterentwicklung.

👍 die Wahl, Emotion zu verwenden. Das Vermeiden der styled API von styled-components ist ein Grund, warum mein Team Emotion gewählt hat (das neben der css Requisite auch eine ähnliche styled API unterstützt). Wir verwenden derzeit die Anpassung des Emotion for Material UI-Stils und es funktioniert ziemlich gut. Eingebaute Unterstützung wäre nur das i-Tüpfelchen.

Zu diesen Tatsachen:

Viele Entwickler verwenden Styled-Komponenten, um die Stile der Material-UI zu überschreiben. Endbenutzer haben zwei CSS-in-JS-Bibliotheken in ihrem Bundle

Unterstützt den gleichzeitigen Modus
gestylte Komponenten: Teilweise

Wenn gestaltete Komponenten den gleichzeitigen Modus vollständig unterstützen würden, wäre dies eine sinnvollere Wahl, da die meisten Entwickler die MUI mit gestalteten Komponenten überschreiben (ausgenommen JSS)? Der Punkt, dass Emotionen in der Bündelgröße kleiner sind, ist umstritten, wenn 2 CSS-in-Js-Lösungen enthalten sein müssen. Und ich würde annehmen, dass die meisten praktischen Anwendungen von MUI das Überschreiben seiner Stile beinhalten.

Während ich und mein Team Emotion als Hauptmethode für das Styling von Komponenten verwenden, bin ich auf einige Ineffizienzen in der Emotionsbibliothek gestoßen. Und ich frage mich, was ihr über diese unten erläuterten Ineffizienzen denkt.

Betrachten Sie unten Emotion StyledComponent;

const StyledComponent = styled.div`
  ${({color}) => color && `color: ${color}`};
  display: flex;
  justify-content: center;
  align-items: center;
  background: teal;
  font-size: 20px;
  padding-top: 8px;
  padding-bottom: 8px;
  margin-top: 12px;
  margin-bottom: 12px;
  border: 1px solid grey;
`

Wenn sich die Farbe ändert, wird eine neue CSS-Klasse generiert, wobei alle CSS-Requisiten ( display: flex, justify-content, ..., border: 1px soild grey ) kopiert werden. Was zu CSS-Klassen mit genau den gleichen CSS-Requisiten für jede Farbrequisite führen würde, siehe unten;
image

Eine weitere Ineffizienz, die wir festgestellt haben, besteht darin, dass eine neue Komponente, die von über StyledComponent wird, eine neue Klasse mit allen CSS-Requisiten erstellt, die von der Basis StyledComponent kopiert wurden. Betrachten Sie unten;

const DerivedComponent = styled(StyledComponent)`
  font-family: monospace;
`

Es wird eine weitere CSS-Klasse erstellt, die nur font-family: monospace zu der obigen CSS-Klasse hinzufügt, die aus StyledComponent generiert wurde. Das heißt, es wird ein CSS erstellt, in das alle Requisiten von StyledComponent kopiert wurden, wie unten zu sehen ist.

image

Wenn nun über StyledComponent und DerivedComponent zusammen verwendet werden, haben wir (anfangs) zwei CSS-Klassen mit doppelten CSS-Requisiten (die sich nur in der Schriftfamilie unterscheiden). Wie unten zu sehen ist;

image

Wie Sie sich vorstellen können, können einige CSS-Klassen, die doppelte CSS-Requisiten voneinander haben, sehr schnell wachsen.

Ich fand heraus, dass wir mit Emotion, wenn Komponentenstile zusammengesetzt werden, CSS-Klassen mit vielen doppelten CSS-Requisiten erhalten.

Ich bin nicht sicher, ob dieses Duplikat von CSS-Requisiten in jeder CSS-Klasse spürbare Auswirkungen auf Apps hat, aber ich frage mich, ob dies bei der Verwendung von Emotionen berücksichtigt wird.

Ich bezweifle nicht die Leistung von Emotion beim Erstellen und Anwenden von CSSStyle zur Laufzeit. Emotionen sind eine der schnellsten bei der Anwendung von CSS-Stilen, wie in Perf-Tests deutlich wird.
Ich bin nur besorgt, dass der CSS-Stil aufgebläht ist. Und da Emotion SSR (ed) sein kann, was bedeutet, dass Stile in HTML eingebettet sind, wird die HTML-Datei möglicherweise unnötig aufgebläht (mit CSS-Stil-Tags). Was wiederum dazu führt, dass viel mehr Tags von Browsern mit unnötigen CSS-Requisiten analysiert werden.

Wenn gestaltete Komponenten den gleichzeitigen Modus vollständig unterstützen würden, wäre dies eine sinnvollere Wahl, da die meisten Entwickler die MUI mit gestalteten Komponenten überschreiben (ausgenommen JSS)? Der Punkt, dass Emotionen in der Bündelgröße kleiner sind, ist umstritten, wenn 2 CSS-in-Js-Lösungen enthalten sein müssen. Und ich würde annehmen, dass die meisten praktischen Anwendungen von MUI das Überschreiben seiner Stile beinhalten.

@petermikitsh Die Gründe, warum wir zu Emotionen gekommen sind, sind eigentlich die vier Punkte in der Schlussfolgerung

  • Kleine Migrationskosten zwischen gestalteten Komponenten und Emotionen
    Entwickler, die bereits gestylte Komponenten verwenden, sollten in der Lage sein, Emotionen fast mühelos zu verwenden.
  • Es gibt verschiedene Möglichkeiten, andere Überschreibungen als Wrapper-Komponenten hinzuzufügen
    Die Unterstützung von cx + css durch Emotionen kann für Entwickler von Vorteil sein, wenn sie es als Alternative zum Hinzufügen von Stilüberschreibungen verwenden, wenn sie keine Wrapper-Komponenten erstellen möchten.
  • Der gleichzeitige Modus wird mit Sicherheit unterstützt 👍
  • Wie mit der Spezifität umgegangen wird

Wenn Entwickler wirklich vermeiden möchten, dass zwei CSS-in-JS-Lösungen im Bundle enthalten sind, sind die Migrationskosten für die Umstellung auf Emotion + gering. Sie unterstützen andere APIs als styled .

@ ko-throw danke fürs aufschreiben das sind alles gute punkte. Die Tatsache, dass Emotionen einen Klassennamen mit allen Stilen generieren, macht sie zur besseren Engine zum Auflösen von Überschreibungen. Das Problem, das wir möglicherweise bei der Generierung mehrerer Klassennamen haben, besteht darin, dass die zuletzt geschriebene Klasse gewinnt, was in Zukunft problematisch werden kann.

Bei einem anderen Projekt habe ich atomares CSS verwendet, bei dem der Speicherverbrauch viel besser ist, da alle CSS-Regeln nur einmal geschrieben werden. Vorhersehbare Überschreibungen sind jedoch ziemlich schwierig, da jeder Klassenname eine atomare Regel ist und dann wieder welche gewinnt. hängt von der Reihenfolge ab, in der sie geschrieben wurden, wenn Sie nicht alle Stile zuvor verarbeiten und korrekt zusammenführen, was sich letztendlich auf die Perfektion auswirken kann.

Andererseits glaube ich, dass Menschen mit jeder CSS-in-JS-Lösung nicht nur zufällig eine unendliche Kombination von Stilen erstellen, sondern immer noch ziemlich strukturiert sind, basierend auf dem Wert der Requisiten.

Dies sind jedoch wieder gute Punkte, an die wir denken werden, vielen Dank, dass Sie sie geteilt haben 👍

  • sonst?

Was ist mit [stylex] Ideenkompatibilität (wie [style9])?

  • sonst?

style9 oder eine andere CSS-Engine, die mit der Stylex- Idee kompatibel ist

Dies scheint ein Setup für die Erstellungszeit zu erfordern, das viele Leute davon abhalten würde, es zu verwenden, insbesondere Anfänger.

(Dies ist eher zu Ihrer Information, Emotion ist eine gute Wahl)

https://github.com/cristianbote/goober (1kB, perf wenig schlechter als Emotionen)

Ich habe noch keine Erfahrung damit, aber ich möchte es eines Tages versuchen.
image
image

@cztomsik Ähnlich wie https://github.com/kuldeepkeshwar/filbert-js, jedoch ohne Unterstützung der JavaScript-Syntax (nur CSS-Vorlagenzeichenfolge)

Hier sind einige Tests, die mit Google Lighthouse zur Zeit bis zur Interaktion durchgeführt wurden:

https://jantimon.github.io/css-framework-performance/

css-lighthouse-scores

Zu Ihrer Information, ich habe einige detaillierte Benchmarks für gestylte Komponenten v5, Emotion v10 und Emotion v11 mit / ohne Babel-Plugin, mit Vanilla-API, CSS-Requisiten-API und gestylter API durchgeführt. Hoffe das hilft der Diskussion!

https://github.com/simnalamburt/css-in-js-benchmark

Haben Sie die neue Welle von CSS-in-JS-Bibliotheken in Betracht gezogen, die stark von atomarer CSS- und Typoskript-Unterstützung abhängen?

Haben Sie die neue Welle von CSS-in-JS-Bibliotheken in Betracht gezogen, die stark von atomarer CSS- und Typoskript-Unterstützung abhängen?

Es ist nicht auf dem Benchmark, aber derzeit ist otion 2 ~ 4 mal langsamer als Emotion. Ich denke, otion hat in der Tat ein ziemlich großes Potenzial und glaube, dass es einen Raum für die Optimierung gibt, aber otion ist noch nicht wirklich bereit für die Produktion.

Die Stiche habe ich allerdings noch nicht getestet. 😃

Was ist mit einer tatsächlichen Null-Laufzeit-Bibliothek? Ich habe niemanden gesehen, der Linaria erwähnt hat .

Ich bin irgendwann über Linaria gestolpert und es gefällt mir wirklich gut. Ich mache mir nur Sorgen, dass die Stile der Dynamik-Requisiten ausschließlich von CSS-Variablen abhängen und IE 11 basierend auf https://github.com/callstack/linaria/issues/445 nicht unterstützt wird. Auch im Vergleich zu styled-components und emotion Die Community ist momentan viel kleiner.

@ TheHolyWaffle
Linaria ist großartig.
Wenn Sie es richtig eingerichtet haben, ist es meiner Meinung nach das Beste aus CSS-in-Js (in Bezug auf die Entwicklererfahrung) und reinem CSS (kann die reine CSS-Leistung nicht übertreffen). Es optimiert sogar (dedupes) und verwendet CSS-Regeln wieder.
Aber Linaria erfordert einen Build- und Bündelungsschritt, der für Anfänger schwierig wäre.

Ich würde gerne Ports für andere CSS-in-JS-Bibliotheken mit ähnlicher API-Oberfläche sehen, z. B. filbert-js / goober

@kuldeepkeshwar Wir werden Sie informieren, sobald wir uns die Adapter für die gestaltete API angesehen haben :)

Wie passt https://compiledcssinjs.com/ in all das? Es scheint ein unglaublich interessanter Ansatz zu sein; Compiled führt auch RFCs für das Projekt aus, was sich als großartig für Open Source und Zusammenarbeit erweist. _Zwinker zwinker_

Ich denke, die Zukunft für das Styling des Webs ist sehr, sehr vielversprechend, und ich hoffe, dass die Material-Benutzeroberfläche ein wesentlicher Bestandteil der Go-to-Lösung für das Styling jeder App ist.

Die Erklärung, wie Compiled funktioniert, kam zu mir:

Diese Art der Transformation ermöglicht es uns, Ihre Komponente an jeden Verbraucher zu liefern, ohne dass dieser seine Werkzeuge konfigurieren / einrichten muss. Einfach importieren und loslegen. Dies ist leistungsstark und vor allem genauso wie das aktuelle CSS in JS-Bibliotheken - mit einem Haken.

_CSS kann nicht zur Laufzeit generiert werden._

Diese einzige Einschränkung öffnet uns viele Türen. Zeitoptimierungen erstellen. Laufzeitgarantien. Leistungsengpässe verschwunden.

In einer anderen Randnotiz möchte ich darauf hinweisen, dass Popularität für ein gutes Projekt nicht viel bedeutet. Ich liebe MUI und die Arbeit, die bisher darin geleistet wurde. Ich finde es auch fantastisch, dass es ein Premiumprodukt geworden ist.
Die Wahl eines 'populären' _Namens_ aus Gründen der Popularität ist jedoch kein vernünftiges Argument.
Ich habe mehrfach gesehen, dass auf Popularität verwiesen wird, und ich mag es sehr, selbst wenn ich bedenke, ob x Menschen x Technologie verwenden - MUI konzentriert sich (in meinen Büchern) auf Leistung, DX und andere Dinge, nur nicht auf Popularität.

MUI hatte nicht immer 60.000 Sterne, es bekam sie, weil es die beste Technologie (oder in der Nähe von) wählte, nicht weil es populäre Technologie wählte.

Wenn die Auswahl auf der Grundlage der Volksabstimmung ein allgemein zugänglicheres Projekt sein soll, sind dies geschäftliche Bedenken und keine möglichen Leistungsverbesserungen. Ein Projekt lebt mit oder ohne Benutzer. Es stirbt mit schlechten Entscheidungen. Ich denke, es gibt so viele Sprüche und das Lesen "es ist nicht populär genug, deshalb ist es eine schlechte Wahl" läutet viele laute Glocken.

Menschen verwenden ein richtiges Produkt, weil es gut ist, nicht weil es beliebte Technologie verwendet. MUI war einmal eine Nische, wurde aber berühmt, obwohl es CSS-in-JS hatte, das übrigens nicht die Volksabstimmung gewann. Es hat nur einige erstaunliche Eigenschaften und hat die richtigen Entscheidungen getroffen, die nicht auf der aktuellen Community basieren, sondern auf dem tatsächlichen DX und der Leistung.

Da diese Nebenbemerkung zur Kenntnis genommen wird, bin ich selbst auf der Seite der Volksabstimmung; Wenn überhaupt, sabotiere ich mich auch. Ich habe keinen persönlichen Vorteil, wenn ich mich für ein weniger beliebtes Produkt entscheide. Ich bin der Meinung, dass Popularität nicht unbedingt berücksichtigt werden sollte, wenn über Revolutionen und Änderungen gesprochen wird. Bitte überdenken Sie einige dieser Optionen basierend auf dem, was sie tatsächlich sind, und nicht auf der Grundlage der aktuellen Beliebtheit der Option.

Zum Abschluss bin ich dankbar für jeden Gedanken und jede Zeit, die in MUI investiert wird. Ich habe in den letzten paar Jahren einige erstaunliche (leider private) Lösungen entwickelt, die allen Standards usw. entsprechen. Es hätte Monate oder Jahre gedauert, diese im Alleingang zu entwickeln! Ich kann meine Wertschätzung nicht so gut beschreiben, dass sie auf dem Papier durchscheinen kann 🙇‍♂️ 🙏 🙇‍♂️

Ich bin gespannt, ob Compiled überhaupt eine Option ist und wie es mit Adaptern und dergleichen funktionieren würde. Ich denke, der kompilierte Ansatz:

Compiled kompiliert Ihr CSS in JS zur Erstellungszeit, indem es Ihren Code statisch analysiert und ihn dann in kompilierte Komponenten umwandelt. Alles, was wir zur Verwendung der Komponente benötigen, ist im JavaScript-Bundle enthalten.

ist ein Pfad, über den man nachdenken muss, wenn man die gesamte Einschränkung für das Kompilieren von "CSS zur Laufzeit" berücksichtigt.

Ich sage dies als Emotionsbetreuer - Kompiliert ist großartig. Oder besser gesagt - es könnte in der Zukunft sein, das ist sehr aufregend, aber es ist noch ziemlich früh im Experimentieren. Ich bezweifle sehr, dass MUI zu diesem Zeitpunkt damit umgehen kann.

Korrigieren Sie mich, wenn ich falsch liege, aber kompiliert impliziert, dass eine Konfiguration vorhanden ist. Dies bedeutet, dass eine Konfigurationsdatei für die MUI auch ohne Verwendung benutzerdefinierter Stile erforderlich ist.

Ich würde es hassen, gezwungen zu sein, eine Konfiguration zu erstellen, nur um MUI zu verwenden. Nebenbei bemerkt: Wäre das nicht schwer in Bootstrappern wie Create React App zu verwenden?

@Andarist Ich stimme vollkommen zu. Ich würde vorschlagen, eine Zusammenarbeit zu beginnen oder zumindest in Betracht zu ziehen, an der Entwicklung der Bibliothek teilzunehmen. Ich bin neugierig, wohin es in Zukunft führen könnte! : eyes: Ich denke, so etwas wie kompiliert - wie Sie sagen - wird in Zukunft großartig sein. Es wäre großartig, wenn mehr großartige Köpfe zusammenkommen würden, um etwas Bemerkenswertes zu machen.

@shilangyu Ich bin nicht sicher, was Sie damit Titelseite von compiled Folgendes zu sagen hat:

Migrieren Sie zu einer Konfigurationsrealität von Null

Die APIs, die wir lieben, sind alle für die Fahrt da - auch CSS-Requisiten und Klassennamen! Unsere Kunden müssen nicht einmal ändern, wie sie unsere Komponenten verbrauchen, und die Null-Konfigurationsgeschichte fortsetzen, die sie nicht benötigen, um ihren Bundler zu konfigurieren, und sie müssen auch keine spezifischen Dinge für das serverseitige Rendern einrichten. Es funktioniert einfach.

Nur der Anfang

Da heute keine Konfiguration mehr verfügbar ist, vergessen wir nicht, wie morgen aussehen könnte. Mit der Möglichkeit der optionalen CSS-Extraktion, der Umwandlung des CSS in eine atomare Form und der Möglichkeit, die CSS-Daten für die Analyse in unserer Codebasis zu verwenden, denken wir an ein aufregendes Morgen.

@ MathiasKandelborg
Ich habe https://compiledcssinjs.com/ durchgesehen. Ist es nicht immer noch Laufzeit css-in-js?
Es erstellt CSS-Klassen zur Erstellungszeit, wendet jedoch diesen Stil (erstellt ein Stiltag mit mit der Erstellungszeit generierten CSS-Klassen) mit dem Tag <CC>...</CC> zur Laufzeit an.
Wenn es so schnell ist wie nur reines CSS, dann ist es wirklich die Zukunft (da es CSS-Variablen verwendet). Danke für das Teilen
Ich frage mich, wie schnell es im Vergleich zu Emotion ist.

Was ist mit einer tatsächlichen Null-Laufzeit-Bibliothek? Ich habe niemanden gesehen, der Linaria erwähnt hat.

Was wir nicht in die Anforderungen aufgenommen haben, ist, dass jede Lösung aus Sicht der Verbraucher von Material-UI nullkonfiguriert sein muss. Wenn ich Null-Laufzeit-Lösungen verstanden habe, generieren sie zur Kompilierungszeit etwas CSS. Muss ich meinen Bundler nicht einrichten, um ihn ordnungsgemäß einzuschließen?

Die Laufzeit ohne Laufzeit ist wahrscheinlich die schnellste Lösung, erfordert jedoch zusätzliche Aufmerksamkeit. Eine Zero-Config-Lösung, die für die Ausführung mit Zero-Runtime konfiguriert werden kann, wäre meiner Meinung nach ideal.

Die Laufzeit ohne Laufzeit ist wahrscheinlich die schnellste Lösung, erfordert jedoch zusätzliche Aufmerksamkeit. Eine Zero-Config-Lösung, die für die Ausführung mit Zero-Runtime konfiguriert werden kann, wäre meiner Meinung nach ideal.

Ich kann nicht wirklich über den aktuellen Status von Compiled sagen, aber ich habe mehrmals mit dem Betreuer darüber gesprochen, und dies ist ungefähr der Plan - die Idee ist, die Unterstützung für Emotion & Styled Components-APIs beizubehalten, sodass die Optimierung des geschriebenen Codes nur eine Frage von sein sollte Ändern der Importe und Einfügen eines Transformations-Plugins oder eines Webpack-Loaders. Es wird sicher nicht den gesamten Code verarbeiten, der möglicherweise geschrieben werden kann (JS ist wild), aber es sollte in der Lage sein, vernünftig geschriebenen Code zu verarbeiten. Wenn es nicht in der Lage sein wird, etwas zu kompilieren. Es wird einfach geworfen - gezwungen, einen Graben zu verwenden oder einen bestimmten Teil des Codes neu zu schreiben, um die statische Analyse zu unterstützen.

Zusammenfassend lässt sich sagen: Wenn Sie sich für 0config Emotion (oder Styled Components) entscheiden, sollte es möglich sein, Compiled in Zukunft als optionale Optimierung anzupassen (wenn das Projekt das hält, was es verspricht).

@ ko-throw Ich denke, es wird zur Erstellungszeit in die gestaltete Komponente kompiliert. Zur Laufzeit werden die Stile aus der Komponente an ihren richtigen Platz verschoben.

Wie sie auf der Webseite sagen:

Alles, was wir zur Verwendung der Komponente benötigen, ist im JavaScript-Bundle enthalten.

Wir nehmen Ihren ursprünglichen Code in seiner ganzen Pracht:

import { styled } from '@compiled/css-in-js';

export const ColoredText = styled.span`
  color: #ff5630;
`;

Und dann in eine kompilierte Komponente umwandeln:

...
...

Dadurch werden die Stile zur Laufzeit an den Kopf des Dokuments verschoben.

Diese Art der Transformation ermöglicht es uns, Ihre Komponente an jeden Verbraucher zu liefern, ohne dass dieser seine Werkzeuge konfigurieren / einrichten muss. Einfach importieren und loslegen. Dies ist leistungsstark und vor allem genauso wie das aktuelle CSS in JS-Bibliotheken - mit einem Haken.

CSS kann zur Laufzeit nicht generiert werden.


Eine Zero-Config-Lösung, die für die Ausführung mit Zero-Runtime konfiguriert werden kann, wäre meiner Meinung nach ideal.

Ich denke du hast den Nagel auf den Kopf getroffen. Es würde sich utopisch anfühlen, plötzlich nur so liebevoll zu träumen .

Es gibt einige Ideen zu erforschen und vielleicht eine Zusammenarbeit zu haben. Einige der Codes und Konzepte sind mir etwas fremd, daher bin ich nicht in der Lage, auf viele Details einzugehen. Hier sind einige Dinge, auf die ich mich freue:

  • Statische Analyse - das ist eine große. Stellen Sie sich vor, Sie erhalten Daten darüber, wie Sie eine Styling-Lösung verwenden, erhalten Empfehlungen basierend auf X-Regeln, Konventionen oder Spezifikationen und lassen sich zeigen, wo Sie optimieren können
  • Null Konfiguration - obwohl ich mehr Freiheit zugunsten von Faulheit priorisieren würde (Installation eines Plugins für x Bundler)
  • CSS-in-JSS zu reinem CSS, wobei Stile zur Kompilierungszeit extrahiert werden, um sie statisch einzuschließen, ohne dass eine Laufzeit erforderlich ist.

Wie sehen Sie die Statistiken zur IE11-Unterstützung? Ich bin sicher, es ist eine absolut praktikable Sache. Edge basiert jetzt auf Chrom, und die meisten Unternehmen sollten den Wechsel vornehmen, wenn MS die Unterstützung für IE endgültig beendet, wenn jedes Betriebssystem, auf dem IE11 installiert wurde, das Ende ihres Unterstützungszyklus erreicht. Es ist in der Tat ein langer Zyklus, aber ich denke, die Betreuer tragen auch dazu bei, Änderungen voranzutreiben, und die Unterstützung für etwas, das im Wesentlichen veraltet ist, scheint es den Menschen zu ermöglichen, zu warten, bis die „Verschiebung“ tatsächlich stattfindet.

Es wäre schön, die Option zu haben, IE11 nicht zu unterstützen. Es ist kein Industriestandard mehr und wird veraltet sein. Es ist eine Frage der Zeit, und die standardmäßige Unterstützung durch erstaunliche Dinge wie MUI hält wahrscheinlich die Verschiebung zurück.

Es wäre schön, die Option zu haben, IE11 nicht zu unterstützen.

Siehe dazu https://github.com/mui-org/material-ui/issues/14420 .

Wir planen nicht, die Unterstützung für IE vollständig einzustellen. Die Standardversion zielt wahrscheinlich nicht auf IE 11 in Version 5 ab, aber wir können keine Lösung auswählen, die in IE 11 überhaupt nicht funktioniert. Oder besser gesagt, es sollte eine Lösung sein, die wir zur Erstellungszeit austauschen und dieselbe produzieren können Ausgabe.

Das macht mich glücklich.

Gibt es einen Code-Mod zum Konvertieren von vorhandenem JSS in Styled / Emotion, frage ich mich?

Hallo, alle miteinander. Ich nutze die Gelegenheit, um in diese Diskussion einzusteigen.

In der aktuellen Version verwendet die Material-Benutzeroberfläche withStyles HOC ohne dynamische Stile (Stil ist eine Funktion, die von Requisiten abhängt), die intern makeStyles . Die Leistung von makeStyles (ohne dynamische Requisiten) ist bemerkenswert und die Material-Benutzeroberfläche könnte sogar schneller sein, wenn sie direkt verwendet wird, anstatt von withStyles , wodurch ein unnötiger Wrapper entsteht.

Ich habe einen Benchmark erstellt, der aus diesem Benchmark besteht , und ihn für Vercel bereitgestellt, damit der gesamte Code mit aktivierten Produktionsflags kompiliert wird. Der Benchmark rendert Karten mit unterschiedlichem CSS in JSS-Bibliotheken. Hier sind die Links:

Für 100 Karten :

Für 500 Karten :

Für 2500 Karten :

Insgesamt sind emotion und styled-components in der Leistung sehr ähnlich. Allerdings scheint makeStyles beim Mounten und erneuten Rendern von 6-8x für Updates insgesamt 2-4x schneller zu sein.

Der Unterschied ist deutlich genug, insbesondere wenn wir auf Geräten mit geringem Stromverbrauch wie unseren Telefonen rendern. Und es gibt viele beschissene Telefone da draußen.

All dies, um zu sagen, dass ich mir Sorgen darüber emotion wird, was die Renderleistung der Material-Benutzeroberfläche und der Websites, die es verwenden, um einen 3-5-fachen Faktor verringert. (Dies ist eigentlich nicht wahr, es hängt von der Komponente ab. Je komplexer es ist, desto geringer ist der Unterschied.)

Einige Fragen und Denkanstöße:

  • Ist der DX den UX-Kompromiss wirklich wert? Sogar der DX ist umstritten, da viele makeStyles bevorzugen
  • Das Problem mit makeStyles hat mit dynamischen Stilen zu tun, die durch die Implementierung einer deterministischen Cache-ID behoben werden können. Derzeit erhält jede Komponenteninstanz eine eigene ID für dynamische Requisiten, auch wenn Requisiten und Ausgabestile identisch sind. Dies führt zu Laufzeit-Overhead, vielen Stil-Tags im Kopf und einer verringerten SSR-Leistung. Scheint durch die Verwendung einer Hashing-Strategie für dynamische Stile korrigierbar zu sein, genau wie es viele andere CSS in JS-Bibliotheken tun. Siehe auch: https://github.com/mui-org/material-ui/pull/16858
  • Gibt es Raum für Verbesserungen bei emotion und styled-components , um näher zu kommen oder sogar besser als makeStyles ?
  • Unterstützt Material UI einen offiziellen JSS-Engine-Adapter, damit Entwickler ihn für mehr Leistung auswählen können?

Ich kann mit einem kleinen Leistungsverlust leben.

Kein Leistungsverlust von 300%, nicht um jeden Preis. 😅

@ Satazor, danke, dass hast . Wir haben vor Beginn dieser Bemühungen einen intensiven Perf-Test durchgeführt. Weitere Informationen finden Sie unter PR https://github.com/mui-org/material-ui/pull/22173 (wir haben dies bei der ListItem-Komponente durchgeführt). Der Perf-Unterschied lag bei Die meisten 10% für das Rendern von x1000-Instanzen im Produktionsmodus .

https://deploy-preview-22173--material-ui.netlify.app/performance/list-raw/

https://deploy-preview-22173--material-ui.netlify.app/performance/list-mui/

https://deploy-preview-22173--material-ui.netlify.app/performance/list-styled/

https://deploy-preview-22173--material-ui.netlify.app/performance/list-styled-wrapper/

Auf dieser Grundlage haben wir uns entschlossen, diesen Unterschied zu ignorieren, da wir Vorteile erhalten würden (dynamische Requisiten aus der Box, gestaltete API, die bereits von einem großen Prozentsatz der Entwickler verwendet wurde usw.). Die gesamte Zusammenfassung finden Sie in der PR Beschreibung :))

Ich bin mir nicht sicher, was auf Ihren Benchmarks passiert, aber 3-5x scheint mir zu viel zu sein. Ich frage mich, warum jemand emotion / styled-compoenents wenn dies der Fall wäre. Wir können es versuchen um zu sehen, wo der Unterschied zwischen den beiden Benchmarks liegt, falls uns etwas fehlt. Außerdem wäre es meiner Meinung nach viel besser, Benchmarks für eine echte MUI-Komponente durchzuführen, damit wir realistischere Zahlen erhalten. Lassen Sie mich wissen, wenn Sie mehr auf dieser Seite erfahren möchten. Die PR, die ich verlinkt habe, ist ein guter Ausgangspunkt.

Danke für die Antwort @mnajdova. Sie haben Recht, dass das Testen einer Mui-Komponente realistischer wäre. Was wahrscheinlich passiert, ist, dass der Mui-Code für die List-Komponenten der vorherrschende Langsamkeitsfaktor ist und der Unterschied zwischen ihnen (~ 30 ms) der tatsächliche Unterschied in der Renderzeit ist, der mit Stilen verbunden ist. Ich werde den Code dieser PR nehmen und ihn dem Benchmark hinzufügen, um die Ergebnisse zu sehen.

Wird das am Ende wichtig sein? Wahrscheinlich nicht, aber es kommt auf die App an. Der Leistungsunterschied zwischen aktuellen und gestalteten Mui-Komponenten nimmt zu, da der Rendering-Code selbst einfacher ist. Als Beispiel erwarte ich größere Unterschiede bei den Symbol- oder Typografiekomponenten, aber geringere Unterschiede bei Karten. Es hängt also wirklich von der App und der Anzahl der Komponenten jedes Typs ab, den die App verwendet.

Dies verringert die Renderleistung der Material-Benutzeroberfläche und der Websites, die sie verwenden, um den 3-5-fachen Faktor.

Sie haben einen Benchmark erstellt, der diesen Faktor aufweist. Daraus folgt nicht, dass jede einzelne Komponente diese Abnahme zeigt. Bitte vermeiden Sie es, zu Schlussfolgerungen zu gelangen, da sich diese irreführenden Informationen aufgrund eines solchen sichtbaren Problems sehr leicht verbreiten.

Mit der devtools-Erweiterung sah ich 140 ms für Mount mit Emotionen und 120 ms für Mount mit makeStyles.

Sie haben einen Benchmark erstellt, der diesen Faktor aufweist. Daraus folgt nicht, dass jede einzelne Komponente diese Abnahme zeigt. Bitte vermeiden Sie es, zu Schlussfolgerungen zu gelangen, da sich diese irreführenden Informationen aufgrund eines solchen sichtbaren Problems sehr leicht verbreiten.

Sie haben Recht, siehe meinen vorherigen Kommentar.

Sie haben einen Benchmark erstellt, der diesen Faktor aufweist. Daraus folgt nicht, dass jede einzelne Komponente diese Abnahme zeigt. Bitte vermeiden Sie es, zu Schlussfolgerungen zu gelangen, da sich diese irreführenden Informationen aufgrund eines solchen sichtbaren Problems sehr leicht verbreiten.

Mit der devtools-Erweiterung sah ich 140 ms für Mount mit Emotionen und 120 ms für Mount mit makeStyles.

Ich habe den Benchmark so aktualisiert, dass actualDuration anstelle von baseDuration wird. Daher sollten jetzt Werte angezeigt werden, die besser mit den Angaben im devtools-Profiler übereinstimmen. Das baseDuration misst die Zeit ohne Memoisierungen, während actualDuration das Gegenteil ist. Bitte beachten Sie, dass sich diese Änderung nur auf die Renderer-Leistung auswirkt. Jetzt sehe ich makeStyles 6-8x schneller für Rerender, was bedeutet, dass das Zwischenspeichern / Auswendiglernen besser ist. Ich erhalte jedoch nicht die Werte, die Sie sehen. Können Sie es mit den aktualisierten Links versuchen?

Screenshot 2020-09-22 092415
Screenshot 2020-09-22 092514

@ Satazor Ich denke nicht, dass Ihre Testfälle gleichwertig sind. Wir sollten gut sein.

Mit ein paar Änderungen können Sie versuchen, das zu verstehen, und das verringert den Leistungsunterschied:

  • Die Montage von Reaktionskomponenten ist mit Kosten verbunden, insbesondere beim Rendern vieler Komponenten. makeStyles verwendet div direkt, während emotions / sc neue Komponenten erstellen. In unserem Tabellen-Benchmark habe ich festgestellt, dass jede Additionskomponente die Basis-Renderzeit hinzufügt. Wenn also 3 Ebenen von Komponenten => x3 sind (oder warum <MenuItem> fast x10 langsamer ist als <li> ).
  • Ihre Demo mit makeStyles erstellt ein einzelnes Stylesheet, Emotion / Sc nicht. Versuchen Sie, ein einzelnes Stylesheet mit CSS-Selektoren zu verwenden, um die Elemente in jedem Kartencontainer auszurichten. Oder machen Sie das Gegenteil und teilen Sie das Haupt-Stylesheet von makeStyles in mehrere auf, eines pro Element.

In der Tat, @oliviertassinari. Es scheint, dass die zukünftige Leistung mit Emotions- / Styled-Komponenten selbst für einfache Komponenten wie Typography , die ich hier implementiert habe, eher im 1,5x-2x-Faktor liegt: https://codesandbox.io/ s / css-in-js-Vergleich-gabelte-lr3sr? file = / src / components / EmotionTypography.js.

Überprüfen Sie den Produktionsaufbau und den Benchmark unter: https://csb-lr3sr-7lp24bj5l.vercel.app/

makeStyles ist beim Mounten 1,5-2x schneller und beim Rendern 3-4x schneller. Dies ist möglicherweise etwas, das Sie im Auge behalten sollten, aber ich denke, dass die Abweichung bei komplexeren Komponenten viel geringer sein wird.

Zusammenfassend bin ich also nicht mehr so ​​besorgt über die Leistung und freue mich darauf zu sehen, wie diese Bemühungen aussehen werden.

@mnajdova Hier ist der Produktions-Build für den List-Test: https://csb-lr3sr-3zi42510w.vercel.app/?components=1000 , kopiert von der von Ihnen erwähnten PR. Link zu Codesandbox: https://codesandbox.io/s/css-in-js-comparison-forked-6s4nl

makeStyles scheint beim Mounten 1,7x schneller und beim erneuten Rendern 2,2x schneller zu sein. Ich bekomme nicht den 10% Unterschied, den Sie sehen. Mache ich etwas falsch?

@satazor Interessant, danke, dass hast . Ich habe diesen Benchmark mit # 22435 verwendet, um die Leistung von zu vergleichen

import Slider from '@material-ui/core/Slider';

vs (Emotion).

import SliderStyled from '@material-ui/lab/SliderStyled';

vs (gestaltete Komponenten).

import SliderStyled from '@material-ui/lab/SliderStyled';

Capture d’écran 2020-09-23 à 17 23 23
Capture d’écran 2020-09-23 à 17 25 07
Capture d’écran 2020-09-23 à 17 23 54

Zu diesem Zeitpunkt ist es schwer zu sagen, warum es langsamer ist. Der Engpass liegt möglicherweise nicht bei den Stilen. Und denken Sie daran, dass ich es im Dev-Modus ausgeführt habe ⚠️!

Ich habe zwei neue Seiten hinzugefügt, um einen Blick auf die Leistung der WIP-Emotionsversion des Sliders zu werfen:

Einmal für die Produktion erstellt, scheinen die Statistiken https://github.com/mui-org/material-ui/issues/22342#issuecomment -697540546 ähnlich zu sein, sie sind ungefähr x1.6 langsamer (aber CSS ist voll dynamisch). Beachten Sie, dass Sie damit die WIP-Emotionsversion spielen können mit:

Capture d’écran 2020-09-23 à 18 56 01

Capture d’écran 2020-09-23 à 18 55 48

Beachten Sie auch, dass wir wissen, dass wir die aktuelle JSS-Version x1.1 schneller machen können, indem wir makeStyles anstelle von withStyles verwenden: # 15023.

@oliviertassinari im Prod-Modus werden die Dinge etwas schneller, aber ich denke, die Unterschiede bleiben dort. Sie können auf Bereitstellen> Vercel auf Code-Sandbox klicken, um die Bereitstellung mit Produktions-Build-Flags schnell durchzuführen.

Wenn ich mir anschaue, wie makeStyles implementiert ist, sehe ich, wie es schneller geht, wenn Sie nur statische Stile verwenden :

  1. Auf jedem Mount wird attach aufgerufen.
  2. Wenn es sich um die erste Instanz dieses Komponententyps handelt, wird stylesCreator.create aufgerufen, was wiederum fn aufruft, das in makeStyles(fn) .
  3. In jeder anderen Instanz wird stylesCreator.create übersprungen, da die Ref-Anzahl> 0 ist.

Für Renderer:

  1. Bei jedem erneuten Rendern wird attach aufgerufen.
  2. Danach wird stylesCreator.create übersprungen, da die Ref-Anzahl> 0 ist, sodass überhaupt keine Arbeit erledigt wird.

Bitte beachten Sie, dass bei Verwendung dynamischer Stile die Blätter hier bei jedem Mount und Renderder aktualisiert worden wären.

Im Gegenteil, styled-components und emotion scheinen unsere Styling-Funktionen auf jeder Komponenteninstanz auszuführen, was zu mehr CPU-Zyklen und Speicher-Gegendruck führt. Ich dachte, sie könnten irgendwie einen Multi-Memoize-Cache basierend auf der Requisiten-Kombination erstellen, aber dies würde voraussetzen, dass die Styling-Funktionen rein sind, was möglicherweise nicht der Fall ist.

     const someContext = useContext(FooContext);

    return <div css={ { paddingTop: someContext.padding(1) } }>;

Wenn meine Annahmen stimmen, wird es sehr schwierig sein, das Leistungsniveau von makeStyles für die Generierung statischer Stile zu erreichen, da die Funktionsweise und das Design der API Optimierungen ermöglichen, die styled oder css API kann nicht.

Ich sehe ein paar mögliche Richtungen, die wir erkunden könnten:

  • In der Beschreibung der ersten Ausgabe haben wir die Leistung nur mit der dynamischen Unterstützung von Material-UI verglichen. Wir könnten einen Eintrag für den statischen Fall hinzufügen (was v4 verwendet). Wir könnten auch ein Argument für statische und dynamische Reaktionen haben. Dies soll uns helfen, den Umfang der verfügbaren Style-Engine-Optionen zu verstehen.
  • Wir können untersuchen, wo der Engpass liegt. Wir könnten uns vorstellen, einen Adapter für jss zu haben, wie wir ihn für gestylte Komponenten haben, und sehen, ob die Leistung besser ist. Mit der dynamischen Version von JSS sollte es viel schlimmer sein, aber wir könnten es mit der statischen Version vergleichen. Vielleicht kommt es von der nicht gestylten Abstraktion.
  • Wir könnten die Verlangsamung als einen Preis betrachten, der es wert ist, ausgegeben zu werden, um dynamische Stile freizuschalten und nicht zu stylen. Wenn Sie eine lange Liste rendern möchten, verwenden Sie Virtualisierung oder verlassen sich auf verschachtelte CSS-Selektoren.
    Emotionen und gestaltete Komponenten haben sich als flexibel erwiesen und sind in der Branche schnell genug, ebenso wie React.

Wenn emotion einen useCss -Haken aufgedeckt hat, wie er in https://github.com/emotion-js/emotion/issues/1321 und https://github.com/emotion- angefordert wurde makeStyles API und folglich die Vorteile von "statischem CSS" beibehalten. Wir würden jedoch überall statisches CSS verwenden, um die Leistung zu steigern, was nicht so "sauber" ist, aber genau das tun wir bereits in Version 4.

Mit der ClassNames API könnten wir derzeit einen Port von withStyles erstellen, der die Vorteile der statischen CSS-Leistung und die gute Leistung von dynamischem CSS, die Emotionen haben, beibehält. Wenn const css = useCss() vorhanden wäre, wäre es unkompliziert, auch einen useStyles API-Port zu erstellen.

Die Hauptvorteile der Beibehaltung der API withStyles + makeStyles die Emotionen unter der Haube verwendet, sind:

  • Die Migration, die das Material durchführen muss, ist praktisch keine, wir müssten nur den Port dieser beiden Funktionen erstellen.
  • Benutzer, die bereits withStyles und makeStyles außerhalb der Material-Benutzeroberfläche verwenden, müssen überhaupt nicht migrieren. Sie würden den Vorteil einer kostenlosen Leistungsverbesserung für dynamisches CSS erhalten.
  • Es ist keine zusätzliche Logik erforderlich, um die CSS-API classes + beizubehalten. Mit styled müssten wir die globalen className s von Hand oder mit einem Util erstellen.
  • In dieser Strategie ist useCss unsere Adapterfunktion für CSS in JS-Lösungen anstelle von styled .
  • Um andere CSS in JS-Lösungen zu unterstützen, müssten sie einen useCss-Hook oder ähnliches bereitstellen. Im Idealfall können wir Webpack- / Babel-Aliasing durchführen, um sie zu wechseln, genau wie styled .

Wir haben das Leistungsproblem unter https://twitter.com/olivtassinari/status/1309247827839680512 weiter untersucht. Ich denke, wir können so weitermachen, wie es ist. Teams, denen die Leistung sehr am Herzen liegt, können sich für die nicht gestalteten Komponenten entscheiden und bieten eine bessere Leistung. Für die anderen, wie die meisten in der Branche, sind Emotionen und gestylte Komponenten gut genug.

  • native: 7,71 ms
  • v5 nicht gestylt: 20,89 ms
  • v4: 29,93 ms
  • v5: 37,37 ms
  • Ameise: 53,48 ms
  • Chakra: 64,67 ms

https://codesandbox.io/s/slider-comparison-forked-jziv6?file=/src/App.js…

Es tut mir leid, dass ich Sie hier so spät in der Diskussion störe, aber ich bin ein bisschen überrascht, dass Sie sich ansehen

Ihre Liste entsprach genau Ihren Anforderungen:

  • Funktioniert Server und Client
  • Volle CSS-Unterstützung, keine Kompromisse bei der Leistung
  • Laufzeitgröße von nur 3 KB (gezippt, ab 12 KB)
  • Vollständige Isolation: Selektoren, Animationen, Keyframes
  • Integriertes CSS-Herstellerpräfix
  • Sehr schnelle, minimale und effiziente Transpilation (siehe unten)
  • Hochleistungs-Laufzeit-CSS-Injection, wenn kein Server-Rendering durchgeführt wird
  • Zukunftssicher: Entspricht dem vom Server renderbaren "Shadow CSS"
  • Unterstützung für Quellkarten
  • Unterstützung für dynamische Stile und Themen
  • CSS-Vorverarbeitung über Plugins

Ich würde darauf achten, dass es sich fast um eine Schatten-CSS-Standard-API handelt . Wenn Sie also das Attribut jsx entfernen, können Sie in Zukunft auf Webkomponenten umsteigen, die übrigens bereits in den normalen Browsern funktionieren.

Ja, ich weiß, dass es möglicherweise nicht das beliebteste ist.
Aber ich möchte nur darauf hinweisen, dass Flash vor einigen Jahren sehr beliebt war.
Aber es ist am Ende ausgetrocknet, da es nicht dem Webstandard entspricht, und wir haben jetzt SVGs.
Nur für den Rekord SVG-Standard war lange vorhanden, als Flash die Branche regierte.
Ich betrachte historische Ereignisse nur als gute Lektionen und würde versuchen, das Muster zu erkennen, dass Popularität der letzte Indikator dafür ist, dass sie kugelsicher, wartbar und zukunftssicher ist.

@mifrej Ich persönlich hatte schlechte Erfahrungen damit: https://github.com/vercel/styled-jsx/issues/142.

Wir haben das Leistungsproblem unter https://twitter.com/olivtassinari/status/1309247827839680512 weiter untersucht. Ich denke, wir können so weitermachen, wie es ist. Teams, denen die Leistung sehr am Herzen liegt, können sich für die nicht gestalteten Komponenten entscheiden und bieten eine bessere Leistung. Für die anderen, wie die meisten in der Branche, sind Emotionen und gestylte Komponenten gut genug.

  • native: 7,71 ms
  • v5 nicht gestylt: 20,89 ms
  • v4: 29,93 ms
  • v5: 37,37 ms
  • Ameise: 53,48 ms
  • Chakra: 64,67 ms

https://codesandbox.io/s/slider-comparison-forked-jziv6?file=/src/App.js…

Hast du die Babel Plugins für Emotion / Styled-Komponenten ausprobiert? Hat es das Timing verändert?

Was würde eine Änderung von JSS für die classes -Stütze bedeuten, die für vorhandene MUI-Komponenten verfügbar ist? Wie würde eine v5-Migration für vorhandene Benutzer aussehen, die diese Requisite umfassend nutzen?

Wir stellen uns vor, dass die Benutzer stattdessen die folgende Syntax verwenden: https://next.material-ui.com/components/slider-styled/#unstyled -slider Die Klassen werden grundsätzlich durch die für jeden Steckplatz in der Komponente verfügbaren Klassenselektoren ersetzt. Sie können sich auch das Anpassungsbeispiel ansehen: https://next.material-ui.com/components/slider-styled/#customized -sliders

Als Vorteil können Sie einfach die Requisiten verwenden und darauf basierende dynamische Stile anwenden.

Wir stellen uns vor, dass die Benutzer stattdessen die folgende Syntax verwenden: https://next.material-ui.com/components/slider-styled/#unstyled -slider Die Klassen werden grundsätzlich durch die für jeden Steckplatz in der Komponente verfügbaren Klassenselektoren ersetzt. Sie können sich auch das Anpassungsbeispiel ansehen: https://next.material-ui.com/components/slider-styled/#customized -sliders

Als Vorteil können Sie einfach die Requisiten verwenden und darauf basierende dynamische Stile anwenden.

Ich liebe diese API! Sehr willkommene Abwechslung, und es scheint wirklich gut mit den Style-Engines zu spielen.

Wenn ich mich richtig erinnere, würde der JSS-Compiler vor v5 diese Klassennamen entstellen, und Sie konnten sie nicht zuverlässig als Ziel festlegen? Aber jetzt scheinen sie für Targeting-Zwecke ausgesetzt zu sein? 🙌 Außerdem gab es ein Problem mit der CSS-Priorität. Und diese Bedenken werden mit diesem neuen Ansatz gelöst? Vielen Dank für die Arbeit an diesem Refactor!

@ConAntonakos genau diese Klassen können sowohl für die nicht gestylte als auch für die gestaltete Version der Komponenten verwendet werden. Die Reihenfolge, in der der Stil aufgerufen wird, stellt sicher, dass die neuen Stile gewinnen, natürlich wenn die Spezifität gleich ist :)

Wenn ich mich richtig erinnere, hat der JSS-Compiler vor v5 diese Klassennamen entstellt, und Sie konnten sie nicht zuverlässig als Ziel festlegen?

Sie könnten sie bereits in Version 4 als Ziel festlegen.

Die Klassen werden grundsätzlich durch die Klassenselektoren ersetzt, die für jeden Steckplatz in der Komponente verfügbar sind.

Werden sie "im Grunde" ersetzt oder tatsächlich ersetzt? Ich dachte, wir haben uns entschlossen, einen Teil der alten API beizubehalten, um die Anzahl der Änderungen zu verringern.

Ich dachte, wir haben uns entschlossen, einen Teil der alten API beizubehalten, um die Anzahl der Änderungen zu verringern.

Wir haben uns entschlossen, dieselbe API für die in der Themenarbeit definierten theme.components.overrides - Overrides auf dieselbe Weise beizubehalten.

Für die Instanzüberschreibungen haben wir jetzt den styled -Ansatz mit den Klassenselektoren, weshalb die classes -Stütze nicht mehr unterstützt wird. Entwickler können dies jetzt flexibler tun.

Entwickler können dies jetzt flexibler tun.

Das klingt nach einem so kleinen Problem, weil es eine Alternative gibt, aber die Migrationskosten dafür sind enorm. Wie sieht der Migrationsplan aus?

Entwickler können die Themenüberschreibungen weiterhin verwenden. Wenn sie nur die Instanzüberschreibungen in ein verschachteltes ThemeProvider sie die definierten Stile überhaupt nicht ändern, da die Struktur zwischen diesen beiden identisch ist (sie ist nicht perfekt) , aber wenn sie ein inkrementelles Upgrade wünschen, ist es ein guter Weg)

Auf der anderen Seite können wir die Klassenstütze immer noch problemlos unterstützen, aber in diesem Fall können wir nicht garantieren, ob die Kombination aus Klassen + Stil für dieselbe Komponente verwendet wird, die man gewinnen sollte. Sollten wir die Unterstützung von Klassen zumindest für die gestaltete Version der Komponenten zurückportieren?

Möglicherweise habe ich dies auf dem Weg durch diesen Thread verpasst - eine weitere verwandte Frage zu meiner classes -Frage. Welche Art von "Korrektheit" kann es geben?

Zum Beispiel habe ich das Schieberegler-Beispiel bearbeitet:

const StyledSlider = styled(SliderUnstyled)`
  & .MuiSlider-raill {
    display: block;
    position: absolute;
    width: 100%;
    height: 2px;
    border-radius: 1px;
    background-color: currentColor;
    opacity: 0.38;
  }
)

Sie werden feststellen, dass ich versehentlich MuiSlider-rail falsch geschrieben habe. Früher gab es mit classes so etwas wie classes.rail , und wenn ich die Eigenschaft falsch geschrieben habe, wurde eine Laufzeitwarnung angezeigt, dass classes.raill im Stylesheet nicht vorhanden ist. Ich glaube, das Thema hatte das gleiche Verhalten?

Die Vorteile der classes API, die ich mir vorstellen kann:

  1. Vorteil gegenüber den globalen CSS-Selektoren, die zwischen untergeordneten Elementen auftreten: z. B. In .css-e7ylz8 .MuiTreeItem-group . Sie können nicht garantieren, dass die Komponente den Stil nicht auf eine untergeordnete Komponente anwendet (nicht den erwarteten Effekt, eine Überraschung!). Wahrscheinlich in Ordnung für unsere Komponenten, da wir vorsichtig sein werden.
  2. Machen Sie den Umgang mit Portalen zum Kinderspiel: https://material-ui.com/guides/interoperability/#portals. Zum Stylen des Tooltips müssen wir die Popper-Komponente formatieren, nicht die Wurzel, wie wir es mit dem Slider getan haben.
  3. Die Syntax $styleRule warnt, wenn die Stilregel undefiniert ist.
  4. Ermöglichen das Anpassen der verwendeten Klassennamen. Die aktuelle Lösung besteht darin, die componentsProps Requisite zu verwenden. Wir führen die Klassennamen zusammen.

Es gibt eine alternative Welt, in der wir:

ein. Lassen Sie 1. und 3. mit gestalteten Komponentenselektoren lösen.
b. Stellen Sie die API classes zur Abwärtskompatibilität bereit.
c. Um eine zu bekommen. und B. Wenn wir arbeiten, müssten wir reduzieren, wie die Stile der Komponente intern geschrieben werden. x-gestaltete Komponente anstelle von 1 gestylter Wurzel. Aber ⚠️ mit der perfekten Implikation.

Müssen wir das wirklich tun?


Ich habe mir die Geschichte der classes Requisite von jQuery UI angesehen. Ich konnte zwei Probleme finden: https://bugs.jqueryui.com/ticket/7053 , https://bugs.jqueryui.com/ticket/8928 und das anfängliche Commit: https://github.com/jquery/jquery- ui / commit / c192d4086d9bbaf09d5f870857af30c60a427e22.

Wir stellen uns vor, dass die Benutzer stattdessen die folgende Syntax verwenden: https://next.material-ui.com/components/slider-styled/#unstyled -slider Die Klassen werden grundsätzlich durch die für jeden Steckplatz in der Komponente verfügbaren Klassenselektoren ersetzt. Sie können sich auch das Anpassungsbeispiel ansehen: https://next.material-ui.com/components/slider-styled/#customized -sliders

Als Vorteil können Sie einfach die Requisiten verwenden und darauf basierende dynamische Stile anwenden.

Wow, das ist das Beste, was es je gab.
Unstyled oder Headless-Komponenten werden das Beste für die Anpassung sein (einer der Kritiker über Mui, denke ich).
Dies ist keine Kleinigkeit, um imo zu beheben, sondern ein hude plus für MUI.

PS: Ich erinnere mich, dass es in der Vergangenheit schwierig war, einige Komponenten anzupassen
PS2: Hast du dir https://github.com/modulz/stitches angesehen ?

Sie werden feststellen, dass ich die MuiSlider-Schiene versehentlich falsch geschrieben habe. Früher gab es bei Klassen so etwas wie classes.rail, und wenn ich die Eigenschaft falsch schrieb, erhielt ich eine Laufzeitwarnung, dass classes.raill im Stylesheet nicht vorhanden ist. Ich glaube, das Thema hatte das gleiche Verhalten?

@ianschmitz Zusätzlich zu der Option @oliviertassinari , die für die Verwendung der gestalteten Komponentenselektoren vorgeschlagen wurde, haben wir eine weitere Option, nämlich das

import { sliderClasses } from '@material-ui/core/Slider';

const StyledSlider = styled(SliderUnstyled)`
  & .${sliderClasses.rail} {
    display: block;
    position: absolute;
    width: 100%;
    height: 2px;
    border-radius: 1px;
    background-color: currentColor;
    opacity: 0.38;
  }
)

Es ist nicht dasselbe wie die Laufzeitwarnung classes.rail , sollte aber gegen Rechtschreibfehler in den Klassen helfen.

@mnajdova Wir könnten auch ein Eslint-Plugin in Betracht ziehen.

In Bezug auf die Unterstützung der classes -Stütze müssen wir Komponenten für jeden Teil (Steckplatz) der Kernkomponente erstellen, damit wir dies zuverlässig tun können. Für Slider müssten wir beispielsweise Komponenten für die Schiene, das Gleis, die Markierung, das Markierungsetikett, den Daumen und das Wertetikett erstellen. Auf diese Weise können wir die Stile direkt für diese Komponenten angeben, anstatt Klassen zur Erhöhung der Spezifität zu verwenden. Diese Änderungen finden Sie in dieser PR - https://github.com/mui-org/material-ui/pull/22893

Mit diesen Änderungen haben wir eine Codesandbox erstellt, die die Leistung dieser neuen aktualisierten Slider-Komponente im Vergleich zu der v4-Version im nativen Stil und im nicht gestylten Format sowie zwei anderen wettbewerbsfähigen Bibliotheken vergleichen kann - https://codesandbox.io/s/ Schieberegler-Vergleich-mit-mehreren-Komponenten-2tytc? file = / package.json

Wenn wir diese Leistung mit der Leistung vergleichen, nur eine Komponente zu haben und die Klassenselektoren für die Teile davon zu verwenden - https://codesandbox.io/s/slider-comparison-forked-jziv6?file=/src/App.js Wir werden feststellen, dass das Hinzufügen von Komponenten pro Steckplatz eine Leistungsverschlechterung von 20% aufweist 😢

Produktionsversionen:

Um ehrlich zu sein, weiß ich derzeit nicht, ob es besser ist, diese Abwärtskompatibilität hinzuzufügen oder nicht.

Sind dies echte Anwendungsfälle für die Unterstützung von classes oder nur zur Erleichterung des Upgrades?
Ist es in Ordnung, eine 20% ige Leistungsverschlechterung nur zur Erleichterung des Migrationspfads zu haben?
Gibt es eine Alternative, die wir nicht sehen können und die uns helfen würde, beides zu tun, ohne die Perf-Kosten zu bezahlen?

@ianschmitz @ eps1lon @oliviertassinari und andere :)

Solange wir mit TypeScript Themen und Stile definieren und verwenden können, würde es mir nichts ausmachen, Zeit mit der Migration zu verbringen, verglichen mit dem Verlust von 20% Perf

Ich bin im Allgemeinen neugierig und vergebe mir, wenn ich das zugrunde liegende Design nicht verstehe, aber classes eine API für JSS war? Wenn das API-Design von JSS zu gestalteten Komponenten wechselt, ist es sinnvoll, weiterhin classes ?

Sind dies echte Anwendungsfälle für die Unterstützung von classes oder nur zur Erleichterung des Upgrades?
Ist es in Ordnung, eine 20% ige Leistungsverschlechterung nur zur Erleichterung des Migrationspfads zu haben?
Gibt es eine Alternative, die wir nicht sehen können und die uns helfen würde, beides zu tun, ohne die Perf-Kosten zu bezahlen?

Entschuldigung, wenn ich mit der vorgeschlagenen API etwas verpasst habe, aber IMO ist der Anwendungsfall, den ich in unserer Organisation am häufigsten sehe, die Abstraktion des zugrunde liegenden Styling-Systems, das von MUI verwendet wird. Ja, ich denke, classes ist eine Art "API für JSS", wie @ConAntonakos erwähnte, aber für den Verbraucher war es egal. Als Verbraucher könnte ich die bevorzugte CSS-Technologie verwenden (gibt es heute Einschränkungen bei classes ?). Wir haben eine Reihe von Produkten mit einer Vielzahl von:

  • Vanilla CSS-Dateien
  • SCSS
  • JSS

abhängig von den Bedürfnissen und Vorlieben dieser Teams.

Das Exportieren der Klassennamen hilft, wenn Sie eine CSS-in-JS-Variante verwenden. Aber was denken Sie für diejenigen, die dies nicht tun?

RE. 20% perf, ich stimme zu, dass dies wahrscheinlich kein akzeptabler Kompromiss ist. Am Ende des Tages solltet ihr das tun, was für die Mehrheit der Community am besten ist. Ich biete nur meine Gedanken an 😄

Ein Wunsch, den ich nie bekam, war, dass Material-UI kompatibel mit reaktionsnativen Komponenten wäre. Viele Projekte sind heutzutage plattformübergreifend und eine einheitliche Styling-Lösung bietet viele Vorteile für plattformübergreifende Komponenten. Am Ende rollten wir unsere eigene mit material-ui auf der Webseite und reag-native-paper auf der nativen Seite und standardisierten auf der material-ui-API. Es würde mich interessieren, ob diese neue Styling-Lösung die Verwendung von (einigen / allen) Material-UI-Komponenten auf React-Native möglich macht. Alle Fensterreferenzen in Komponenten wären natürlich ein Blocker, aber das Styling selbst unterstützt auch native, nicht wahr?

@mschipperheyn React -Native ist bisher kein Ziel. Es sind + 5% des Nutzungspotenzials (1 Monat Wachstum) und + 50% mehr Aufwand (eine Vermutung). Die Opportunitätskosten sind sehr hoch, ohne dass eine offensichtliche Richtung für die Monetarisierung erkennbar ist (außerhalb des Modells von Ionic). Denken Sie auch daran, dass das Flattern einen großen Teil des Publikums erfasst hat , der auf native Ziele reagiert.

Gibt es eine Lösung für dieses Problem, nachdem sich Version 5 in der Alpha-Version befindet? Basiert die Styling-Lösung insbesondere noch auf JSS? Wir haben erhebliche Leistungsprobleme im Zusammenhang mit JSS festgestellt und sind daher gespannt auf eine neue Lösung.

@zzzev Dies ist an sich kein Problem. Es ist ein RFC-Thread (Request for Comments).

Ich bin neugierig, über welche wesentlichen Leistungsprobleme Sie sprechen und wie ein Wechsel von JSS dies verbessern würde. Ich sehe es so, dass bei Leistungsproblemen wahrscheinlich nicht die Stile, sondern die Art und Weise, wie sie implementiert werden, das gleiche Ergebnis erzielt werden kann, wenn die Stile auf andere Weise mit weniger Rechenleistung geschrieben werden.

Zumindest kann ich mich nicht darauf beziehen, wie ein Wechsel von JSS zu Emotion (der in diesem Thread gezeigt wird, um höchstwahrscheinlich einen Leistungsabfall zu haben) irgendetwas verbessern würde.

Mein Verständnis ist, dass Emotionen die Leistung statischer Stile und die Leistung perfekter dynamischer Stile leicht beeinträchtigen - aber vielleicht stimmt das nicht ganz? Es gibt viele verschiedene Zahlen in diesem Thread und es ist schwierig, ein Bild der Leistung zu erstellen (und es hängt natürlich stark von der Situation eines Einzelnen ab).

Wenn Sie sagen, wir sollten die Stile anders schreiben, meinen Sie damit, dynamische Stile zu vermeiden? Oder gibt es andere Best Practices, die wir in Betracht ziehen sollten?

@zzzev Richtig im ersten Teil, nicht ganz im zweiten (es sei denn, Sie rechnen als unendlichen Leistungsgewinn. von nicht unterstützt zu unterstützt 🙂).

Emotion ermöglicht die Unterstützung dynamischer Stile auf Kosten einer moderat langsameren Leistung für statische Stile.

Ich bin verwirrt; Gibt es in den aktuellen / v4 makeStyles keine dynamischen Stile? zB dieses Muster

Ich bin verwirrt; Gibt es in den aktuellen / v4 makeStyles keine dynamischen Stile? zB dieses Muster

Es gibt aber ein großes bekanntes Perf-Problem. Mein Team bleibt weit weg Geldautomat

Ich hasse es einfach, Komponenten zu gestalten
jss ist gut, aber es gibt ein paar Probleme beim Debuggen, der Leistung und immer noch einige Fehler, die noch nicht behoben sind, wie z. B. verschachtelt wie &:after

Es ist mein Paketaufbau für React-Native und React-Native-Web
https://www.npmjs.com/package/@material-native-ui/theme -provider

Ich würde so etwas mögen (es baut auf RN und RNW auf)

Gibt es also eine Schlussfolgerung zu der empfohlenen Stillösung für Material UI v5? Es scheint, dass die Absicht besteht, sich von JSS zu entfernen, auf dem @material-ui/styles derzeit aufgebaut ist. Oder wird @material-ui/styles überarbeitet, um stattdessen auf anderen Styling-Lösungen wie styled-components aufzubauen?

Gibt es also eine Schlussfolgerung zu der empfohlenen Stillösung für Material UI v5? Es scheint, dass die Absicht besteht, sich von JSS zu entfernen, auf dem @ material-ui / styles derzeit aufgebaut ist. Oder @ material-ui / styles wird überarbeitet, um stattdessen auf anderen Styling-Lösungen wie Styled-Components aufzubauen?

@ matthewkwong2 wir würden das @material-ui/styles -Paket nicht in die neue gestaltete Engine übernehmen, es wird weiterhin jss unterstützen. In Version 5 wird es auf den Rest der Codebasis isoliert, und wir planen, es in Version 6 zu entfernen, um den Übergang zur neuen Styling-Engine zu erleichtern.

Für v5 werden wir neue Beat-Praktiken in Bezug auf die Styling-Lösung haben, wie das sx prop und das styled Dienstprogramm. Wir arbeiten noch an der Dokumentation dazu.

Auch die Themenüberschreibungen und -varianten werden in Version 5 weiterhin unterstützt.

Für v5 werden wir neue Beat-Praktiken in Bezug auf die Styling-Lösung haben, wie die sx-Requisite und das gestylte Dienstprogramm. Wir arbeiten noch an der Dokumentation dazu.
Auch die Themenüberschreibungen und -varianten werden in Version 5 weiterhin unterstützt.

Wenn ich das richtig verstehe, wird empfohlen, für das Styling einzelner Komponenten sx oder styled anstelle von makeStyles .

Aber was ist mit dem Thema (dh createMuiTheme )? Ich glaube, dass dieser Teil auch auf JSS aufgebaut ist, oder? Was wäre die empfohlene Methode, um jetzt ein Thema zu erstellen (dh mit dem Hauptzweck, globale Stile zu definieren)?

Wir behalten weiterhin die gleiche Struktur für die Erstellung des Themas bei. Wir erwarten lediglich, dass die Werte für die Komponentenüberschreibungen und -varianten der Syntax für Emotions- / Stilkomponenten folgen. Es gibt keine Änderungen bei der Erstellung des Themas. Die API ist genau dieselbe. Der gleiche Themenkontext wird auch für die neue gestaltete Engine wiederverwendet. Ist das bei matthewkwong2 sinnvoll ?

@mschipperheyn React -Native ist bisher kein Ziel. Es sind + 5% des Nutzungspotenzials (1 Monat Wachstum) und + 50% mehr Aufwand (eine Vermutung). Die Opportunitätskosten sind sehr hoch. Denken Sie auch daran, dass das Flattern einen großen Teil des Publikums erfasst hat , der auf native Ziele reagiert.

Ich möchte uns nicht zu sehr auf eine Tangente einlassen, aber ich möchte einige dieser Gründe zurückdrängen.

  • In der Vergangenheit war Material Design beim Erstellen von RN-Apps eines der schwierigsten Dinge. Tatsächlich war es ein ausreichend großes Problem, das möglicherweise entscheiden konnte, ob eine mobile App erstellt werden sollte. Ich höre, es ist ein bisschen besser mit einer vielversprechenden neuen Bibliothek. Aber ich bezweifle, dass es so vielversprechend ist, wie es wäre, wenn MUI in der Mischung wäre. Vielleicht bin ich es nur, aber ich konnte sehen, dass eine plattformübergreifende MUI die Nutzung von RN tatsächlich steigert. Ich weiß, dass es nur ein kleiner Teil der Nutzung von React-Dom ist, aber das Web ist enorm und React-Dom dominiert moderne Web-Frameworks . Selbst wenn die reaktionsnationale Nutzung relativ gering ist, kann dies eine ganze Reihe von Personen sein, die sie absolut nutzen würden. Eine Umfrage unter aktuellen MUI-Benutzern wäre wahrscheinlich eine bessere Metrik als npm-Statistiken.
  • Ich weiß, dass ich nicht auf dem Laufenden bin, aber ich kaufe Flutter nicht ganz, um React Native zu übernehmen. Dieser Verkehrsvergleich ist kein guter Vergleich. Es wird von so vielen verwirrenden Faktoren beeinflusst (Flutter ist neuer, so dass mehr Leute RN bereits kennen und nicht auf die Dokumentation verweisen müssen; Flatters Dokumentation könnte nützlicher sein, wenn sie erneut auf den zunehmenden Datenverkehr verweist; stattdessen zur Expo). Dieser etwas fehlerhafte Google Trends-Vergleich ist fast ein besseres Maß und ziemlich gleichmäßig. Ich persönlich weiß, dass Flutter ein paar Hard Deal Breaker hatte und RN für das nächste Mal, wenn ein Kunde sagt, dass er eine mobile App möchte, noch vielversprechender ist.
  • JSS war eines der größten Probleme (möglicherweise sogar das größte) bei der Funktionsweise von MUI mit React Native. Ich weiß, dass es noch einige komplizierende Faktoren geben wird, aber meiner Meinung nach hat der Wechsel zu Emotionen wahrscheinlich 2/3 der Schwierigkeit beseitigt, MUI zumindest experimentell in RN zum Laufen zu bringen.

Der Wechsel zu Emotionen hat wahrscheinlich 2/3 der Schwierigkeiten beseitigt, MUI in RN zum Laufen zu bringen

Wir freuen uns auf Ihren POC 😄

Wir freuen uns auf Ihren POC 😄

Ich würde gerne damit herumspielen, wenn ich eine Chance habe. Aber die Leute machen sich im Allgemeinen nicht die Mühe, POCs für Dinge zu erstellen, für die Betreuer ein Desinteresse zeigen. Es macht keinen Sinn, etwas aufzubauen, wenn die aktuelle Atmosphäre so ist, dass es wahrscheinlich einfach verlassen wird. Deshalb möchte ich mich davon abhalten, den Wert von RN oder den Wert von RN als eine Möglichkeit für die Zukunft abzulehnen.

Zwei Fragen:

  1. Können Sie die neue Styling-Lösung ohne HOCs verwenden? Ich liebe die React-Hook-API, über die MUI derzeit verfügt ... Ich bin mir nicht sicher, ob die gestaltete Syntax auch ein HOC unter der Haube ist, aber das würde die Bemühungen (so ziemlich überall in React-Bibliotheken) übertreffen, sich von HOCs zu entfernen.
  2. Wird die classes -Stütze, die die meisten Komponenten noch unterstützen, unterstützt (dies würde volle Flexibilität bei der Verwendung von Styling-Lösungen für Benutzer bieten)?

Das fast-refresh ist in der create-react-app v4 standardmäßig aktiviert. sollten wir als neue Anforderung Unterstützung für die schnelle Aktualisierung hinzufügen?

Probieren Sie es mit Gatsby aus. Wenn ich import { Link } from '@material-ui/core' mache,

Can't resolve '@emotion/core' in 'node_modules/@material-ui/styled-engine'
File: node_modules/@material-ui/styled-engine/index.js

Can't resolve '@emotion/styled' in '/node_modules/@material-ui/styled-engine'
File: node_modules/@material-ui/styled-engine/index.js

Bei Änderung auf import Link from '@material-ui/core/Link' Problem weg.

Wenn ich @emotion/styled @emotion/core installiere,

'@ Emotion / reagiere' in '/ node_modules / @ emotions / styled / dist' kann nicht aufgelöst werden.

Dann installiere ich @emotion/react .

Ein Laufzeitfehler tritt auf.

Error: The `@emotion/core` package has been renamed to `@emotion/react`. Please import it like this `import { jsx } from '@emotion/react'`.
./node_modules/@emotion/core/dist/emotion-core.cjs.dev.js
node_modules/@emotion/core/dist/emotion-core.cjs.dev.js:3

Beteiligte Paketversionen:

    "@emotion/core": "^11.0.0",
    "@emotion/react": "^11.0.0",
    "@emotion/styled": "^11.0.0",
    "@material-ui/core": "^5.0.0-alpha.15",
    "@material-ui/lab": "^5.0.0-alpha.15",

Installieren Sie v10-Versionen von Emotion-Paketen

Oh 11 ist jetzt die "neueste" Version, daher denke ich, dass ich das aktualisieren oder dokumentieren muss

Oh 11 ist jetzt die "neueste" Version, daher denke ich, dass ich das aktualisieren oder dokumentieren muss

Wir haben es über Versionsbereiche in peerDependencies dokumentiert. Wir haben es in der Installationsanleitung nicht explizit erwähnt, da wir planen, es bald auf Version 11 zu aktualisieren.

Freundliche Erinnerung daran, dass dies ein Alpha und eine Emotion 11 ist, die nur wenige Tage alt ist. Als Early Adopter sollten Sie mit rauen Kanten rechnen.

Hallo allerseits, ich bin neu hier und habe mir Material-UI-CSS-Lösungen angesehen und bin auf dieses Problem gestoßen.
Wenn ich nur meine 2 Cent dafür gebe, möchte ich Linaria https://github.com/callstack/linaria vorschlagen
Es ist eine Null-Laufzeitbibliothek mit CSS-Extraktion und CSS-Variablen als React-Requisiten.

Hoffe das hilft bei diesem RFC 😄.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

anthony-dandrea picture anthony-dandrea  ·  3Kommentare

reflog picture reflog  ·  3Kommentare

mb-copart picture mb-copart  ·  3Kommentare

FranBran picture FranBran  ·  3Kommentare

revskill10 picture revskill10  ·  3Kommentare