Diese Woche untersuchte Chris Ferdinandi einen cleveren JavaScript-Snippet, der kreativ mit neuen Syntaxfunktionen geschrieben ist, aber vielleicht weniger lesbar und performant ist. Es ist eine schnelle Lektüre, aber sein Aufruf an die Fixierung unserer Branche auf Cleverness ist es wert... herauszugreifen.
...wir sind als Branche besessen von Kürze und cleverem Code, und das Ergebnis ist Code, der manchmal weniger performant und für die meisten Menschen typischerweise schwerer zu lesen und zu verstehen ist.
Er argumentierte letzte Woche ähnlich, als er über Code-Lesbarkeit schrieb, und bemerkte, dass Kürze cool aussehen mag, aber letztendlich zu allen möglichen Problemen in einer Codebasis führt.
Oft sind Webentwickler von Kürze besessen. Es gibt diese Sache, bei der Entwickler versuchen, dieselbe Funktion mit möglichst wenigen Zeichen zu schreiben.
Persönlich halte ich Kürze für sinnlos. Lesbarkeit ist viel wichtiger.
Ich stimme Chris in diesem Punkt vollkommen zu, aber ich denke, es gibt eine wichtige Unterscheidung zu treffen, und das ist der Unterschied zwischen Code, der als Prototyp gedacht ist, und Code, der für die Produktion gedacht ist. Wie Jeremy Keith vor einiger Zeit argumentierte:
Interessant ist, dass – wenn es um Prototyping geht – unsere üblichen Frontend-Prioritäten über Bord gehen können und sollten. Die Priorität ist jetzt Geschwindigkeit. Wenn das bedeutet, Semantik oder Leistung zu opfern, dann sei es so. Wenn ich einen Prototypen baue und mich frage: „Nun, was ist der richtige Klassenname für diese Komponente?“, dann weiß ich, dass ich in der falschen Denkweise bin. Diese Frage mag für Produktionscode gültig sein, aber für Prototypen ist sie Zeitverschwendung.
Ich stimme Chris zu, dass wir Code schreiben sollten, der leicht zu lesen ist, wenn wir in der Produktion sind. Ich denke auch, dass das Experimentieren mit Code auf diese Weise gut ist, wenn es um Prototypen geht. Wir sollten niemals davor zurückschrecken, mit Code zu spielen und Dinge ein wenig voranzutreiben – solange wir das nicht in einer riesigen Web-App tun, in der viele andere Entwickler mit uns zusammenarbeiten.
Ich habe festgestellt, dass einige Leute wirklich geniale Dinge mit Sass machen. Ich sitze regelmäßig da und denke: „Wow, so etwas habe ich noch nie gesehen.“ Aber wenn es um eine Web-Produktions-App geht, die von Hunderten von Menschen gleichzeitig verstanden werden muss, glaube ich nicht, dass dies die Reaktion ist, die wir wollen, wenn jemand den Code ansieht.
Daher versuche ich, Sass-Code zu schreiben, der tatsächlich so einfach ist, dass er fast dumm aussieht. Eine einfache Möglichkeit, Code viel einfacher zu machen, ist die Reduzierung der Verschachtelung.
.element {
.heading { ... }
}
Das sieht gut aus, wenn Code darin ist – und es ist ziemlich leicht zu verstehen – aber fügen Sie ein komplexes Design hinzu (sagen wir, mit Pseudo-Elementen und Media Queries) und Sie haben plötzlich einen ziemlich komplexen Regelsatz vor sich. Kreativität und Cleverness können schwerer zu scannen und einen kleinen Teil des Codes zu identifizieren sein, den Sie suchen. Außerdem haben wir in diesem Beispiel unsere .heading Klasse unnötigerweise etwas spezifischer gemacht, was uns ermutigen könnte, Dinge an anderer Stelle in der Codebasis auf eine ungeschickte Weise zu überschreiben.
Wir könnten Folgendes schreiben:
.element { ... }
.element-heading { ... }
Ich weiß, das sieht albern einfach aus, aber die Beziehung zwischen diesen beiden Klassen ist leichter zu erkennen und in Zukunft leichter zu erweitern. Das Bündeln all dieses Codes in eine einzige verschachtelte Klasse kann sehr schnell aus dem Ruder laufen. Auch wenn es viel cooler aussieht.
(Nebenbei bemerkt, Andy Bells Beitrag über die Verwendung des kaufmännischen Und in Sass – und die daraus resultierenden Kommentare – ist ein großartiges Beispiel für den Konflikt zwischen Kreativität und Praktikabilität.)
Jedenfalls ist der Punkt, den ich hier machen möchte, dass CSS (und übrigens auch JavaScript) eine seltsame Sprache ist, weil es keine festen Regeln dafür gibt. Es hängt alles vom Codebase und dem Projekt ab. Aber ich denke, wir können sicher sagen, dass unser Code viel langweiliger sein sollte als unsere Prototypen, wenn sie in Produktion gehen.
Machen Sie weiterhin Prototypen, die wild und experimentell oder unmöglich seltsam sind! Codequalität verdammt.
Das Problem beim lockeren Umgang mit Prototyp-Code ist, dass Prototyp-Code nur allzu oft zum Produktionscode wird. Und die Zeit, ihn zu bereinigen, ist möglicherweise nicht immer verfügbar.
Zustimmung. Das ist mein Leben.
„Nichts ist so beständig wie eine temporäre Lösung.“
Also ja, ich stimme Ihnen zu. Die Menge der Male, die ich meine Prototypen in die Produktion gehen sah, ist erstaunlich.
Ich leide oft unter den Schmerzen von „nicht vollständig bereinigtem Prototyp-Code“ in der Produktion. Meine Ansicht ist, dass es in Ordnung ist, solange Ihr Team gut darin ist, Code im Allgemeinen ständig zu refaktorieren (was meins ist). Das verschwendet etwas Zeit, aber bei weitem nicht so viel Zeit, wie wenn Ingenieure (insbesondere Junioren) versuchen, produktionsreifen Code zu schreiben, wenn das Kernproblem noch nicht einmal gelöst ist.
Warum nicht schreiben
.element {
…
&-heading { … }
}
@Bytebrand
Ich habe diesen Ansatz bei der Verwendung der SMACSS-Namenskonvention verwendet und ihn dann schnell wieder verworfen, weil ich für jedes Modul eine Teil-Datei erstellt habe (im Fall von .element). Alles in einer Klammer zu schreiben, ergibt für mich keinen Sinn, da es meine Gesamtsicht auf das Modul reduziert. Daher ziehe ich es vor, mein SASS zu schreiben, wie in diesem Artikel beschrieben. Ich verschachtele jedoch die Modifikatoren innerhalb der relevanten Klasse, zum Beispiel
.element {
&#{–bigger} {
font-size: 20px;
}
}
Das gibt mir viel Komfort und spart mir Zeit beim Scannen der Datei.
Um Ihnen den größtmöglichen Spielraum für die Hinzufügung von beliebigen Dingen zum funktionierenden Code zu geben, ohne über Struktur und Codierungsstandards nachdenken zu müssen. Sie können dies später arrangieren und korrigieren, nachdem Sie sich mit den Ergebnissen sicher sind.
Ich stimme zu, wenn Sie versuchen, einen logischen Fluss zu entwickeln, können Sie einfach vorgehen. Aber beim Prototyping musste ich schon immer Produktionsnamen, Kommentare und Code verwenden. Es ist großartig, wenn Sie eine Kultur einrichten, in der dies möglich ist.
Ich frage mich, ob das wirklich das ist, was der Autor sagen wollte. Ändern Sie die Kultur.
Ich: Bin nicht ganz überzeugt von der Idee.
Es geht um Klarheit und die Abkehr von Verschachtelungen, da diese von Natur aus zu mehr Komplexität führen.
Danke für die Erwähnung. Eine Sache, die geklärt werden muss (und die ich im zweiten verlinkten Artikel erwähne), ist, dass ein großer Grund, warum Lesbarkeit wichtiger ist, darin besteht, dass man Werkzeugen erlauben kann, den Code für sich zu verdichten und zu optimieren.
Kurzen Code zu schreiben ist sinnlos, wenn Uglify alles nehmen kann, was Sie ihm geben, und etwas ausspucken, das nur einen Bruchteil der Größe hat und für Menschen völlig unlesbar ist.
Ich stelle sicher, dass es in unseren SCSS-Partials immer einen Root-Selektor gibt.
Anstatt einer völlig flachen SCSS-Datei (wie im Beispiel).
Der Grund dafür ist, dass sichergestellt wird, dass die zum Partial hinzugefügten Stile für dieses Partial relevant sind. Mit einer flachen SCSS-Datei ist es einfach, einen Selektor hinzuzufügen, der überhaupt nicht mit dem Partial als Ganzes zusammenhängt. Wenn Entwickler in Eile sind, anstatt den richtigen Ort für den Code zu finden, werden sie ihn an den ersten Ort legen, der funktioniert, und das ist jede Datei, wenn alle SCSS-Partials flach sind. Die Verwendung eines einzelnen Root-Selectors beschränkt alle Stile auf die Komponente, für die das Partial zuständig ist, was das Hinzufügen von irrelevanten Stilen verhindert.
Offensichtlich könnte jemand einen Stil außerhalb dieses Root-Selectors hinzufügen, aber dann fällt er in der Code-Überprüfung stärker auf.
Ich liebe Sass-Verschachtelung, weil sie für mich perfekt lesbar ist. Ich nutze Verschachtelung intensiv und mag nicht zu viele Klassennamen. Oft reicht eine Modulklasse und alle darin befindlichen Tags können durch Verschachtelung in dieser Klassenbezeichnung angesprochen werden.
Ich schreibe auch nicht ein Attribut pro Zeile – ich habe die Klasse und alle ihre Attribute in einer einzigen Zeile. Daran habe ich mich gewöhnt. Es ist kompakt und schön für meine Augen und für die Produktion wird es minifiziert. Ihr Beispiel würde mir die Augen weh tun.
Es gibt vieles, was über die Schlechtigkeit von cleverem Code gesagt werden kann, aber das SCSS-Beispiel verdeutlicht dies nicht und ist sehr irreführend.
Es behauptet, dass das zweite Code-Beispiel einfacher ist, weil es keine Kreativität oder Cleverness gibt, und das zweite ist albern einfach, aber beide sind albern einfach. Es behauptet auch, dass das erste cooler aussieht, was rein subjektiv und irrelevant ist.
Die beiden Code-Beispiele sind nicht dasselbe. Das erste erzeugt „.element .heading {}“, was sich sehr von „.element-heading {}“ unterscheidet. Man kann argumentieren, dass es darum geht, Selektoren nicht zu verschachteln, aber dieser Punkt wird viel zu leicht gestreift, indem gesagt wird, wir hätten den Selektor etwas spezifischer gemacht. Es eröffnet auch neue Probleme: Das Umbenennen der Klasse ist schwieriger, da Sie jetzt mehrere Ersetzungen vornehmen müssen, Sie können ein Element nicht aus dem Container heben, ohne auch Änderungen am CSS-Code vorzunehmen, und wahrscheinlich andere. Diese mögen wie kleinlich erscheinen, aber der wichtige Punkt ist, dass Sie Kompromisse eingehen, keiner ist objektiv besser als der andere.
Der Punkt, den der Artikel macht: „Ich weiß, das sieht albern einfach aus, aber die Beziehung zwischen diesen beiden Klassen ist leichter zu erkennen und in Zukunft leichter zu erweitern“, ist meiner Meinung nach völlig falsch, und das Gegenteil ist der Fall. Wenn Sie den zweiten Stil verwenden, gibt es keine Garantie, wo die Deklarationen beginnen oder enden. Sie oder andere Leute könnten einen Fehler machen und andere Deklarationen für andere Komponenten dazwischen einfügen. Das erste Beispiel gibt Ihnen durch seine Syntax eine Garantie und eliminiert die Möglichkeit menschlicher Fehler: Alle Stile, die zu dieser Komponente und ihren Kindern gehören, befinden sich hier zwischen den {} Blöcken. Sie können keine Stile einfügen, die zu einer anderen Komponente gehören, die nicht unter diesem Baum liegt, da Sie den {} Block schließen und später wieder öffnen müssten. Dies erhöht die Klarheit und verringert sie nicht.
Es ist auch viel einfacher zu refaktorieren: Das Umbenennen der Klasse oder das Verschieben der Deklarationen, wenn sie zu viel werden, in eine andere Datei sind einfacher, und aufgrund der Garantie können Sie sicher sein, dass Sie alles verschieben und nichts zurücklassen oder etwas verschieben, das Sie nicht sollten.
Der Punkt „fügen Sie ein komplexes Design hinzu (sagen wir, mit Pseudo-Elementen und Media Queries) und Sie haben plötzlich einen eher komplexen Regelsatz vor sich“, ist wahr, aber das liegt daran, dass Ihre Anwendung/Anforderungen größer werden, die Komplexität wird sowieso da sein, das Verschachteln/Entschachteln von Deklarationen wird sie nicht wesentlich beeinflussen.
Ehrlich gesagt? Schlechter Code ist schlecht. Wenn wir immer die Leistungskurve nach oben jagen, wären wir gezwungen, funktionale Programmierung und in vielen Fällen OO aufgrund ihres Performance-Hits gegenüber optimierter prozeduraler Logik flach zu ignorieren.
Ich neige jedoch dazu zu denken, dass „Lesbarkeits“-Argumente für das untere Ende des Talentpools sprechen. Leute zitieren Onkel Bob mit religiöser Inbrunst und legen ihm dann Worte in den Mund, die bis zum Punkt gehen, dass selbst Sprachfeatures schlecht sind, weil „Lesbarkeit“. SOLID wurde ebenfalls in ähnlicher Weise weitgehend missverstanden.
Aussagen wie „weniger Verschachtelung“ sind gut und schön, aber wo ist das Argument für Probleme mit der zyklomatischen Komplexität? Persönlich finde ich, wenn ich Code lese, der höhere Funktionen oder verschachtelte Aufrufe aufweist, bei denen ich gezwungen bin, den Fluss der Anwendung kontinuierlich symbolisch zu verfolgen, diesen unlesbar aufgrund konzeptioneller Diskontinuität, obwohl er die Höhe der Mode ist.
Ein Problem, das auftritt, ist jedoch, dass die Forderung aller, schnell zu sein, oft bedeutet, dass ein clever geschriebener Prototyp der Führungsebene präsentiert wird, die keine Demo oder keinen Prototyp sieht, sondern ein fertiges Produkt, das ihrer Meinung nach morgen gestartet werden sollte. Und all dieser clevere, unlesbare, nicht wartbare Produktionscode geht in die Produktion, oder im besten Fall haben Sie ein paar Wochen Zeit, um ihn aufzuräumen.
Wenn Entwickler in Eile sind und anstatt den richtigen Ort für den Code zu finden, ihn an den ersten Ort legen, der funktioniert, und das ist jede Datei, wenn alle SCSS-Partials flach sind. Die Verwendung eines einzelnen Root-Selectors beschränkt alle Stile auf die Komponente, für die das Partial zuständig ist, was das Hinzufügen von irrelevanten Stilen verhindert.