Gatsby leistet hervorragende Arbeit bei der Verarbeitung und Handhabung von Bildern. Zum Beispiel hilft es Ihnen, Zeit bei der Bildoptimierung zu sparen, da Sie nicht jedes Bild manuell optimieren müssen.
Mit Plugins und etwas Konfiguration können Sie sogar Bildvorabladung und eine Technik namens Blur-Up für Ihre Bilder mit Gatsby einrichten. Dies trägt zu einer reibungsloseren Benutzererfahrung bei, die schneller und ansprechender ist.
Ich fand die Kombination aus gatsby-source-filesystem, GraphQL, Sharp Plugins und gatsby-image ziemlich mühsam zu organisieren und unintuitiv, besonders wenn man bedenkt, dass es sich um eine ziemlich gängige Funktionalität handelt. Hinzu kommt, dass gatsby-image ganz anders funktioniert als ein normales <img>-Tag, und die Implementierung allgemeiner Anwendungsfälle für Websites könnte komplex werden, wenn Sie das gesamte System konfigurieren.

Wenn Sie dies noch nicht getan haben, sollten Sie die gatsby-image Docs durchlesen. Es ist die React-Komponente, die Gatsby verwendet, um responsive, lazy-geladene Bilder zu verarbeiten und zu platzieren. Zusätzlich speichert sie die Bildposition, was Seitenumbrüche beim Laden verhindert, und Sie können sogar Blur-Up-Vorschauen für jedes Bild erstellen.
Für responsive Bilder würden Sie *im Allgemeinen* ein <img>-Tag mit einer Reihe von Bildern in passenden Größen im srcset-Attribut verwenden, zusammen mit einem sizes-Attribut, das die Layoutsituation informiert, in der das Bild verwendet wird.
<img srcset="img-320w.jpg 320w,
img-480w.jpg 480w,
img-800w.jpg 800w"
sizes="(max-width: 320px) 280px,
(max-width: 480px) 440px,
800px"
src="img-800w.jpg">
Sie können mehr darüber lesen, wie dies funktioniert, in den Mozilla Docs. Dies ist einer der Vorteile der Verwendung von gatsby-image überhaupt: Es erledigt die gesamte Größenanpassung und Komprimierung automatisch und übernimmt die Aufgabe, srcset-Attribute in einem <img />-Tag einzurichten.
Verzeichnisstruktur für Bilder
Projekte können leicht an Größe und Komplexität zunehmen. Selbst eine Einzelseiten-Website kann eine ganze Menge Bildressourcen enthalten, von Icons bis hin zu vollständigen Galerien. Es ist hilfreich, Bilder in einer bestimmten Reihenfolge zu organisieren, anstatt alle in einem einzigen Verzeichnis auf dem Server anzuhäufen. Dies hilft uns, die Verarbeitung intuitiver einzurichten und eine Trennung der Belange zu schaffen.
Bei dem Versuch, Dateien zu organisieren, ist noch zu beachten, dass Gatsby eine benutzerdefinierte Webpack-Konfiguration verwendet, um alle Dateien in einem Projekt zu verarbeiten, zu minifizieren und zu exportieren. Die generierte Ausgabe wird in einem /public-Ordner platziert. Die Gesamtstruktur, die gatsby-starter-default verwendet, sieht so aus
/
|-- /.cache
|-- /plugins
|-- /public
|-- /src
|-- /pages
|-- /components
|-- /images
|-- html.js
|-- /static (not present by default)
|-- gatsby-config.js
|-- gatsby-node.js
|-- gatsby-ssr.js
|-- gatsby-browser.js
Lesen Sie mehr darüber, wie die Gatsby-Projektstruktur funktioniert, hier.
Beginnen wir mit den gängigen Bilddateien, auf die wir stoßen und die wir organisieren müssten
Zum Beispiel
- icons
- Logos
- Favicon
- Dekorative Bilder (im Allgemeinen Vektor- oder PNG-Dateien)
- Bildergalerie (z. B. Team-Headshots auf einer Über-uns-Seite oder etwas Ähnliches)
Wie *gruppieren* wir diese Assets? Unter Berücksichtigung unseres Effizienz-Ziels und der oben genannten Gatsby-Projektstruktur wäre der beste Ansatz, sie in zwei Gruppen aufzuteilen: eine Gruppe, die keine Verarbeitung benötigt und direkt in das Projekt importiert wird; und eine weitere Gruppe für Bilder, die Verarbeitung und Optimierung erfordern.
Ihre Definitionen mögen unterschiedlich sein, aber diese Gruppierung könnte etwa so aussehen
Statisch, keine Verarbeitung erforderlich
- Icons und Logos, die keine Verarbeitung benötigen
- Voroptimierte Bilder
- Favicons
- Andere Vektordateien (wie dekorative Grafiken)
Verarbeitung erforderlich
- Nicht-Vektor-Grafiken (z. B. PNG- und JPG-Dateien)
- Galeriebilder
- Jedes andere Bild, das verarbeitet werden kann, d. h. im Grunde gängige Bildformate außer Vektoren
Nachdem wir die Dinge in eine gewisse Ordnung gebracht haben, können wir mit der Verwaltung jeder dieser Gruppen fortfahren.
Die Gruppe „statisch“
Gatsby bietet einen sehr einfachen Prozess für den Umgang mit der statischen Gruppe: Fügen Sie alle Dateien in einen Ordner namens static im Stammverzeichnis des Projekts ein. Der Bundler kopiert automatisch den Inhalt in den public-Ordner, von wo aus die endgültige Build direkt auf die Dateien zugreifen kann.
Angenommen, Sie haben eine Datei namens logo.svg, die keine Verarbeitung benötigt. Platzieren Sie sie im static-Ordner und verwenden Sie sie in einer Komponentendatei wie folgt
import React from "react"
// Tell webpack this JS file requires this image
import logo from "../../static/logo.svg"
function Header() {
// This can be directly used as image src
return <img src={logo} alt="Logo" />
}
export default Header
Ja, so einfach ist das – ähnlich wie beim Importieren einer Komponente oder Variable und deren anschließender direkter Verwendung. Gatsby bietet detaillierte Dokumentation zum direkten Importieren von Assets in Dateien, die Sie zur weiteren Klärung heranziehen können.
Sonderfall: Favicon
Das Plugin gatsby-plugin-manifest fügt nicht nur eine manifest.json-Datei zum Projekt hinzu, sondern generiert auch Favicons für alle erforderlichen Größen und bindet sie in die Website ein.
Mit minimaler Konfiguration haben wir Favicons, kein manuelles Größenanpassen mehr und kein Hinzufügen einzelner Links im HTML-Head mehr. Platzieren Sie favicon.svg (oder .png oder welches Format auch immer Sie verwenden) im static-Ordner und passen Sie die Datei gatsby-config.js mit den Einstellungen für gatsby-plugin-manifest an.
{
resolve: `gatsby-plugin-manifest`,
options: {
name: `Absurd`,
icon: `static/favicon.svg`,
},
},
Die Gruppe „verarbeitet“
Idealerweise möchten wir, dass gatsby-image wie ein img-Tag funktioniert, bei dem wir den src angeben und es im Hintergrund die gesamte Verarbeitung durchführt. Leider ist es nicht so einfach. Gatsby verlangt, dass Sie gatsby-source-filesystem für die Dateien konfigurieren, dann GraphQL verwenden, um sie mithilfe von Gatsby Sharp Plugins (z. B. gatsby-transformer-sharp, gatsby-plugin-sharp) mit gatsby-image abzufragen und zu verarbeiten. Das Ergebnis ist ein responsives, lazy-geladenes Bild.
Anstatt Sie durch die Einrichtung der Bildverarbeitung in Gatsby zu führen (was bereits gut in den Gatsby-Docs dokumentiert ist), zeige ich Ihnen einige Ansätze, um diesen Prozess für einige gängige Anwendungsfälle zu optimieren. Ich gehe davon aus, dass Sie grundlegende Kenntnisse über die Bildverarbeitung in Gatsby haben – aber wenn nicht, empfehle ich Ihnen dringend, zuerst die Dokumentation durchzulesen.
Anwendungsfall: Eine Bildergalerie
Nehmen wir den gängigen Fall von Profilbildern auf einer Über-uns-Seite. Die Anordnung ist im Grunde ein Array von Daten mit Titel, Beschreibung und Bild als Raster oder Sammlung in einem bestimmten Abschnitt.
Das Datenarray würde etwa so aussehen
const TEAM = [
{
name: 'Josh Peck',
image: 'josh.jpg',
role: 'Founder',
},
{
name: 'Lisa Haydon',
image: 'lisa.jpg',
role: 'Art Director',
},
{
name: 'Ashlyn Harris',
image: 'ashlyn.jpg',
role: 'Frontend Engineer',
}
];
Lassen Sie uns nun alle Bilder (josh.jpg, lisa.jpg und so weiter) in src/images/team platzieren. Sie können einen Ordner in images basierend auf der Gruppe erstellen, zu der er gehört. Da wir uns mit Teammitgliedern auf einer Über-uns-Seite beschäftigen, haben wir uns für images/team entschieden. Der nächste Schritt ist, diese Bilder abzufragen und mit den Daten zu verknüpfen.
Um diese Dateien im Gatsby-System für die Verarbeitung verfügbar zu machen, verwenden wir gatsby-source-filesystem. Die Konfiguration in gatsby-config.js für diesen speziellen Ordner würde so aussehen
{
resolve: `gatsby-source-filesystem`,
options: {
name: `team`,
path: `${__dirname}/src/images/team`,
},
`gatsby-transformer-sharp`,
`gatsby-plugin-sharp`,
},
Um ein Array von Dateien aus diesem speziellen Ordner abzufragen, können wir sourceInstanceName verwenden. Es nimmt den Wert des Namens an, der in gatsby-config.js angegeben ist.
{
allFile(filter: { sourceInstanceName: { eq: "team" } }) {
edges {
node {
relativePath
childImageSharp {
fluid(maxWidth: 300, maxHeight: 400) {
...GatsbyImageSharpFluid
}
}
}
}
}
}
Dies gibt ein Array zurück
// Sharp-processed image data is removed for readability
{
"data": {
"allFile": {
"edges": [
{
"node": {
"relativePath": "josh.jpg"
}
},
{
"node": {
"relativePath": "ashlyn.jpg"
}
},
{
"node": {
"relativePath": "lisa.jpg"
}
}
]
}
}
Wie Sie sehen können, verwenden wir relativePath, um die benötigten Bilder mit dem Element im Datenarray zu verknüpfen. Etwas schnelle JavaScript könnte hier helfen
// Img is gatsby-image
// TEAM is the data array
TEAM.map(({ name, image, role }) => {
// Finds associated image from the array of images
const img = data.allFile.edges.find(
({ node }) => node.relativePath === image
).node;
return (
<div>
<Img fluid={img.childImageSharp.fluid} alt={name} />
<Title>{name}</Title>
<Subtitle>{role}</Subtitle>
</div>
);
})
Das ist das Nächstliegende, was wir dem Verwenden von src nahe kommen, ähnlich wie bei <img>-Tags.
Anwendungsfall: Grafiken
Obwohl Grafiken mit demselben Dateityp erstellt werden können, sind die Dateien normalerweise in verschiedenen Abschnitten (z. B. Seiten und Komponenten) verteilt, wobei jede normalerweise unterschiedliche Abmessungen hat.
Es ist ziemlich klar, dass das Abfragen des gesamten Arrays, wie wir es zuvor getan haben, nicht funktioniert. Wir können jedoch immer noch alle Bilder in einem einzigen Ordner organisieren. Das bedeutet, dass wir sourceInstanceName immer noch verwenden können, um anzugeben, aus welchem Ordner wir das Bild abfragen.
Ähnlich wie bei unserem vorherigen Anwendungsfall erstellen wir einen Ordner namens src/images/art und konfigurieren gatsby-source-filesystem. Bei der Abfrage, anstatt das gesamte Array abzurufen, fragen wir hier nach dem spezifischen Bild, das wir in der Größe und Spezifikation nach unseren Anforderungen benötigen.
art_team: file(
sourceInstanceName: { eq: "art" }
name: { eq: "team_work" }
) {
childImageSharp {
fluid(maxWidth: 1600) {
...GatsbyImageSharpFluid
}
}
}
Dies kann direkt in der Komponente verwendet werden
<Img fluid={data.art_team.childImageSharp.fluid} />
Darüber hinaus kann dies für jede Komponente oder jeden Abschnitt wiederholt werden, der ein Bild aus dieser Gruppe benötigt.
Sonderfall: Inlining von SVGs
Gatsby kodiert kleinere Bilder automatisch in ein Base64-Format und platziert die Daten inline, um die Anzahl der Anfragen zur Leistungssteigerung zu reduzieren. Das ist im Allgemeinen großartig, kann aber für SVG-Dateien ein Nachteil sein. Stattdessen können wir SVGs manuell bearbeiten, um die gleichen Leistungsvorteile zu erzielen, oder im Falle, dass wir Dinge interaktiver gestalten möchten, Animationen integrieren.
Ich habe gatsby-plugin-svgr als die bequemste Lösung hier gefunden. Es ermöglicht uns, alle SVG-Dateien als React-Komponenten zu importieren
import { ReactComponent as GithubIcon } from './github.svg';
Da wir technisch gesehen SVG-Dateien und nicht Rasterbilder verarbeiten, wäre es sinnvoll, die SVG-Datei aus dem static-Ordner zu verschieben und sie im Ordner der Komponente zu platzieren, die sie verwendet.
Fazit
Nachdem ich auf ein paar Projekten mit Gatsby gearbeitet habe, sind dies einige der Wege, wie ich Hindernisse bei der Arbeit mit Bildern überwunden habe, um diesen schönen Blur-Up-Effekt zu erzielen. Ich dachte, sie könnten für Sie nützlich sein, insbesondere für die gängigen Anwendungsfälle, die wir uns angesehen haben.
Alle hier verwendeten Konventionen stammen aus dem gatsby-absurd Starter-Projekt, das ich auf GitHub eingerichtet habe. Hier ist das Ergebnis
Es ist eine gute Idee, sich das anzusehen, wenn Sie Beispiele für die Verwendung in einem Projekt sehen möchten. Schauen Sie sich Team.js an, um zu sehen, wie mehrere Bilder aus derselben Gruppe abgefragt werden. Andere Abschnitte – wie About.js und Header.js – veranschaulichen, wie Design-Grafiken (die Gruppe der über verschiedene Abschnitte geteilten Bilder) abgefragt werden. Footer.js und Navbar.js enthalten Beispiele für die Handhabung von Icons.
Danke, aber NEIN, danke.
Es erscheint zu kompliziert.
Meine Lösung ist viel einfacher.
inotify erkennt neue Bilder in einem bestimmten Verzeichnis und führt native Linux-Befehle aus, um neue Bilder zu skalieren und zu optimieren.
In wenigen Zeilen Bash-Skript erledigt.
Sie sollten einen Artikel darüber schreiben, wie! Ich würde ihn gerne lesen.