Wichtigste Erkenntnisse
- Eine Smart-CDN-URL besteht aus einem Workspace, einem Template-Namen und einem Dateipfad, wobei Abfrageparameter Werte an das Template liefern.
- Das Template liest diese Parameter als Assembly Variables aus, sodass ${fields.w} zur Breite der Größenänderung werden kann.
- Nur die erste Anfrage für eine bestimmte Parameterkombination wird codiert; alle weiteren werden aus dem Cache beantwortet.
Bei der Auslieferung responsiver Bilder geht es vor allem darum, wo die Variantenliste verwaltet wird. Werden alle Größen vorab erzeugt, richten sich die Speicherkosten nach der Anzahl der Breakpoints. Werden die Größen bei Bedarf abgeleitet, entstehen die Kosten bei der ersten Anfrage jeder Variante; alle weiteren Anfragen werden aus einem vorgeschalteten Cache bedient.
Worauf es besonders ankommt
- AVIF und WebP können über die Variable ${browser.wanted_image_format} anhand des Accept-Headers des Browsers ausgewählt werden.
- Begrenzen Sie die Breiten, die über eine URL angefordert werden können, da jede einzelne Kombination ein separates Encoding auslöst.
- Eine signierte URL läuft ab. Die verbleibende Gültigkeitsdauer ihrer Signatur begrenzt zugleich, wie lange das Ergebnis cachefähig bleibt.
Das Template hinter der URL bereitstellen
Eine Smart-CDN-URL besteht aus drei Teilen und einem Abfragestring: dem Workspace als Subdomain von tlcdn.com, dem Namen eines Templates und dem Pfad der zu verarbeitenden Datei. Eine Anfrage an diese URL führt das Template aus. Die Abfrageparameter werden darin als Assembly Variables bereitgestellt, sodass ein Template, das die Größe auf ${fields.w} ändert, aus ?w=640 ein 640 Pixel breites Ergebnis erzeugt. Die Variantenliste wird nicht in das Frontend einkompiliert.
Diese Trennung bestimmt, welche Daten wohin gehören. Das Template enthält die Pipeline – Original importieren, transformieren und ausliefern –, während die URL nur die wenigen Werte übermittelt, die sich berechtigterweise je Anfrage unterscheiden. Da die Pipeline serverseitig bleibt, können eine geänderte Encoding-Qualität oder ein neuer Verarbeitungs-Step bereitgestellt werden, ohne das Markup einer einzigen Seite zu ändern.
{
"steps": {
"imported": {
"robot": "/s3/import",
"credentials": "my_s3_credentials",
"path": "/images/${fields.input}"
},
"resized": {
"use": "imported",
"robot": "/image/resize",
"resize_strategy": "fit",
"width": "${fields.w}"
},
"served": {
"use": "resized",
"robot": "/file/serve",
"cache_duration": 604800
}
}
}Workspace und Template
Die Subdomain identifiziert den Workspace, und das erste Pfadsegment benennt das auszuführende Template.
Dateipfad
Der restliche Pfad identifiziert das Original, das das Template verarbeiten soll.
Abfrageparameter
Diese Parameter erreichen das Template als Assembly Variables. So kann eine URL viele Größen ausliefern.
Zulässige URL-Parameter festlegen
Jede einzelne Parameterkombination erzeugt ein eigenes Ergebnis und damit einen eigenen Cache-Eintrag sowie bei der ersten Anfrage ein eigenes Encoding. Ein Layout, das jeweils die aktuelle Containerbreite anfordert, erzeugt eine unbegrenzte Menge nahezu identischer Bilder. Jedes davon wird einmal kostenpflichtig codiert und danach nur selten wiederverwendet. Eine kurze Liste mit Breiten aus realen Breakpoints verursacht nur wenige Encodings; alle weiteren Anfragen werden anschließend aus dem Cache bedient.
Hier liegt auch die Angriffsfläche für Missbrauch. Akzeptiert eine URL beliebige Abmessungen, kann jede Person, die sie findet, systematisch Breiten durchprobieren und Ihren Auslieferungsendpunkt zur Quelle hoher Encoding-Kosten machen. Durch das Signieren der URL entfällt diese Möglichkeit vollständig. Wenn das Signieren nicht praktikabel ist, begrenzt eine Validierung im Template den Schaden, indem sie eine angeforderte Breite beschränkt oder auf einen Standardwert zurückfällt.
Ein fester Satz von Breiten
Wählen Sie die Breiten anhand der Breakpoints aus, die das Design tatsächlich verwendet, und nicht anhand von Containermaßen.
Cache-Fragmentierung
Nahezu identische Varianten teilen den Traffic auf, für den sonst dasselbe Cache-Ergebnis verwendet würde.
Werte im Template begrenzen
Begrenzen Sie die Werte, die eine Anfrage anfordern kann, damit ein unerwarteter Parameter nicht hohe Kosten verursacht.
URL signieren und Ablaufzeit als Cache-Einstellung behandeln
Die Signierung erfolgt im Backend, da sie das Auth Secret benötigt. Die zu signierende Zeichenfolge besteht aus dem Workspace, dem Template-Namen und dem Dateipfad, gefolgt von den Abfrageparametern, die aufsteigend nach ihren Schlüsseln sortiert sind. Für den HMAC wird SHA256 verwendet, und das Ergebnis wird mit dem Präfix sha256: in einen sig-Parameter geschrieben. Beachten Sie, dass Smart-CDN-Signaturen SHA256 verwenden, während reguläre API-Anfragesignaturen SHA384 verwenden. Außerdem muss der Auth Key für die Nutzung mit Smart CDN aktiviert sein.
Beim Parameter exp, einem UNIX-Zeitstempel in Millisekunden, gilt es, eine wichtige Abwägung zu treffen. Er dient eindeutig der Zugriffskontrolle: Nach diesem Zeitpunkt funktioniert die URL nicht mehr. Zugleich steuert er das Caching, da die effektive Cache-Lebensdauer einer signierten Antwort durch die verbleibende Gültigkeitsdauer ihrer Signatur begrenzt wird. Eine kurze Gültigkeitsdauer erhöht die Sicherheit, verringert aber die Wiederverwendung des Cache. Eine lange hält Ergebnisse im Cache verfügbar und verlängert die Nutzbarkeit der URL.
import { Transloadit } from 'transloadit'
const transloadit = new Transloadit({
authKey: process.env.TL_KEY,
authSecret: process.env.TL_SECRET,
})
const url = transloadit.getSignedSmartCDNUrl({
workspace: 'my-workspace',
template: 'responsive-image',
input: 'canoe.jpg',
urlParams: { w: 640 },
})Aufsteigende Schlüsselreihenfolge
Die Parameter werden vor dem Signieren der Zeichenfolge nach ihren UTF-16-Codeeinheiten in aufsteigender Reihenfolge sortiert.
sig und exp
Moderne URLs verwenden diese beiden Parameter; die Legacy-Parameter s und expires sind veraltet.
Ablaufzeit begrenzt den Cache
Wählen Sie das Zeitfenster anhand der Vertraulichkeit der Inhalte und der gewünschten Cache-Wiederverwendung.
Format über den Accept-Header auswählen lassen
Moderne Formate sparen tatsächlich Bytes, und der Browser teilt bereits mit, welche er akzeptiert. Die Assembly Variable ${browser.wanted_image_format} wertet diese Angabe unter Berücksichtigung der Qualitätsgewichtungen im Header als avif, webp oder jpg aus. Liest ein Template diesen Wert in den Parameter format von /image/resize ein, erhält jeder Browser das beste Format, das er ausdrücklich unterstützt. Diese Auswahllogik erscheint nicht in Ihrem Markup, und es ist keine zweite URL erforderlich, um sie abzubilden.
Entscheidend ist, was jpg tatsächlich bedeutet. Ein Medienbereich mit Platzhalter führt einen Client bewusst nicht als unterstützend auf. Daher erhalten curl, die meisten SDKs und Server-zu-Server-Aufrufer diesen Wert – er beschreibt, was der Aufrufer akzeptiert, nicht das Format der Datei. Wird er direkt an format übergeben, wird bei jeder solchen Anfrage ein transparentes PNG oder animiertes GIF in JPEG konvertiert. Wenn Sie den Fallback stattdessen null zuordnen, behält /image/resize das Eingabeformat bei. Browser erhalten so ein modernes Format, während alle anderen das unveränderte Original erhalten.
{
"steps": {
"resized": {
"use": ":original",
"robot": "/image/resize",
"width": 800,
"format": "${browser.wanted_image_format === 'jpg' ? null : browser.wanted_image_format}"
},
"served": {
"use": "resized",
"robot": "/file/serve"
}
}
}avif und webp
Werden ausgewählt, wenn der Browser sie ausdrücklich akzeptiert; dabei werden Qualitätsgewichtungen berücksichtigt.
Der jpg-Fallback
Wird bei fehlenden Headern oder Headern zurückgegeben, die nur Platzhalter enthalten. Dies trifft auf die meisten Aufrufer außerhalb von Browsern zu.
Fallback null zuordnen
Behält bei der Größenänderung das Eingabeformat bei, sodass Transparenz und Animation den gesamten Verarbeitungsweg überstehen.
Cache-Hit-Rate als gesamtes wirtschaftliches Argument
Zwei Robots teilen die Kosten untereinander auf. Wenn Sie verstehen, welcher Robot wofür zuständig ist, lassen sich die meisten Überraschungen erklären. /file/serve berechnet nur dann Gebühren, wenn im CDN keine Kopie im Cache vorliegt und der Inhalt erneut erzeugt werden muss. Die Encoding-Kosten richten sich daher nach der Cache-Miss-Rate und nicht nach dem Traffic. /tlcdn/deliver übernimmt die globale Auslieferung. Seine Verwendung ergibt sich aus der Domain tlcdn.com, statt ausdrücklich in den Assembly Instructions angegeben zu werden. Die Bandbreite wird mit einer Mindestberechnung von 102.400 Bytes pro Auslieferung abgerechnet.
Die Standardwerte weisen Browser an, Inhalte 72 Stunden und CDNs 24 Stunden lang zwischenzuspeichern. Mit cache_duration für /file/serve überschreiben Sie beide gleichzeitig. Richten Sie den Wert danach aus, wie lange das zugrunde liegende Original gültig bleibt: Inhalte, die sich nie ändern, können lange im Cache bleiben, während Dateien, die nach einem Tag gelöscht werden, nicht länger am Edge vorgehalten werden sollten. Vermeiden Sie es, im Markup direkt auf einen Serve-Endpunkt ohne vorgeschaltetes CDN zu verweisen, da bei einer beliebten Seite dann jeder Aufruf ein neues Encoding auslöst.
Berechnung bei erneuter Erzeugung
Bei einer Variante im Cache fallen nur Auslieferungskosten an; das Encoding wird bei einem Cache-Miss berechnet.
cache_duration
Legt die Cache-Zeitfenster für Browser und CDN gemeinsam fest und ersetzt die Standardwerte von 72 Stunden und 24 Stunden.
Immer ein CDN vorschalten
Bei der direkten Auslieferung über einen Ursprungsendpunkt führt jeder Seitenaufruf zu einem weiteren Encoding.
Vary: Accept
Ausgehandelte Formate werden getrennt im Cache gespeichert. Daher vervielfacht jedes Format die Anzahl der Einträge, die eine Breite erzeugt.
Originale unter eigener Kontrolle aufbewahren
Das Template importiert zunächst das Original, üblicherweise mit /s3/import aus Ihrem eigenen Bucket. Dabei verwendet es einen aus der URL gebildeten Pfad wie /images/${fields.input}. Derivate sind ein Cache, kein dauerhafter Datensatz. Wenn Sie die Originale in Ihrem eigenen Speicher aufbewahren, bleibt die Beziehung einseitig: Alles Ausgelieferte lässt sich aus einer Datei rekonstruieren, die Sie besitzen, und nichts Wichtiges existiert ausschließlich als im Cache gespeicherte Variante.
Diese Anordnung macht ein Redesign kostengünstig. Neue Breakpoints erfordern neue Parameterwerte und eine Aufwärmphase, während sich der Cache füllt, aber keinen Migrationsprozess für gespeicherte Dateien. Deshalb ist auch ein Formatwechsel unkompliziert: Das Template fordert etwas anderes an, alte Varianten laufen ab, und die Originale werden nie verschoben.
Bei jeder Anfrage importieren
Das Template ruft das Original anhand eines aus der URL übernommenen Pfads aus Ihrem Speicher ab.
Derivate sind entbehrlich
Alles, was das CDN vorhält, kann erneut erzeugt werden. Der Verlust einer zwischengespeicherten Variante kostet daher einen einzigen Encoding-Vorgang.
Breakpoints können sich ändern
Eine neue Größe ist ein neuer Parameterwert und kein Batch-Verarbeitungsauftrag für gespeicherte Dateien.
Wissenswerte technische Details
- Eine Smart-CDN-URL hat die Form einer Workspace-Subdomain auf tlcdn.com, gefolgt vom Template-Namen und dem Dateipfad. Ihre Abfrageparameter gelangen als Assembly Variables wie ${fields.w} in das Template.
- Die ausgelieferte Antwort weist Browser standardmäßig an, Inhalte 72 Stunden und CDNs 24 Stunden lang zwischenzuspeichern. Der Parameter cache_duration für /file/serve überschreibt beide mit einer einzigen Einstellung.
- /file/serve wird nur berechnet, wenn im CDN keine Kopie im Cache vorliegt und der Inhalt erneut erzeugt werden muss. Dadurch hängen die Encoding-Kosten von der Cache-Hit-Rate statt vom Datenverkehr ab.
- Die globale Auslieferung übernimmt /tlcdn/deliver. Dies wird durch die Domain tlcdn.com vorgegeben und nicht in die Assembly Instructions geschrieben. Die Bandbreite wird mit einer Mindestberechnung von 102.400 Byte abgerechnet.
- Die Signatur ist ein HMAC SHA256 über den Workspace, den Template-Namen, den Dateipfad und die Abfrageparameter, die in aufsteigender Reihenfolge ihrer Schlüssel sortiert werden. Sie wird als Parameter sig übermittelt, dem sha256 und ein Doppelpunkt vorangestellt sind.
- Der Parameter exp ist ein UNIX-Zeitstempel in Millisekunden. Da die effektive Cache-Lebensdauer einer signierten Antwort durch die verbleibende Gültigkeitsdauer der Signatur begrenzt ist, betrifft deren Ablauf das Caching ebenso wie die Sicherheit.
- Die Assembly Variable ${browser.wanted_image_format} wird zu avif aufgelöst, wenn AVIF ausdrücklich akzeptiert wird, zu webp, wenn WebP das beste ausdrücklich akzeptierte moderne Format ist, und zu jpg, wenn der Header Accept fehlt oder nur Wildcards enthält. Qualitätsgewichtungen werden dabei berücksichtigt.
- Ein Wildcard-Medienbereich aktiviert für einen Client bewusst kein modernes Format. Dadurch bleibt für Aufrufe mit curl, über ein SDK oder zwischen Servern der Wert jpg erhalten. Wird dieser Wert stattdessen null zugeordnet, behält /image/resize das Eingabeformat bei.
- Smart-CDN-Antworten enthalten den Header Vary: Accept. Daher speichern Caches für jedes ausgehandelte Format einen separaten Eintrag, und die Anzahl der verwendeten Formate vervielfacht die Anzahl der gecachten Varianten entsprechend.
Ein praxisnaher Ansatz
- 1
Bewahren Sie die Originale in einem von Ihnen kontrollierten Speicher auf und importieren Sie sie mit /s3/import in das Template.
- 2
Stellen Sie in der URL eine kurze, feste Liste von Breiten bereit, statt einen unbegrenzten Parameter anzubieten.
- 3
Sorgen Sie dafür, dass ein Auth Key, der für die Nutzung mit Smart CDN aktiviert ist, die URLs im Backend signiert.
- 4
Lesen Sie ${browser.wanted_image_format} im Template aus und ordnen Sie den jpg-Fallback null zu.
Wann Transloadit hilfreich ist
Verwenden Sie ein Template, das das Original aus Ihrem eigenen Speicher importiert, es mit /image/resize transformiert und mit /file/serve endet. Fordern Sie es über eine tlcdn.com-URL an, deren Abfrageparameter die Assembly Variables bereitstellen, die das Template ausliest.
Architekturgrenze
Die Formatverhandlung wird dem Template angeboten und nicht automatisch angewendet. Ein Template, das ${browser.wanted_image_format} nie ausliest, liefert daher weiterhin genau das aus, was es zuvor ausgeliefert hat. Bei fehlenden Accept-Headern oder solchen, die nur einen Platzhalter enthalten, wird die Variable ebenfalls zu jpg aufgelöst. Dies ist eine Aussage über den Client und nicht über die Datei. Wird dieser Fallback direkt an einen Formatparameter übergeben, gehen Transparenz und Animation bei jeder Anfrage verloren, die nicht von einem Browser stammt.
Häufig gestellte Fragen
Liefert Smart CDN WebP oder AVIF automatisch aus?
Ja, aber erst wenn das Template dies anfordert. Lesen Sie ${browser.wanted_image_format} in den Parameter format ein. So erhält jeder Browser das beste Format, das er ausdrücklich akzeptiert. Ein Template, das die Variable nie ausliest, liefert weiterhin das aus, was es zuvor ausgeliefert hat.
Warum wurde mein transparentes PNG als JPEG zurückgegeben?
Weil der Aufrufer keinen Accept-Header oder nur einen Platzhalter gesendet und das Template diesen jpg-Fallback als festes Format verwendet hat. Der Fallback beschreibt die Unterstützung durch den Client und nicht die Datei. Ordnen Sie ihn daher null zu, damit die Größenänderung stattdessen das Eingabeformat beibehält.
Wie viele Breiten sollte ich anbieten?
So wenige, wie das Design tatsächlich benötigt, üblicherweise einige wenige aus realen Breakpoints. Jede zusätzliche Kombination erzeugt einen weiteren Cache-Eintrag und ein weiteres Encoding bei der ersten Anfrage. Varianten mit ähnlichen Größen rechtfertigen selten den Traffic, den sie sich gegenseitig entziehen.
Warum sind meine Encoding-Kosten höher, als die Anzahl der Bilder vermuten lässt?
Fast immer Cache-Misses. Unbegrenzte Breitenparameter, kurze Gültigkeitszeiten von Signaturen und ein niedriger Wert für cache_duration verkürzen die Lebensdauer eines im Cache gespeicherten Ergebnisses. Nach jedem Ablauf fallen bei der nächsten Anfrage erneut Kosten für das Encoding an.
Muss ich jede URL signieren?
Das ist nicht zwingend erforderlich. Eine unsignierte URL, die beliebige Parameter akzeptiert, kann jedoch von jeder Person systematisch durchprobiert werden, die sie findet. Jede neue Kombination verursacht ein kostenpflichtiges Encoding. Signieren Sie die URLs oder begrenzen Sie die akzeptierten Werte im Template.
Wo werden die Originaldateien gespeichert?
In Ihrem eigenen Speicher. Das Template importiert das Original bei jeder Anfrage, üblicherweise mit /s3/import und einem aus der URL gebildeten Pfad. So hält das CDN nur Derivate vor, die sich jederzeit aus einer von Ihnen kontrollierten Quelle neu erzeugen lassen.