Wenn Sie Ihre eigenen SVG-Dateien zeichnen oder sie aus dem Internet herunterladen, sind Tools wie dieser SVG-Editor oder SVGOMG Ihre Freunde. Das Komprimieren der Dateien mit diesen Tools dauert nur wenige Sekunden und reduziert Ihre Dateigröße erheblich. Aber wenn Sie Ihr SVG inline verwenden müssen, um es zu animieren oder mit dem Code zu interagieren, gibt es immer noch viel, was Sie für die *Code-Lesbarkeit* tun können.
Das Wiederverwenden von Inhalten mit dem SVG-Element <use> ist nicht immer eine Option, aber wenn es eine ist, werden Sie es nicht bereuen, ein paar zusätzliche Minuten zu investieren, um es in die Praxis umzusetzen.
In diesem Artikel zeige ich ein Beispiel, bei dem ich dieses Element stark nutzen konnte – nicht nur, um die Dateigröße gering zu halten, sondern auch für einen klareren Markup, der besser lesbar und einfach zu warten wurde.
Dies ist das erste Design, mit dem ich arbeiten musste. Es wurde ursprünglich in Illustrator erstellt.

Werfen Sie einen Blick auf den folgenden Code. Dies ist die Originaldatei, die direkt aus der Software exportiert wurde und 2,05 KB wiegt:
Es ist überhaupt keine schwere Datei. Wenn Sie sie jedoch öffnen, werden Sie feststellen, dass es viele leere Tags, veraltete Namespaces, unnötige Leerzeichen, Kommas und zusätzliche Informationen gibt, die von der Software hinzugefügt wurden. Das macht den Code schwer zu handhaben, mühsam zu überfliegen und erzeugt ein langes Scrollen bei hunderten von Zeilen in Ihrem Dokument.
Sie werden auch feststellen, dass die Datei tatsächlich die Elemente <use> und <defs> verwendet, aber nicht auf die bestmögliche Weise. Und das ist nicht die Schuld der Software! Jede Astronautenillustration in der Originaldatei hat eine Maskierung: ein unsichtbarer Kreis, der wie ein Fenster wirkt, durch das wir unseren Charakter sehen können. Ohne ihn würde der Anzug des Astronauten außerhalb des Kreises überlaufen. Es gibt ein paar Möglichkeiten, dies in Illustrator zu vermeiden, z. B. das Zuschneiden dieser zusätzlichen Teile mit einer Pfadfinderoption. Auf diese Weise würden wir ein paar Bytes sparen und einen zusätzlichen Kreis vermeiden, der nur für die Maskierungsinformationen der Grafik verwendet wird, die wir nicht anzeigen. **Die Komprimierung der Datei beginnt in der Software.** Dennoch gibt es viele Dinge, die wir am Code verbessern können, falls wir die Originaldatei nicht bearbeiten möchten.
Das Komprimieren der SVG mit SVGOMG und das Beibehalten der Standardoptionen erfordert keinen Aufwand, und Sie erhalten eine Datei, die 1,46 KB wiegt. Das ist eine Reduzierung von 30 % im Vergleich zur Originalgröße, und die Grafik wird exakt gleich aussehen.
Wiederverwendung von Inhalten
Dies erfordert eine Überprüfung des SVG und einige Anpassungen. Ich weiß, dass diese Option im Vergleich zum vorherigen Beispiel mehr Zeit in Anspruch nimmt, aber sie ist nicht so schwer, wie es scheint.
Wir haben ein wiederholtes Element, den Astronauten im Kreis. Das ist das, was wir in SVGOMG komprimieren werden. Das Ergebnis wird etwa so aussehen:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 95.8 95.8">
<style>.st3,.st4{fill:#ffcb2f;stroke:#12192c;stroke-width:1.4891;stroke-miterlimit:10}.st4{fill:#69b2b1}</style>
<circle cx="47.9" cy="47.9" r="47.9" fill="#12192c"/>
<circle cx="47.9" cy="47.9" r="40.7" fill="#f6a2a4"/>
<defs><circle id="SVGID_1_" cx="47.9" cy="47.9" r="40.7"/></defs>
<clipPath id="SVGID_2_"><use xlink:href="#SVGID_1_" overflow="visible"/></clipPath>
<g clip-path="url(#SVGID_2_)">
<path class="st3" d="M63.9 45.6H32c-4 0-7.2 1.9-7.3 4.3l-.8 26.6H72l-.8-26.6c-.2-2.5-3.4-4.3-7.3-4.3z"/>
<path class="st4" d="M74.3 86.9L66 88.2C53.8 90 41.4 90 29.1 88.1l-7.7-1.2v-14c0-4 3.2-7.2 7.2-7.2h38.5c4 0 7.2 3.2 7.2 7.2v14z"/>
<path class="st3" d="M31.8 47.3h-.6c-.7 0-1.2-.6-1.2-1.2V23.2c0-.7.6-1.2 1.2-1.2h.6c.7 0 1.2.6 1.2 1.2v22.9c0 .7-.6 1.2-1.2 1.2z"/>
<circle class="st4" cx="31.5" cy="20.7" r="2.8"/>
<circle class="st4" cx="47.9" cy="51.4" r="20.3"/>
<path d="M64.5 53.1c0 8-7.4 11.2-16.5 11.2S31.4 61 31.4 53.1s7.4-14.4 16.5-14.4 16.6 6.4 16.6 14.4z" fill="#13192d" stroke="#12192c" stroke-width="1.489" stroke-miterlimit="10"/>
<path fill="none" stroke="#12192c" stroke-width="1.489" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-dasharray="9.6793,3.7228" d="M65.9 88V76.9"/>
<path fill="none" stroke="#12192c" stroke-width="1.489" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M29.6 87.9v-11"/>
</g>
</svg>
Erste Empfehlungen:
- Verschieben Sie den Inhalt von
<style>in die CSS-Datei (vorausgesetzt, Sie können Ihr SVG inline verwenden und haben ein Stylesheet in Ihrem Dokument verlinkt). - Benennen Sie die IDs so um, dass sie für Sie sinnvoll sind.
- Runden Sie diese komplizierten Zahlen, wie z. B.
stroke-width="1.489"aufstroke-width="1.5". Dies kann passieren, wenn Sie Ihre Vektoren in Illustrator mit der Option "Skalieren von Rändern" (scaling borders) umändern. - Entfernen Sie
stroke-miterlimit="10", da wir es nicht benötigen, da unserstroke-linejoinrund ist. - Dieser Code wird unsere Astronautenvorlage sein. Wir müssen alles in eine Gruppe packen, dieser Gruppe eine ID geben und sie innerhalb eines
<defs>-Tags platzieren. Beachten Sie, dass wir bereits ein<defs>-Element mit einem Kreis darin haben. Wir können diesen entfernen, da er Teil eines größeren<defs>-Tags sein wird.
Beachten Sie, dass die ersten beiden Kreise gefüllte Formen mit unterschiedlichem Radius und unterschiedlicher Farbe sind. Wir können den kleineren beibehalten und einen ausreichend großen Strich hinzufügen, um den gleichen Effekt zu erzielen – wieder etwas, das wir vermeiden könnten, indem wir in Illustrator von vornherein einen Kreis mit Rand verwenden.
Eine weitere wichtige Sache ist, dass unsere aktuelle viewBox zu klein für das ist, was wir bauen wollen. Machen wir sie größer und fügen wir etwas negativen Raum auf der X-Achse hinzu, damit wir unseren Astronauten von der Mitte aus klonen können.
Um mehr über viewBox zu erfahren, lesen Sie diesen wunderschönen Leitfaden zum Skalieren von SVG von Amelia Wattenberger.
Am Ende werden wir etwas wie das hier haben:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-400 0 1000 5000">
<defs>
<g id="astronaut">
<circle cx="94.5" cy="48" r="44" fill="currentColor" stroke="#12192c" stroke-width="8"/><clipPath id="a"><circle cx="94.5" cy="47.9" r="40"/></clipPath>
<g clip-path="url(#a)"><path class="st3" d="M110.5 45.6H78.6c-4 0-7.2 1.9-7.3 4.3l-.8 26.6h48.1l-.8-26.6c-.1-2.5-3.4-4.3-7.3-4.3z"/><path class="st4" d="M121 86.9l-8.3 1.3C100.4 90 88 90 75.8 88.1l-7.7-1.2v-14c0-4 3.2-7.2 7.2-7.2h38.5c4 0 7.2 3.2 7.2 7.2v14z"/><path class="st3" d="M78.4 47.3h-.6c-.7 0-1.2-.6-1.2-1.2V23.2c0-.7.6-1.2 1.2-1.2h.6c.7 0 1.2.6 1.2 1.2v22.9c0 .7-.5 1.2-1.2 1.2z"/><circle class="st4" cx="78.1" cy="20.7" r="2.8"/><circle class="st4" cx="94.5" cy="51.4" r="20.3"/><path d="M111.1 53.1c0 8-7.4 11.2-16.5 11.2S78 61 78 53.1s7.4-14.4 16.5-14.4 16.6 6.4 16.6 14.4z" fill="#13192d" /><path fill="none" stroke="#12192c" stroke-width="1.5" stroke-linecap="round" d="M112.5 88V76.9"/><path fill="none" stroke="#12192c" stroke-width="1.5" stroke-linecap="round" d="M76.3 87.9v-11"/></g>
</g>
</defs>
</svg>
Was sich im <defs> befindet, wird nirgendwo gerendert. Um unseren Astronauten zu klonen, müssen wir seine ID innerhalb eines <use>-Elements wie folgt verlinken:
<use xlink:href="#astronaut"/>
xlink:href ist seit SVG2 veraltet, aber es ist besser, es aus Kompatibilitätsgründen zu verwenden. Sie können href in modernen Browsern verwenden, aber ich habe es auf Safari getestet und es funktionierte zum Zeitpunkt des Schreibens nicht. Wenn Sie xlink:href verwenden, stellen Sie sicher, dass Sie diesen Namespace in Ihrem SVG-Tag einfügen: xmlns: xlink="http://www.w3.org/1999/xlink (Sie benötigen ihn nicht, wenn Sie sich entscheiden, href zu verwenden).
Jetzt können wir den entsprechenden Text zu dieser ersten Abbildung hinzufügen und ihn mit dem Transform-Attribut ausrichten. Wir platzieren beide Elemente besser innerhalb einer Gruppe, damit wir in zukünftigen Instanzen die gesamte Gruppe an die gewünschte Position verschieben können.
<g transform="translate(-95 210)">
<use xlink:href="#astronaut"/>
<text transform="translate(25 130)">Tech Leader</text>
</g>
Die Verbindungslinien sind einfache Formen, die direkt mit <path> gezeichnet werden können. Pfade sehen beängstigend aus, aber für Linien gibt es nicht viel zu befürchten. Ich werde diesen Code erklären.
<path class="line" d="M-4 200v-25h200"/>
d="" steht für Daten und dort werden wir unsere Befehle platzieren. M bedeutet, unsere Hand zu der Stelle zu bewegen, an der wir mit dem Zeichnen beginnen werden (aber es zeichnet nichts). -4 200 bedeutet, dass wir unseren Stift vier Einheiten nach links und 200 nach unten von unserer viewBox aus platzieren (entsprechend der Ausrichtung des SVG-Koordinatensystems). v ist der Befehl, mit dem Zeichnen einer vertikalen Linie zu beginnen, die von dieser Stelle aus 25 Einheiten nach oben verläuft. h steht für horizontal, also zeichnen wir von dort eine Linie 200 nach rechts. Es fühlt sich an wie Logo-Writer.
Ich habe die Linien in drei Pfade aufgeteilt, aber wir können auch nur einen mit dem M-Wert nach einer Reihe von Befehlen verwenden, um unsere Hand zu bewegen und von einem neuen Punkt im Koordinatensystem aus zu zeichnen.
Werfen Sie einen Blick auf das endgültige Dokument. Jetzt wiegt die Datei 779 Bytes und hat 12 Zeilen lesbaren und skalierbaren Codes.
Wenn wir in den Attributen, die wir in <defs> definiert haben, einen Wert angeben, ist es aufgrund der Natur des <use>-Elements nicht möglich, ihn in seinen Klonen zu ändern. Deshalb wurde im obigen Beispiel die Füllung des Hauptkreises durch den Wert currentColor ersetzt, um die Hintergründe aller Replikationen kontrollieren zu können. currentColor übernimmt den CSS-Farbwert des Elements (oder eines darüber liegenden Elements). Im SVG füge ich einigen replizierten Astronauten eine Klasse hinzu und gebe diesen Klassen einen Farbwert in CSS. Auf diese Weise kann ich alle Instanzen des <use>-Elements mit dieser Klasse ändern. Um mehr über <use> und die Gestaltung seines Inhalts zu erfahren, bietet dieser Beitrag von Sara Soueidan alles, was Sie wissen müssen.
Mit diesem fertigen Code können wir die Grafik viel einfacher auf etwas wie das hier skalieren.

Hier sind die drei Beispiele nebeneinander, um die Lesbarkeit und die Menge des Codes zu vergleichen. Wir sind von 241 auf 10 saubere Zeilen gekommen.

Schön, die Verwendung von
<use>hervorzuheben. Ich benutze es täglich, aber ich verwende <symbol> anstelle von <defs> innerhalb des SVG. Ist das nicht der Grund, warum das Symbol-Element überhaupt existiert?Guter Punkt, iGadget! Sie haben Recht, ich hätte
<symbol>anstelle von<defs>verwenden können. Ich denke, in meinem Kopf ist<symbol>besser für ein System (wie ein Icon-System) geeignet. In diesem Beispiel habe ich nur eine wiederholte Figur verwendet und keine Vorteile der Attribute genutzt, die<symbol>anbietet, wie viewBox, title, preserveAspectRatio...Toller Artikel! Wirklich schön, Ihre Aufschlüsselung des Prozesses und der Zeichensequenz zu sehen.
Danke, alioso! Ich schätze es!
Es wäre interessant, die Dateigröße vor und nach der Gzip-Komprimierung zu vergleichen. Da die Komprimierung am besten funktioniert, wenn wiederholte Daten vorhanden sind, sollte das mehrmalige Definieren desselben Elements nach der Komprimierung nur geringe Auswirkungen auf die Dateigröße haben.
Natürlich ist das Extrahieren des Elements wegen des DRY-Prinzips besser für die Wartung, aber meiner Erfahrung nach werden SVGs selten von Hand geschrieben/bearbeitet. Meistens exportiert der Designer die Datei und durchläuft einen automatischen Optimierungsprozess, bevor sie auf der Website angezeigt wird, ohne manuelle Eingriffe.
Absolut! Gzip ist immer ein guter Verbündeter.
Ich verstehe, dass manuelle Optimierung nicht der übliche Fall ist. Ich nutze sie viel, weil ich oft in den Code eingreife, um Klassen für Animationen hinzuzufügen.
In diesem speziellen Beispiel haben wir dieses Organigramm verwendet, um nur die vorhandenen Rollen in einem Team anzuzeigen, sodass Informationen dynamisch ein- oder ausgeblendet wurden, je nach Struktur jedes Teams. Die Möglichkeit, diese Einfachheit im Code zu haben, war für diese Aufgabe sehr nützlich.