Generic First CSS: Neues Denken bei Mobile First

Veröffentlicht: 2022-03-10
Kurzzusammenfassung ↬ Mit dem Aufkommen von responsivem Webdesign und dem Mobile-First-Ansatz ist es sieben wunderbare Jahre her, dass uns neue Konzepte gezwungen haben, die Art und Weise, wie wir CSS schreiben, auf der Basisebene anzupassen. Nun, ich habe nichts allzu Bahnbrechendes zu bieten, aber ich habe eine kleine Überraschung. Siehe: Generisches erstes CSS.

Ich denke, man kann mit Sicherheit sagen, dass Ethan Marcottes Responsive Web Design eine willkommene Offenbarung für Webentwickler auf der ganzen Welt war. Es löste eine ganz neue Welle des Designdenkens und wunderbare neue Front-End-Techniken aus. Auch die Herrschaft der oft verachteten m-Punkt-Websites war vorbei. In derselben Zeit und fast ebenso einflussreich war Luke Wroblewskis Mobile-First-Methodik – eine solide Verbesserung, die auf Marcottes beeindruckenden Grundlagen aufbaute.

Diese Techniken bilden die Grundlage für das Leben der meisten Webentwickler und sie haben uns gute Dienste geleistet, aber leider ändern sich die Zeiten und Entwickler wiederholen sich ständig. Wenn wir die Effizienz unserer Methoden steigern und die Projektanforderungen komplexer werden, entstehen neue Frustrationen.

Die Reise zum ersten Generikum

Ich kann nicht genau sagen, was mich dazu gebracht hat, die Art und Weise, wie ich mein CSS schreibe, zu ändern, weil es für mich wirklich eine natürliche Entwicklung war, die fast unbewusst geschah. Rückblickend denke ich, dass es eher ein Nebenprodukt der Entwicklungsumgebung war, in der ich arbeitete. Das Team, mit dem ich zusammengearbeitet habe, hatte einen netten SCSS-Workflow mit einem raffinierten kleinen Mixin zum einfachen Hinzufügen von Haltepunkten in unseren CSS-Deklarationen. Sie verwenden wahrscheinlich eine ähnliche Technik.

