Wie entfernt man ungenutztes CSS von einer Website?

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Hier ist, was ich Ihnen gleich vorweg mitteilen möchte: das ist ein schwieriges Problem. Wenn Sie hier gelandet sind, weil Sie auf ein Tool hoffen, das Ihnen genau sagt, welches CSS Sie aus Ihrem Projekt löschen können, nun ja... es gibt Werkzeuge da draußen, aber ich warne Sie, sehr vorsichtig damit zu sein, denn keines davon kann jemals die vollständige Geschichte erzählen.

Ich weiß, was Sie wollen. Sie möchten das Tool ausführen, das löschen, was es Ihnen sagt, und Sie haben in 2,2 Minuten eine schnellere Website. Es tut mir leid, aber ich werde Sie enttäuschen.

Ich denke, Sie sollten eine gesunde Skepsis gegenüber jedem solchen Werkzeug haben. Keines von ihnen lügt Sie an – sie haben oft einfach nicht genügend Informationen, um Ihnen sichere und umsetzbare Ergebnisse zu liefern. Das soll nicht heißen, dass Sie sie nicht verwenden können oder dass es nicht geht. Lassen Sie uns einen Spaziergang machen.

Die Motivation

Ich stelle mir vor, der Hauptgrund für den Wunsch, ungenutztes CSS zu entfernen, ist dieser:

Sie haben ein CSS-Framework verwendet (z. B. Bootstrap), die gesamte CSS-Datei des Frameworks eingebunden und nur eine Handvoll der bereitgestellten Muster verwendet.

Ich kann das nachvollziehen. CSS-Frameworks bieten oft keine einfachen Möglichkeiten, nur das zu nutzen, was man verwendet, und die Anpassung des Quellcodes für diesen Zweck könnte ein Maß an Fachwissen erfordern, das Ihr Team nicht besitzt. Das könnte sogar der Grund sein, warum Sie sich überhaupt für ein Framework entschieden haben.

Nehmen wir an, Sie laden 100 KB CSS. Ich würde sagen, das ist viel. (Während ich schreibe, hat diese Website ~23 KB, und es gibt ziemlich viele Seiten und Vorlagen. Ich tue nichts Besonderes, um die Größe zu reduzieren.) Sie haben die Vermutung oder einige Beweise dafür, dass Sie einen Teil dieser Bytes nicht verwenden. Ich kann den Grund für die Alarmbereitschaft sehen. Wenn Sie ein 100 KB großes JPG hätten, das Sie durch das Hochladen auf ein Tool auf 20 KB komprimieren könnten, wäre das großartig und absolut lohnenswert. Aber der Gewinn bei CSS ist noch wichtiger, da CSS im Head geladen wird und das Rendering blockiert. Das JPG nicht.

😬 Überprüfung der "Abdeckung"

Die Entwicklertools von Chrome verfügen über einen Tab "Abdeckung", der Ihnen anzeigt, wie viel Ihres CSS und JavaScript verwendet wird. Wenn ich zum Beispiel gerade die Homepage von CSS-Tricks besuche...

Es sagt mir, dass 70,7 % meiner Datei style.css ungenutzt sind. Ich stelle mir vor, dass das stimmt und der Rest des CSS woanders verwendet wird. Ich habe keine große Style-Bibliothek auf diese Website geworfen; ich habe jede Zeile davon von Hand geschrieben, daher bezweifle ich, dass mehr als 2/3 davon global ungenutzt sind.

Ich nahm an, ich könnte "aufzeichnen", dann auf verschiedene Bereiche der Website klicken und sehen, wie diese ungenutzte Zahl sinkt, während verschiedene Seiten mit unterschiedlichem HTML gerendert werden, aber leider aktualisiert sich mit dem Seitenrefresh auch der Abdeckungs-Tab. Er ist nicht sehr nützlich, um eine mehrseitige Ansicht der CSS-Abdeckung zu erhalten, es sei denn, Sie haben eine Single Page App, nehme ich an?

Ich sage ungern, aber ich finde die Überprüfung der Codeabdeckung ziemlich nutzlos. Für mich malt sie ein düsteres Bild all dieses ungenutzten Codes auf der Website, was meine Zweifel schürt, aber alles, was ich tun kann, ist, mir darüber Sorgen zu machen.

