CSS, DRY und Code-Optimierung

Artikel vom 16. September 2015. ISSN 1614-3124, #49. Schwerpunkt: (RSS-Feed für alle Themen).

Dieser und viele andere Beiträge sind auch als hübsches, wohlerzogenes E-Book erhältlich: On Web Development. Wenn Sie sich speziell mit der Optimierung von CSS beschäftigen, ich habe einige Grundlagen in einem kleinen Buch zusammengetragen: CSS Optimization Basics.

Vor ein paar Monaten erklärte ich einmal die Probleme mit dem Sortieren nach Kategorie. Also dem Sortieren von CSS, Deklarationen genau gesagt, nach Dimensionen, Farben, Positionierungsschema und mehr war mir auch nicht so klar. Und es fiel mir auf, dass die Motivation des CSS-Kategoriesortierers durch ein besonderes Problem entstand, und nicht auf bloßer Präferenz fußte. Es war etwas Grundlegendes, etwas, dass uns Webentwicklern schon andere Kopfschmerzen bereitet hat. Das darunterliegende Problem war, dass man sich zu oft in CSS wiederholt – bzw. sich zu oft »falsch« wiederholt.

Sich in Code nicht zu wiederholen, Dinge nicht doppelt und dreifach zu deklarieren, bildet ein wichtiges Wartbarkeitsprinzip. Manche Einführung in Wartbarkeit ist hier noch etwas schwach auf der Brust, aber wenn wir nach Definitionen greifen, finden wir, dass DRY ein Prinzip ist, »Redundanz zu vermeiden oder zumindest zu reduzieren«, da in Systemen, »die dem DRY-Prinzip treu bleiben, Änderungen nur an einer Stelle vorgenommen zu werden brauchen« (Wikipedia), oder dass Redundanz zu »Wartungsalbträumen« führen kann, so dass, frei übersetzt, »innerhalb eines Systems jedes Stück Information über eine einzelne, unzweideutige, verbindliche Repräsentation« verfügen sollte (Cunningham & Cunningham). (Ich setze in diesem Artikel voraus, dass klar ist, warum Wartbarkeit wichtig ist und wie DRY dazu beiträgt.)

Die natĂĽrliche Art, CSS zu schreiben

Was in unseren Stylesheets passiert, ist dass wir zu selten Anstrengungen unternehmen, Wiederholung zu vermeiden. Die natürliche Tendenz ist, höchstens unfreiwillig Wiederholungen von Selektoren zu vermeiden, einfach durch die Art, wie wir entwickeln. Diese Art besteht darin, sich auf Features zu konzentrieren, und Features werden durch Selektoren und Gruppen von Selektoren reflektiert.

Am besten sehen wir uns ein Beispiel an. Es ist etwas abstrakt gehalten, um eine Balance zwischen Verständnis und vielleicht ablenkenden Details zu erzielen. Wenn wir anfangen, an einem Webprojekt und seinem Stylesheet zu zaubern, neigen wir dazu, etwa wie folgt vorzufahren:

funktion1 {
  deklaration1
  deklaration2
  deklaration3
}

…

funktion2 {
  deklaration4
  deklaration5
  deklaration1
}

…

funktion3 {
  deklaration6
  deklaration2
}

(»funktionn« steht dabei für die Selektoren unserer Features, und »deklarationn« für unterschiedliche Deklarationen, solange sie nicht dieselbe Nummer tragen.)

Dies ist der prinzipielle Ablauf, der sich wenig ändert, wenn mit mehr Selektoren und Deklarationen gearbeitet wird. Ich behaupte, dass ziemlich jeder so arbeitet. So schreiben wir anfangs alle unseren CSS-Code.

Durch unseren Fokus auf Features und Funktionen tendieren wir dazu, die Wiederholung zumindest von Selektoren zu vermeiden. Aber nicht ganz: Wir tendieren dazu. Und das hilft nicht.

Was zum einen passiert, ist dass je größer ein Stylesheet wird, desto mehr Entropie und Wiederholung entstehen. Die Reihenfolge von Selektoren, Deklarationen, Regeln und Abschnitten wird immer chaotischer, und es gibt mehr und mehr Duplikate sowohl was Selektoren als auch was Deklarationen anbelangt (und vielleicht sogar Regeln). Dem Webentwickler, der dies noch nie beobachtet hat, sei nahegelegt, seine Stylesheets sorgfältiger zu prüfen; das ist nur als freundlicher Hinweis zu verstehen, da ich weiß, unter wie viel Druck wir manchmal bei unserer Arbeit stehen.

Zum anderen ist der scheinbar glĂĽckliche Umstand, dass wir uns nicht so oft bei unseren Selektoren wiederholen, nicht nur dem Zufall wie wir arbeiten geschuldet, sondern generell nicht so hilfreich, da Selektoren, wie sie es sollten, normalerweise kĂĽrzer als Deklarationen sind. Das bedeutet, dass etwaige Einsparungen hier in Bezug auf Wiederholung durch die Wiederholungen aufgefressen werden, die wir dann bei Deklarationen messen. Wir kriegen davon einen ersten Eindruck im obigen abstrakten Code-Beispiel.

Die bessere Art, CSS zu schreiben