Dieses wundervolle kleine SCSS-Mixin machte es plötzlich einfach, supergranulare Medienabfragen zu schreiben. Nehmen Sie einen hypothetischen Biografieblock, der ungefähr so ​​​​aussieht:

 .bio { display: block; width: 100%; background-color: #ece9e9; padding: 20px; margin: 20px 0; @include media('>=small') { max-width: 400px; background-color: white; margin: 20px auto; } @include media('>=medium') { max-width: 600px; padding: 30px; margin: 30px auto; } @include media('>=large') { max-width: 800px; padding: 40px; margin: 40px auto; } @include media('>=huge') { max-width: 1000px; padding: 50px; margin: 50px auto; } }

Abb.1. Typisches Mobile First mit kaskadierenden Medienabfragen

Das funktioniert gut – ich habe in der Vergangenheit viele CSS dieser Art geschrieben. Eines Tages dämmerte mir jedoch, dass das Überschreiben von CSS-Deklarationen bei zunehmender Gerätebreite einfach keinen Sinn machte. Warum eine CSS-Eigenschaft deklarieren, damit sie nur in der folgenden Deklaration überschrieben wird?

Mehr nach dem Sprung! Lesen Sie unten weiter ↓

Dies hat mich dazu veranlasst, mit dem Schreiben von unterteilten Medienabfragen zu beginnen, im Gegensatz zu dem häufigeren Ansatz von Medienabfragen, die nach oben (oder unten) kaskadieren, wie im Beispiel in Abb. 1.

Anstatt Medienabfragen zu schreiben, die mit zunehmender Bildschirmgröße nach oben kaskadieren, habe ich damit begonnen, gezielte Medienabfragen zu erstellen, die Stile bei gewünschten Bildschirmbreiten einkapseln. Das Media-Query-Mixin würde hier wirklich zur Geltung kommen. Jetzt sehen meine SCSS-Medienabfragen so aus:

 .bio { display: block; width: 100%; padding: 20px; margin: 20px 0; @include media('>=small', ' < medium') { max-width: 400px; margin: 20px auto; } @include media('>=medium', ' < large') { max-width: 600px; padding: 30px; margin: 30px auto; } @include media('>=large', ' < huge') { max-width: 800px; padding: 40px; margin: 40px auto; } @include media('>=huge') { max-width: 1000px; padding: 50px; margin: 50px auto; } }

Abb.2. Ein Beispiel für unterteilte Medienabfragen

Dieser neue Ansatz fühlte sich für mich einfach intuitiver an, er reduzierte das Zurücksetzen von Stilen vom vorherigen Haltepunkt und machte das CSS leichter lesbar. Noch wichtiger war, dass die Medienanfragen auf signifikantere Weise selbstdokumentierend wurden.

Ich war immer noch nicht 100% zufrieden mit dem Obigen, aber es schien, als gäbe es noch ein großes Problem zu lösen.

Das Problem mit Mobile First

Das Problem mit Mobile First ist, dass Sie per Definition höchstwahrscheinlich Mobile-First-Stile in nachfolgenden Medienabfragen überschreiben müssen. Das fühlt sich ein bisschen wie ein Anti-Pattern an.

Also – für mich – lag die Antwort auf der Hand: Lassen Sie uns die Idee der Unterteilung von Medienanfragen zu ihrem logischen Abschluss bringen – wir werden auch die mobilspezifischen Stile in ihre ganz eigenen Medienanfragen untergliedern. Ich weiß, ich weiß, das geht gegen die allgemeine Konvention, die wir im Laufe der Jahre gelernt haben. „Mobile First“ ist so allgegenwärtig, dass es normalerweise eine der „Fähigkeiten“-Fragen ist, die ein Personalchef stellen wird. Also muss doch jede Alternative falsch sein, oder? Dies ist normalerweise der Teil, an dem die Leute den Kopf schütteln, während sie immer und immer wieder Mobile First sagen.

Okay, also werden wir das Mobile-First-Dogma durchbrechen und alle unsere Stile in die relevanten Medienanfragen unterteilen. Was uns jetzt bleibt, sind reine generische Stile, die in einem CSS-Selektor deklariert sind, wobei alle anderen gerätespezifischen Stile in Medienabfragen eingekapselt sind, die nur für die relevanten Bildschirmabmessungen gelten. Wir haben jetzt Generic First CSS :

 .bio { display: block; width: 100%; @include media('>=0', ' < small') { padding: 20px; margin: 20px 0; } @include media('>=small', ' < medium') { max-width: 400px; margin: 20px auto; } @include media('>=medium', ' < large') { max-width: 600px; padding: 30px; margin: 30px auto; } @include media('>=large', ' < huge') { max-width: 800px; padding: 40px; margin: 40px auto; } @include media('>=huge') { max-width: 1000px; padding: 50px; margin: 50px auto; } }

Abb. 3. Ein Beispiel für Generic First CSS

Ja, es gibt etwas mehr Medienabfragen, aber ich sehe das als Vorteil, jeder Entwickler kann sich jetzt dieses CSS ansehen und genau sehen, welche Stile bei jeder einzelnen Bildschirmgröße angewendet werden, ohne den kognitiven Aufwand, Medien auseinandernehmen zu müssen. Abfragespezifität.

Dies kann großartig für Personen sein, die mit der Codebasis nicht vertraut sind, oder sogar für Sie!

Wann man nicht aufteilen sollte

Es gibt immer noch Zeiten, in denen die Unterteilung von Medienabfragen eine Belastung darstellt, und in einigen Fällen ist eine gute alte >= Medienabfrage in Ordnung. Denken Sie daran, dass wir nur versuchen, das Überschreiben von Eigenschaften zu vermeiden.

Dev-Tool Bliss

Eine wichtige unbeabsichtigte Folge des Schreibens von kompartimentiertem Generic First CSS ist die Erfahrung, die Sie aus dem Style-Panel Ihres Entwicklertools ziehen werden. Ohne die Medienabfragekaskade haben Sie jetzt einen klareren Überblick darüber, welche Stile angewendet werden – Sie haben kein Stilfenster voller durchgestrichener Deklarationen von überschriebenen Medienabfrageregeln – Das Rauschen ist weg! Das ist – für mich – einer der größten Vorteile der Generic-First-CSS-Technik. Es bringt ein wenig mehr Vernunft in das CSS-Debugging-Erlebnis, und das ist Gold wert. Dank mir später.

Vorher-Nachher-Screenshot, der zeigt, wie sich der generische erste CSS-Ansatz auf das Style-Panel der Chrome-Entwicklungstools auswirkt.
Abb.4. Wie generisch zuerst, unterteiltes CSS dazu beitragen kann, Freude und Vernunft in Ihre Entwicklungskonsole zu bringen. (Große Vorschau)

Auswirkungen auf die Leistung

All diese Vorteile von Generic First CSS klingen also ziemlich gut, aber ich denke, es gibt eine letzte Schlüsselfrage, die meiner Meinung nach angegangen werden muss. Es geht um das Thema Leistungsoptimierung. Jetzt weiß ich es noch nicht genau, aber ich habe eine Ahnung, dass vollständig unterteilte Medienabfragen einen leichten Leistungsvorteil haben können.

Browser führen eine Rendering-Aufgabe aus, die als berechnete Stilberechnung bezeichnet wird. Auf diese Weise berechnet der Browser, welche Stile zu einem bestimmten Zeitpunkt auf ein Element angewendet werden müssen. Diese Aufgabe wird immer beim ersten Laden der Seite ausgeführt, kann aber auch ausgeführt werden, wenn sich der Seiteninhalt ändert oder wenn andere Browseraktionen stattfinden. Jeder Schub, den Sie der Geschwindigkeit des Prozesses geben können, ist großartig für das anfängliche Laden der Seite und könnte sich auf den Lebenszyklus der Seiten Ihrer Website auswirken.

Zurück zum generischen ersten CSS: Gibt es Leistungsprobleme im Zusammenhang mit dem Browser, der die CSS-Spezifität einer Vielzahl von kaskadierenden Medienabfragen ermitteln muss?

Um dies zu beantworten, habe ich einen Testfall entwickelt, der verwendet werden kann, um Geschwindigkeitsvorteile oder -nachteile zu messen.

Der Testfall

Der Testfall besteht aus einer einfachen HTML-Seite, die einen „Bio“-Block 5000 Mal ausgibt, das Markup ist für jeden Block gleich, aber die Klassen sind leicht unterschiedlich (numerisches Unterscheidungsmerkmal), das CSS für diesen Block wird ebenfalls 5000 Mal ausgegeben , wobei sich nur die Klassennamen unterscheiden. Das ausgegebene CSS wird durch ein Tool namens CSS MQPacker geleitet. Dies trägt dazu bei, die Dateigröße von CSS, das viele Inline-Medienabfragen verwendet, drastisch zu reduzieren, indem alle separaten Instanzen einer bestimmten Medienabfrage zu einer kombiniert werden. Es ist ein großartiges Tool, das wahrscheinlich davon profitieren wird modernste CSS-Codebasen — Ich habe es als eigenständiges CLI-Tool über eine npm-Aufgabe im Testprojekt package.json verwendet, Sie können es auch als postcss-Plugin verwenden, was schön und praktisch ist!

Der erste Testfall ist ein Mobile-First-Beispiel für kaskadierende Medienabfragen, der zweite Testfall ist eine generische erste unterteilte Variante des CSS. Das CSS für diese Fälle ist etwas ausführlich und könnte wahrscheinlich viel prägnanter geschrieben werden, aber es dient wirklich nur als grobes Beispiel, um die Argumentation zu testen.

Der Test wurde 20 Mal für jede CSS-Variante in Desktop Google Chrome v70 durchgeführt, kein riesiger Datensatz, aber genug, um mir eine ungefähre Vorstellung von einem Leistungsgewinn/-verlust zu geben.

Die von mir gewählten Testmetriken sind:

  • Gesamte Seitenladezeit
    Eine grundlegende Metrik zum Überprüfen der Seitenladezeit mithilfe der Performance-API-Markierungen am Anfang von <head> und ganz am Ende von <body>
  • Der Neuberechnungsstil
    Zeit aus dem Leistungsbereich der Entwicklungstools.
  • Das gesamte Seiten-Rendering
    Zeit aus dem Leistungsbereich der Entwicklungstools.
Ergebnistabelle des Google Chrome-Leistungsprofilers
Abb.5. Die Schlüsselmetrik, die gemessen wird, ist „Stil neu berechnen“. (Große Vorschau)

Ergebnistabelle (alle Zeiten in Millisekunden)

Mobil zuerst Allgemein zuerst
Ladezeit Stile berechnen Gesamte Renderzeit Ladezeit Stile berechnen Gesamte Renderzeit
1135 565.7 1953 1196 536.9 2012
1176 563,5 1936 1116 506.9 1929
1118 563.1 1863 1148 514.4 1853
1174 568.3 1929 1124 507.1 1868
1204 577.2 1924 1115 518.4 1854
1155 554.7 1991 1177 540.8 1905
1112 554.5 1912 1111 504.3 1886
1110 557.9 1854 1104 505.3 1954
1106 544.5 1895 1148 525.4 1881
1162 559.8 1920 1095 508.9 1941
1146 545.9 1897 1115 504.4 1968
1168 566.3 1882 1112 519.8 1861
1105 542.7 1978 1121 515.7 1905
1123 566.6 1970 1090 510.7 1820
1106 514.5 1956 1127 515.2 1986
1135 575.7 1869 1130 504.2 1882
1164 545.6 2450 1169 525.6 1934
1144 565 1894 1092 516 1822
1115 554.5 1955 1091 508.9 1986
1133 554,8 2572 1001 504.5 1812
Durchschn 1139,55 557.04 1980 1119.1 514.67 1903.15

Abb.6. 20 Testläufe zur Messung der wichtigsten Last-/Rendering-Metriken von Mobile First vs. Generic First CSS.

Aus meinem zugegebenermaßen kleinen Datensatz scheint mein anfänglicher Verdacht richtig zu sein. Im Durchschnitt sehe ich, dass die Aufgabe zur Stilneuberechnung 42 ms weniger Zeit in Anspruch nimmt, was einer Geschwindigkeitssteigerung von 7,6 % entspricht, und daher verringert sich auch die Gesamtrenderzeit. Der Unterschied ist nicht überwältigend, aber es ist eine Verbesserung. Ich denke nicht, dass der Datensatz groß genug ist, um zu 100 % schlüssig zu sein, und der Testfall ist ein wenig unrealistisch, aber ich bin sehr froh, dass ich keinen Leistungsabfall sehe.

Ich wäre sehr daran interessiert zu sehen, wie die generische First-Methodik auf eine real existierende Codebasis angewendet wird, die auf Mobile-First-Weise geschrieben wurde – die Vorher-Nachher-Metriken wären für die tägliche Praxis viel realistischer.

Und wenn jemand Vorschläge hat, wie man diesen Test über einen breiteren Satz von Iterationen automatisieren kann, lass es mich bitte in den Kommentaren wissen! Ich würde mir vorstellen, dass es ein Tool geben muss, das das kann.

Fazit

Um die Vorteile dieser neuen Entwicklungsmethodik noch einmal zusammenzufassen...

  • CSS, das genau das tut, was beabsichtigt ist, kein Nachdenken;
  • Selbstdokumentierende Medienabfragen;
  • Eine bessere Erfahrung mit Entwicklungstools;
  • Seiten, die schneller gerendert werden.

Ich würde gerne glauben, dass ich nicht die einzige Person bin, die sich für das Schreiben von CSS in diesem Stil einsetzt. Wenn Sie bereits die generische erste Denkweise angenommen haben, hurra! Aber wenn nicht, denke ich, dass Ihnen die Vorteile, die es mit sich bringt, wirklich gefallen werden. Ich persönlich habe sehr von der übersichtlichen Erfahrung mit den Entwicklertools profitiert, was für viele Entwickler ein großer Vorteil sein wird. Der selbstdokumentierende Charakter dieser Art, Ihre Medienanfragen zu schreiben, wird auch für Sie selbst und das gesamte Team (falls vorhanden) von Vorteil sein. Und schließlich kosten Sie diese Vorteile nichts in Bezug auf die Leistung und haben tatsächlich gezeigt, dass sie marginale Geschwindigkeitsgewinne bringen!

Letztes Wort

Wie alle Entwicklungsmethoden ist es vielleicht nicht jedermanns Sache, aber ich habe mich ganz natürlich für Generic First CSS entschieden. Ich sehe es jetzt als eine wertvolle Arbeitsweise, die mir alle Vorteile von Mobile First mit einigen positiven neuen Ergänzungen bietet die harte Arbeit der Front-End-Entwicklung ein wenig einfacher.

Ressourcen

Testfall-Repo

Wenn Sie den Testfall starten und selbst ausprobieren möchten, finden Sie ihn auf GitHub. Ich würde gerne einige Berichte von anderen sehen.

Werkzeuge

  • CSS-MQPacker
  • Medien einschließen