Dies könnte genau der Grund sein, der Sie auf die Idee gebracht hat, ungenutztes CSS zu entdecken und zu löschen.

Meine Hauptsorge

Meine größte Sorge ist, dass Sie sich etwas wie die Codeabdeckung ansehen und Ihre ungenutzten Zeilen sehen

Und Sie denken: Perfekt! Das CSS lösche ich! Und das tun Sie, nur um festzustellen, dass es doch nicht ungenutzt war und Sie große Styling-Probleme auf der gesamten Website verursacht haben. Die Sache ist die: Sie wissen nicht wirklich, ob ein CSS-Selektor ungenutzt ist, es sei denn, Sie

  1. prüfen die Abdeckung auf jeder einzelnen Seite Ihrer gesamten Website...
  2. während Sie das gesamte JavaScript ausführen...
  3. unter jeder möglichen Zustandskombination...
  4. in jeder möglichen Kombination von Medienabfragen, die Sie verwendet haben.

Die Überprüfung Ihrer Homepage zählt nicht. Die Überprüfung all Ihrer Top-Level-Seiten zählt nicht. Sie müssen sich durch jede Seite arbeiten, einschließlich Zuständen, die nicht immer im Vordergrund stehen, ganz zu schweigen von allen Randfallszenarien. Andernfalls könnten Sie am Ende das Dropdown-Styling für das Dropdown zur Auswahl der Kreditkarte im Pop-up-Modal löschen, das für Benutzer mit einem deaktivierten Konto erscheint, die während ihrer Gnadenfrist angemeldet sind und auch eine Geschenkkarte einlösen möchten.

Das ist zu komplex für automatisierte Werkzeuge, um zu versprechen, dass ihr Ansatz perfekt funktioniert, insbesondere wenn man die Unbekannten des Browserkontexts (unterschiedliche Bildschirmgrößen, unterschiedliche Fähigkeiten, unterschiedliche Browser) und Drittanbieter berücksichtigt.

Hier ist ein Beispiel, wie sich meine Sorge äußert

PurifyCSS Online nimmt einige URLs und liefert sofort einen kopierbaren CSS-Schnipsel zur Verwendung

Hier habe ich css-tricks.com in PurifyCSS Online eingegeben und neues CSS erhalten.

Ups!

Links CSS-Tricks wie gewohnt. Rechts habe ich das neue "gereinigte" CSS angewendet, das eine Menge für andere Seiten notwendiges CSS gelöscht hat.

Es gab mir die Möglichkeit, andere URLs einzugeben (was nett ist), aber es gibt Zehntausende von URLs auf CSS-Tricks. Viele davon sind ziemlich ähnlich, aber alle haben das Potenzial für verwendete Selektoren. Ich habe den Eindruck, dass es kein JavaScript ausgeführt hat, denn alles, was über JavaScript auf die Seite kam, blieb ungestylt. Es hat sogar meine :hover-Zustände gelöscht.

Sie können vielleicht verstehen, warum mein Vertrauen in diese Tools so gering ist.

Teil eines Build-Prozesses

PurifyCSS wird wahrscheinlich häufiger als Build-Prozess-Tool verwendet als die Online-Oberfläche. Ihre Dokumentation enthält Anleitungen für Grunt, Gulp und webpack. Zum Beispiel das Globbing von Dateien zur Überprüfung und Verarbeitung

var content = ['**/src/js/*.js', '**/src/html/*.html'];
var css = ['**/src/css/*.css'];

var options = {
  // Will write purified CSS to this file.
  output: './dist/purified.css'
};

purify(content, css, options);

Das gibt Ihnen viel mehr Möglichkeiten für Genauigkeit. Dieser Inhalts-Blob könnte eine Liste aller Vorlagen, Teilkomponenten und JavaScript-Dateien sein, die Ihre Website erstellen. Das kann mühsam zu pflegen sein, aber Sie werden sicherlich mehr Genauigkeit erhalten. Es berücksichtigt keine Inhalte in Datenspeichern (z. B. dieser Blogbeitrag, der in einer Datenbank lebt) und Drittanbieter-JavaScript, aber vielleicht ist Ihnen das egal oder Sie können es auf andere Weise berücksichtigen.