Die Art, CSS zu schreiben, zu verbessern, heißt nicht zwangsläufig, dass man die natürliche ändert. Sie besteht vielmehr darin, sich auf Nachoptimierung zu konzentrieren, die Wiederholungen vermeidet. Überraschenderweise besteht das Gros der Vermeidung von Wiederholung von CSS in einer Methode, die – und hier fehlen mir einfach alternative Quellen – ich selbst 2007/2008 beworben habe: jede Deklaration nur einmal zu verwenden. (Die erste öffentliche Erwähnung erhielt jedoch nicht so viel Aufmerksamkeit, während die Google-Fassung nicht gleich viel Gegenliebe fand.)

Jede Deklaration nur einmal zu verwenden erscheint bei weitem die effektivste Weise, DRY auf CSS anzuwenden. Um die gerne deutlichen Ersparnisse zu erzielen (20–40%), ist jedoch ein wenig manuelle Arbeit erforderlich. Wie dieser Prozess aussieht, habe ich bereits in besagten Beiträgen auf dieser Website und bei Google beschrieben, und so werde ich mich hier auch nicht selbst wiederholen. (Andere Kollegen mögen dies jedoch einst effektiver ausgedrückt haben.)

Code-Optimierung, des Webentwicklers Stiefkind

Nehmen wir nun an, dass verständlich ist, warum wir DRY in CSS benötigen, wie DRY in CSS Arbeit darstellt, wie diese Arbeit auf Deklarationen, nicht Selektoren, fußt und dass diese Arbeit manuell ist, da sie äußerst schwer ist, zu automatisieren.

Dann möchte ich entsprechend meine Argumentation auf die Beobachtung ausweiten, dass wir uns generell nicht genügend um CSS-Optimierung kümmern. Ich denke, dass DRY dafür ein gutes Beispiel ist, nicht nur, weil es so oft vernachlässigt wird, nicht nur, weil es, wenn übersehen, ineffiziente Kategoriesortierung ermutigt, sondern weil es, was ebenso leicht vergessen wird, uns direkt in das Drama um Konstanten und Mixins geführt hat.

Was diesbezüglich passiert ist, war dass Webentwickler bemerkt hatten, dass sie fürchterlich viel Code nach der natürlichen Art schrieben, um dann danach zu eifern – man möchte sagen, zu schreien –, CSS durch Konstanten und Mixins, und nur durch Konstanten und Mixins, zu vereinfachen. Das jedoch kann leicht als panische Kurzschlussreaktion erscheinen, und zwar aus drei Gründen:

  1. Aus technologischer Sicht war der Gebrauch von Konstanten und Mixins bereits möglich, durch Sprachen wie PHP. Bert Bos beschrieb diesen Umstand damals in einem wunderschönen Artikel über Variablen.

  2. Aus Sicht des Problems ermöglichte der einmalige Einsatz von Deklarationen schon die erwünschte Reduktion von Wiederholung und Komplexität, reduziert zumindest auf einen arg geringeren Bedarf nach Konstanten.

    (Was die so kritisierte Sortierung nach Kategorien anbelangt, reduziert das einmalige Verwenden von Deklarationen die durchschnittliche Zahl von Deklarationen auf etwa zwei, herunter von den zehn oder mehr, die Kategoriesortierer allein in Beispielen benutzen. Ganz grob formuliert, aber in die Erkenntnis mĂĽndend, die ich eingangs ansprach: Das Kernproblem des Kategoriesortierers ist eher die natĂĽrliche, nicht-optimierte Art, CSS zu schreiben.)

  3. Aus Sicht einer Lösung war die Idee, Komplexität durch Variablen einzudämmen eine, die einen Schritt übersprang, nämlich den, diese Komplexität zu vermeiden – was vielleicht direkt zu DRY geführt hätte.

❧ Auch wenn ich den Nutzen von Konstanten und Mixins ausdrücklich anerkenne, denke ich, dass das ganze Kein-DRY-sondern-laut-nach-Variablen-Schreien ein gutes Beispiel dafür ist, wie wir CSS-Optimierung vernachlässigen. Wir schauen selten genau darauf, wie wir besseres CSS schreiben können, wie wir mehr aus CSS rausholen können und wie wir die Probleme, die uns im Weg stehen, vermeiden können, bevor wir schwere CSS-Arbeitsgruppenartillerie anfordern.

Dies aber als Momentaufnahme. Das Wichtigste, was hier mitzunehmen ist, ist bitte Wiederholung in Stylesheets zu minimieren – vielleicht dadurch, Deklarationen nur einmal zu verwenden –, sich mehr auf CSS-Optimierung zu konzentrieren und zu bedenken, dass Probleme vermeiden auch ein Weg ist, sie zu lösen.

War dies nützlich oder interessant? Teile (toote) diesen Beitrag, oder lad mich vielleicht auf einen Kaffee ein. Danke!

Ăśber mich

Jens Oliver Meiert, am 30. September 2021.

Ich bin Jens, und ich bin ein Engineering Lead und Autor. Ich habe als technischer Leiter für Firmen wie Google und als Engineering Manager für Firmen wie Miro gearbeitet, bin W3C und WHATWG verbunden und schreibe und prüfe Fachbücher für O’Reilly und Frontend Dogma.

Mit meinem aktuellen Umzug nach Spanien bin ich offen für eine neue Remote-Führungsposition im Frontend-Bereich. Beachte und empfehle gerne meinen Lebenslauf oder mein LinkedIn-Profil.

Ich experimentiere gerne, nicht nur in der Webentwicklung, sondern auch in anderen Bereichen wie der Philosophie. Hier auf meiert.com teile ich einige meiner Ansichten und Erfahrungen.