perf: Produktbilder werden als AVIF ausgeliefert
Docker Image bauen und veroeffentlichen / build-and-push (push) Successful in 2m43s
Docker Image bauen und veroeffentlichen / build-and-push (push) Successful in 2m43s
next/image lieferte bisher nur WebP (die Next.js-Vorgabe). Am Hero-Bild der
Startseite (wabenhain.com, 1920x1280) nachgemessen, mit genau den
Einstellungen, die Next.js selbst verwendet — WebP q75 gegen AVIF q47
(image-optimizer.js skaliert die Qualitaet mit 50/80) bei effort 3:
Breite WebP AVIF
640 21,2 kB 12,0 kB -43 %
828 30,2 kB 17,4 kB -42 %
1080 44,4 kB 26,5 kB -40 %
1920 105,0 kB 65,7 kB -37 %
Auf einer Shop-Uebersicht mit einem Dutzend Kacheln ist das der groesste
einzelne Posten der Seite. Browser ohne AVIF-Unterstuetzung bekommen
unveraendert WebP, ganz alte das Original; die Auswahl trifft Next.js anhand
des Accept-Headers.
Die Kodierdauer spricht nicht dagegen: bei effort 3 lag AVIF in derselben
Messung durchgehend gleichauf oder schneller als WebP (1920 px: 60 ms gegen
122 ms). minimumCacheTTL steigt trotzdem von den voreingestellten vier Wochen
auf ein Jahr — nicht wegen der Kodierdauer, sondern weil hochgeladene Bilder
unveraenderlich sind: lib/uploads.ts legt jede Datei unter einem eigenen
Namen ab, ein ausgetauschtes Produktbild bekommt also eine neue URL. Ein
kurzes TTL wirft hier nur brauchbare Ergebnisse weg.
Dazu zwei ausdrueckliche Festschreibungen, die das bisherige Verhalten
dokumentieren statt es zu aendern:
- qualities: [75] entspricht der Vorgabe von Next.js 16, die andere Werte
bereits ablehnt (gegen die laufende Seite geprueft: ?q=42 antwortet mit
400). Ausgeschrieben, damit eine spaetere Erweiterung der Liste eine
bewusste Entscheidung ist und nicht unbemerkt Kodier-Last je Wert oeffnet.
- dangerouslyAllowSVG: false entspricht ebenfalls der Vorgabe. Ausgeschrieben,
weil ein SVG ein Dokument ist, das Skripte enthalten kann, und hier
same-origin ausgeliefert wuerde.
tsc: 0 Fehler. vitest: 359/359 gruen. eslint: 0 Warnungen. next build: gruen.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
1 parent
73c070f11e
commit
7dd42e35bc
1 file changed
+37
@@ -25,6 +25,43 @@ const nextConfig: NextConfig = {
|
|||||||
// werden."
|
// werden."
|
||||||
serverExternalPackages: ["pdfkit", "ffmpeg-static"],
|
serverExternalPackages: ["pdfkit", "ffmpeg-static"],
|
||||||
|
|
||||||
|
images: {
|
||||||
|
// AVIF vor WebP. Next.js liefert das erste Format, das der Browser laut
|
||||||
|
// Accept-Header unterstuetzt; Browser ohne AVIF bekommen unveraendert
|
||||||
|
// WebP, ganz alte das Original.
|
||||||
|
//
|
||||||
|
// Am Hero-Bild der Startseite nachgemessen (1920x1280), mit den
|
||||||
|
// Einstellungen aus next/dist/server/image-optimizer.js — WebP q75 gegen
|
||||||
|
// AVIF q47 (Next.js skaliert die Qualitaet mit 50/80) bei effort 3:
|
||||||
|
// 640 px -43 %, 828 px -42 %, 1080 px -40 %, 1920 px -37 %.
|
||||||
|
//
|
||||||
|
// Die Kodierdauer spricht nicht dagegen: bei effort 3 lag AVIF in
|
||||||
|
// derselben Messung gleichauf oder schneller als WebP (1920 px: 60 ms
|
||||||
|
// gegen 122 ms). Die frueher hier vermutete teure Erstkodierung gibt es
|
||||||
|
// in dieser Einstellung nicht.
|
||||||
|
formats: ["image/avif", "image/webp"],
|
||||||
|
|
||||||
|
// Ein Jahr statt der Next.js-Vorgabe von vier Wochen. Hochgeladene Bilder
|
||||||
|
// sind unveraenderlich: lib/uploads.ts legt jede Datei unter einem eigenen
|
||||||
|
// Namen ab, ein ausgetauschtes Produktbild bekommt also eine neue URL.
|
||||||
|
// Ein kurzes TTL wuerde hier nur brauchbare Ergebnisse wegwerfen.
|
||||||
|
minimumCacheTTL: 60 * 60 * 24 * 365,
|
||||||
|
|
||||||
|
// Entspricht der Vorgabe von Next.js 16, die andere Werte bereits ablehnt
|
||||||
|
// (gegen die laufende Seite geprueft: ?q=42 antwortet mit 400) — aendert
|
||||||
|
// das Verhalten also nicht. Ausgeschrieben, damit eine spaetere
|
||||||
|
// Erweiterung der Liste eine bewusste Entscheidung ist: jeder zusaetzlich
|
||||||
|
// erlaubte Wert oeffnet einen eigenen Cache-Eintrag und eine eigene
|
||||||
|
// Kodierung je Bild, von aussen ueber die URL ausloesbar.
|
||||||
|
qualities: [75],
|
||||||
|
|
||||||
|
// Ebenfalls die Vorgabe, ausdruecklich festgehalten: ein SVG ist ein
|
||||||
|
// Dokument, das Skripte enthalten kann — same-origin ausgeliefert waere
|
||||||
|
// das ein XSS-Vektor. Diese Zeile soll verhindern, dass der Schalter
|
||||||
|
// spaeter beilaeufig umgelegt wird.
|
||||||
|
dangerouslyAllowSVG: false,
|
||||||
|
},
|
||||||
|
|
||||||
// Turbopacks Dateisystem-Caches (.next/dev/cache & .next/cache/turbopack)
|
// Turbopacks Dateisystem-Caches (.next/dev/cache & .next/cache/turbopack)
|
||||||
// kollidieren in diesem OneDrive-synchronisierten Arbeitsverzeichnis
|
// kollidieren in diesem OneDrive-synchronisierten Arbeitsverzeichnis
|
||||||
// wiederholt mit der Cloud-Synchronisierung ("Failed to open database" /
|
// wiederholt mit der Cloud-Synchronisierung ("Failed to open database" /
|
||||||
|
|||||||
Reference in new issue
Block a user