PurgeCSS, ein Konkurrent von PurifyCSS, warnt vor seiner Vergleichstechnik

PurifyCSS kann mit jedem Dateityp arbeiten, nicht nur mit HTML oder JavaScript. PurifyCSS vergleicht alle Wörter in Ihren Dateien mit den Selektoren in Ihrem CSS. Jedes Wort wird als Selektor betrachtet, was bedeutet, dass viele Selektoren fälschlicherweise als verwendet angesehen werden können. Sie könnten zum Beispiel zufällig ein Wort in einem Absatz haben, das einem Selektor in Ihrem CSS entspricht.

Behalten Sie das also im Hinterkopf. Es ist dumm in der Art und Weise, wie es potenzielle Selektoren-Übereinstimmungen vergleicht, was sowohl clever als auch gefährlich ist.

UnusedCSS ist ein Online-Dienst, der Ihre Website für Sie durchforstet

Die manuelle Konfiguration eines Tools, das jede Seite Ihrer Website aus jedem Winkel betrachtet, ist sicherlich eine mühsame Aufgabe und etwas, das mit der Zeit synchron gehalten werden muss, wenn sich Ihre Codebasis weiterentwickelt. Interessanterweise versucht der Online-Dienst UnusedCSS, diese Belastung zu überwinden, indem er die Website selbst anhand einer einzigen von Ihnen angegebenen URL durchforstet.

Ich habe mich für den kostenpflichtigen Dienst angemeldet und ihn auf CSS-Tricks gerichtet. Ich gebe zu, mit einem einfachen Blick auf die Ergebnisse fühlt es sich für mich viel genauer an

Es sagt mir, dass ich 93 % meines CSS verwende, was mir als Handautor des gesamten CSS auf dieser Website mehr entspricht.

Es ermöglicht Ihnen auch, die bereinigte Datei herunterzuladen und bietet viele Anpassungsmöglichkeiten, wie z. B. das Auswählen/Abwählen von Selektoren, die Sie tatsächlich benötigen/nicht benötigen (z. B. Sie sehen einen Klassennamen, den es Ihrer Meinung nach nicht benötigt, den Sie aber sicher brauchen), sowie das Präfixen und Entfernen doppelter Selektoren.

Ich habe die erhöhte Genauigkeit des Online-Crawling-Dienstes genossen, aber es gab viel Rauschen, und ich kann auch nicht sehen, wie ich ihn praktisch in einen täglichen Build- und Release-Prozess integrieren würde.

Tools werden im Allgemeinen nach der Verarbeitung verwendet

Sagen wir, Ihr CSS wird mit Less oder Sass erstellt und dann mit einem Postprozessor zu CSS kompiliert. Wahrscheinlich würden Sie automatisiertes Bereinigen von ungenutztem CSS am Ende jeder anderen CSS-Vorverarbeitung, die Sie durchführen, einbauen. So...

  1. Sass
  2. PostCSS / Autoprefixer
  3. [ Bereinige ungenutztes CSS ]
  4. Produktions-CSS

Das ist sowohl logisch als auch leicht amüsant für mich. Sie beheben nicht wirklich das Styling, das ungenutztes CSS generiert. Stattdessen wischen Sie es am Ende des Builds einfach weg. Ich nehme an, JavaScript macht diese Art von Dingen schon seit einiger Zeit mit Tree Shaking, also gibt es einen Präzedenzfall, aber es fühlt sich für mich immer noch seltsam an, weil eine CSS-Codebasis so direkt von Hand bearbeitet wird. Dieses Setup ermutigt Sie fast dazu, CSS überall hin zu werfen, da es keine Strafe für Übertreibungen gibt. Es nimmt jeden Anreiz, zu verstehen, wie CSS angewendet und verwendet wird.

PurgeCSS ist ein weiteres Tool, das explizite Eingaben verarbeitet und Ihnen Ergebnisse liefert

PurgeCSS ist ein weiterer Akteur auf dem Markt für ungenutztes CSS. Eine tangentiale Sache, die mir daran gefällt, ist, dass es klar erklärt, wie es sich von anderen Tools unterscheidet. Zum Beispiel im Vergleich zu PurifyCSS

Der größte Nachteil von PurifyCSS ist seine mangelnde Modularität. Dies ist jedoch auch sein größter Vorteil. PurifyCSS kann mit jedem Dateityp arbeiten, nicht nur mit HTML oder JavaScript. PurifyCSS vergleicht alle Wörter in Ihren Dateien mit den Selektoren in Ihrem CSS. Jedes Wort wird als Selektor betrachtet, was bedeutet, dass viele Selektoren fälschlicherweise als verwendet angesehen werden können. Sie könnten zum Beispiel zufällig ein Wort in einem Absatz haben, das einem Selektor in Ihrem CSS entspricht.

PurgeCSS behebt dieses Problem, indem es die Möglichkeit bietet, einen "Extractor" zu erstellen. Ein Extractor ist eine Funktion, die den Inhalt einer Datei nimmt und die Liste der darin verwendeten CSS-Selektoren extrahiert. Dies ermöglicht eine perfekte Entfernung von ungenutztem CSS.

PurgeCSS scheint derzeit der große Star zu sein. Viele Leute benutzen es und schreiben darüber.

Obwohl PurgeCSS eine spezielle Konfiguration benötigt, um mit Tailwind zu funktionieren, scheinen Tailwind und PurgeCSS wie zwei Erbsen in einer Schote. Tatsächlich empfiehlt ihre Dokumentation die gemeinsame Nutzung und bietet eine CLI für die Verwendung in einem Build-Prozess.

Ich glaube, der Kern der Sache ist dieser: Tailwind erzeugt diese große CSS-Datei voller Utility-Selektoren. Aber sie sind nicht dazu gedacht, dass Sie das Ganze verwenden. Sie verwenden diese Utility-Selektoren in Ihrem HTML, um all Ihr Styling zu machen, und verwenden dann PurgeCSS, um Ihr gesamtes HTML zu durchsuchen und die ungenutzten Utility-Selektoren in Ihrem Produktions-CSS auszusortieren.

Dennoch wird es eine ständige Wartungsaufgabe sein, es über jede einzelne Vorlage auf Ihrer Website zu lehren (JavaScript, HTML oder andere), während Sie alles, was auf Drittanbieter-Ressourcen angewiesen ist, manuell konfigurieren und wissen, dass Daten aus einem Datenspeicher wahrscheinlich nicht während eines Build-Prozesses analysiert werden können, was sie zu etwas macht, das manuell berücksichtigt werden muss.

Meine Lieblingstechnik: Jemand, der mit Ihrer CSS-Codebasis sehr vertraut ist, ist sich des Problems bewusst und strebt an, es im Laufe der Zeit zu beheben

Vielleicht erscheint Ihnen das wie der Ansatz eines alten Hasen, der mit der Zeit gehen muss, aber hey, das erscheint mir einfach als der praktischste Ansatz. Da dieses Problem so schwierig ist, denke ich, dass harte Arbeit die Lösung dafür ist. Es geht darum, das Problem zu verstehen und im Laufe der Zeit auf eine Lösung hinzuarbeiten. Ein Front-End-Entwickler, der eng in Ihr Front-End eingebunden ist, wird mit der Zeit ein Verständnis dafür entwickeln, was im CSS-Bereich verwendet und was ungenutzt ist, und kann es reduzieren.

Ein extremer Testansatz, den ich gesehen habe, ist die Verwendung von (d.h. background-image: url(/is-this-being-used.gif?selector);) im CSS-Block und dann die Überprüfung von Serverprotokollen über einen Zeitraum, um zu sehen, ob dieses Bild abgerufen wurde. Wenn es abgerufen wird, wurde es verwendet; wenn nicht, dann nicht.

Aber vielleicht ist mein Lieblingswerkzeug im potenziellen Werkzeugkasten dieses:

Visuelle Regressionstests

Sie erstellen Screenshots von so viel wie möglich Ihrer Website – wie von allen wichtigsten Seiten und diesen Seiten in verschiedenen Zuständen – plus über verschiedene Browser und Bildschirmgrößen hinweg. Diese Screenshots werden von Ihrem Master-Branch in Git erstellt.

Bevor dann irgendwelche Branches in den Master gemergt werden, nehmen Sie all diese Screenshots davon und vergleichen sie mit den Screenshots im Master. Nicht manuell, sondern programmatisch.

Genau das macht Percy, also schauen Sie mal

Es gab im Laufe der Jahre andere Versuche mit Tools für visuelle Regressionstests, aber Percy ist das einzige, das mir einleuchtet. Ich muss nicht nur Screenshots machen; ich möchte, dass sie verglichen werden, damit ich visuelle Unterschiede zwischen ihnen sehen kann. Ich möchte nicht nur die Unterschiede sehen; ich möchte sie genehmigen oder ablehnen. Ich möchte auch, dass diese Genehmigung Merges blockiert oder erlaubt, und ich möchte die Kontrolle über den Browser haben, bevor der Screenshot gemacht wird. Ich möchte die Vergleichsbilder nicht manuell aktualisieren. Das alles gehört zum Kern von Percy.

Offenlegung: Percy hat hier auf CSS-Tricks schon einmal Dinge gesponsert – einschließlich des obigen Videos –, aber nicht diesen Beitrag.

Der Bezug zu Atomic CSS und CSS-in-JS

Ich bin sicher, es gibt viele Leute, die das hier lesen und sagen würden: Ich habe kein ungenutztes CSS, weil die Werkzeuge, die ich benutze, genau das CSS generieren, das es braucht, und nichts mehr.

Hey, das ist irgendwie cool.

Vielleicht ist das Atomizer. Vielleicht ist es Tachyons, das Sie auch durch UnCSS laufen lassen und dabei sehr vorsichtig sind. Vielleicht ist es die gerade angesagte Kombination aus Tailwind + PurgeCSS.

Vielleicht gehen Sie Stile auf andere Weise an. Wenn Sie JavaScript-Komponenten und Stile eng koppeln, wie React und Emotion, oder einfach nur CSS-Module mit irgendetwas verwenden, ist weniger ungenutztes CSS ein Vorteil von CSS-in-JS. Und da Tree-Shaking und Code-Splitting bei vielen JavaScript-basierten Build-Prozessen mit von der Partie sind, haben Sie nicht nur weniger CSS, sondern laden auch nur das, was Sie im Moment brauchen. Aber all das hat auch seine Nachteile.

Wie vermeidet man ungenutztes CSS in zukünftigen Projekten?

Ich denke, die Zukunft des Stylings ist eine bewusste Trennung zwischen globalen und komponentenbasierten Stilen. Die meisten Stile sind auf Komponenten beschränkt, aber es gibt globale Stilentscheidungen, die die Kaskade klar nutzen (z. B. globale Typografie-Standardeinstellungen).

Wenn die meisten Stile auf Komponenten beschränkt bleiben, gibt es meiner Meinung nach weniger Möglichkeiten für ungenutzte Stile, sich anzuhäufen, da es viel einfacher ist, einen kleinen Block HTML und einen kleinen Block CSS, die direkt miteinander verbunden sind, zu begreifen. Und wenn Komponenten sterben oder sich weiterentwickeln, sterben oder entwickeln sich die Stile mit ihnen. CSS-Bundles werden aus Komponenten erstellt, die tatsächlich verwendet werden.

CSS-in-JS-Lösungen gehen natürlich in diese Richtung, da Stile an Komponenten gebunden sind. Das ist im Grunde der Hauptpunkt. Aber es ist nicht zwingend erforderlich. Ich mag den generischen Ansatz von CSS-Modulen, der so ziemlich ausschließlich für die Stilbegrenzung gedacht ist und nicht vorschreibt, dass Sie ein bestimmtes JavaScript-Framework verwenden.

Wenn all das theoretisch oder unerreichbar erscheint und Sie nur eine Bootstrap-Website haben, bei der Sie die Größe dieses Bootstrap-CSS reduzieren möchten, empfehle ich, Bootstrap aus dem Quellcode anstelle des endgültigen, standardmäßig verteilten Bundles zu verwenden. Der Quellcode ist SCSS und aus einer Reihe von High-Level-Includes aufgebaut. Wenn Sie bestimmte Teile von Bootstrap nicht benötigen, können Sie sie entfernen.

Entfernen von Dropdowns, Badges und Breadcrumbs aus Bootstrap vor dem Build.

Viel Glück da draußen, Leute.