UI/UX-Design

Vom leeren Repo zum produktionsreifen Designsystem

Ein AR-Prototyp lässt sich auf dem Telefon vorführen. Ihn zuverlässig auszuliefern, ist eine andere Aufgabe: Browser wechseln den Viewer, Modelle sind groß, und ein fehlgeschlagener Kamerastart taucht in keinem Serverlog auf. Meine Position: Für eine erste produktive AR-Vorschau gehört die Szene in eine statisch ausgelieferte Webanwendung mit systemnativem Fallback – nicht in eine eigens betriebene Rendering-Plattform.

Der erste Release braucht einen engen Vertrag zwischen Design und Betrieb

Beginne mit genau einem Nutzungspfad: Eine Person öffnet eine Produktseite, sieht ein drehbares 3D-Modell und kann es auf einem unterstützten Smartphone im Raum platzieren. Das ist eine überprüfbare Anforderung. „AR funktioniert“ ist dagegen keine, weil ein Desktop ohne Kamera, ein iPhone mit AR Quick Look und ein Android-Gerät mit Scene Viewer unterschiedliche Ergebnisse liefern.

Ich lese Digitales Produktdesign fuer moderne Softwareentwicklung als Designimpuls; für den Produktionsbetrieb schreibe ich zusätzlich auf, welcher Zustand bei fehlender AR-Unterstützung erscheinen muss. In diesem Setup bleibt das drehbare Modell verfügbar, sofern WebGL funktioniert. Fehlt auch WebGL, zeigt die Seite ein normales Vorschaubild und die Produktinformationen. So hängt die grundlegende Aufgabe nicht von einer erfolgreichen Kamerasitzung ab.

Halte diesen Vertrag in einem Architecture Decision Record (ADR) fest: unterstützte Geräteklassen, Modellformate, sichtbare Ladezustände, Verhalten bei verweigerter Kameraberechtigung und eine Kontaktadresse für Fehlerberichte. Beschreibe außerdem, was nicht garantiert wird. Eine maßstabsgetreue Platzierung würde ich im ersten Release nicht versprechen, weil die wahrgenommene Größe auch von Tracking, Umgebung und Viewer abhängt und deshalb auf Zielgeräten geprüft werden muss.

Für den Start reicht ein GLB-Modell nach glTF 2.0 für die Webansicht und ein USDZ-Modell für Apples AR Quick Look. Ein Vorschaubild ist ein eigenes Artefakt, kein Screenshot, den der Browser erst aus dem 3D-Modell erzeugen muss. Als anpassbaren Startwert setze ich für das GLB ein Budget von 8 MB; auf langsamen Verbindungen kostet jedes zusätzliche Megabyte Zeit, bevor überhaupt eine Szene sichtbar werden kann. Für USDZ plane ich zunächst höchstens 15 MB ein – eine zu prüfende Obergrenze, keine Eigenschaft des Formats.

Erstelle die Artefakte reproduzierbar: Export aus Blender, Sichtprüfung mit dem glTF Validator der Khronos Group und anschließend ein Test der tatsächlich ausgelieferten Dateien auf den Zielgeräten. Der Validator findet Formatprobleme, aber keine schlecht lesbaren Oberflächen oder einen falschen Maßstab. Lege daher im Repository eine kleine Abnahmeliste neben die Quelldateien: Blickwinkel, Materialdarstellung, Ausgangsgröße und das erwartete Vorschaubild. Eine neue Modelldatei ohne aktualisierte Abnahme darf den Release nicht passieren.

Eine statische Webanwendung ist der bessere erste Produktionsstandard

Setze die Oberfläche mit Vite und @google/model-viewer um. Die Webkomponente übernimmt die 3D-Darstellung und kann für AR zwischen WebXR, Androids Scene Viewer und Apples AR Quick Look vermitteln. Pinne Node.js 22, Vite 6 und die gewählte Version von @google/model-viewer im Lockfile; eine unbemerkte Änderung der Build-Werkzeuge erschwert die Zuordnung eines Darstellungsfehlers zu einem Release. Das Modell referenzierst du über src, das Vorschaubild über poster und die Apple-Datei über ios-src.

Ich nehme Augmented Reality & digitales Produktdesign: Neue Erlebnisse schaffen als Entwurfshilfe, würde die erste Betriebsarchitektur aber nicht um eine eigene Echtzeit-Engine herum bauen. Die Anwendung braucht zunächst verlässlich erreichbare Dateien und einen verständlichen Rückweg aus dem AR-Viewer; ein zusätzlicher Rendering-Dienst schafft dafür nur einen weiteren Ausfallpunkt.

Die explizite Wahl lautet WebXR gegen systemnative Viewer. WebXR gewinnt, wenn Interaktionen innerhalb derselben Websitzung bleiben und du deren Zustände selbst gestalten musst. Es kostet Unterstützung für Geräteunterschiede, Kameraberechtigungen und mehr Tests im Browser. AR Quick Look und Scene Viewer gewinnen beim ersten einfachen Platzieren eines Modells, weil Betriebssystem und Gerät den AR-Modus übernehmen. Ihr Preis ist geringere Kontrolle über Oberfläche und Telemetrie: Ein erfolgreicher Dateiabruf beweist nicht, dass jemand die Szene im Viewer gesehen hat. model-viewer kann beide Wege zugänglich machen, beseitigt diesen Unterschied aber nicht.

Baue lokal zuerst die Seite mit einem einzigen Modell. Teste Tastaturbedienung, lesbare Schaltflächen und den Zustand vor dem Download, bevor du einen AR-Button freigibst. Der Button darf auf einem nicht unterstützten Gerät keine Kamerafunktion suggerieren. Danach prüfst du auf einem iPhone mit Safari und einem Android-Gerät mit Chrome, ob jeweils die vorgesehene Datei beziehungsweise der Viewer öffnet. Browser-Emulation in Playwright ersetzt diese beiden Gerätetests nicht, weil sie weder AR Quick Look noch das Tracking des Geräts verlässlich nachstellt.

Ich würde keine Modelle zur Laufzeit aus einem CMS konvertieren, solange ein freigegebener Export pro Release genügt. Eine Laufzeitkonvertierung verlängert den Fehlerpfad von der Produktseite bis zum Modell und erschwert Rollbacks. Wer häufig neue Modelle benötigt, kann später eine getrennte Build-Pipeline ergänzen; zunächst ist ein überprüftes Artefakt einfacher zu unterstützen.

Versionierte Modelldateien machen einen Rollback erst möglich

Der erste Deployment-Test soll beweisen, dass HTML, JavaScript, GLB und USDZ zusammenpassen. Vite baut die Anwendung in dist; die freigegebenen Modelldateien liegen dort unter einem versionsgebundenen Pfad, etwa /releases/42/model.glb und /releases/42/model.usdz. Diese Release-Nummer als Beispiel ist keine Cache-Laufzeit: Sie verhindert, dass ein altes HTML-Dokument unbemerkt ein neu überschriebenes Modell lädt.

Nginx 1.27 kann das gebaute Verzeichnis zunächst als einfachen Origin ausliefern. Die folgende Datei gehört als default.conf nach /etc/nginx/conf.d/; sie funktioniert innerhalb der üblichen http-Konfiguration des Nginx-Images. Die langen Cache-Zeiten gelten nur, wenn die Modell-URLs bei Änderungen einen neuen Versionspfad erhalten.

server {
  listen 80;
  root /usr/share/nginx/html;
  location / {
    try_files $uri $uri/ /index.html;
  }
  location ~* \.glb$ {
    types { model/gltf-binary glb; }
    add_header Cache-Control "public, max-age=31536000, immutable";
  }
  location ~* \.usdz$ {
    types { model/vnd.usdz+zip usdz; }
    add_header Cache-Control "public, max-age=31536000, immutable";
  }
}

Vor dem Hochladen lässt du nginx -t gegen diese Konfiguration laufen. Danach prüfst du mit curl -I die echten Release-URLs: Statuscode, Content-Type und Cache-Control müssen zur Datei passen. Ein Test nur gegen / übersieht den häufigeren Fehler, dass die Seite lädt, aber das Modell unter einem falschen Pfad liegt. Der Fallback auf index.html gilt für Seitenrouten; fehlende GLB- und USDZ-Dateien müssen dagegen einen 404 liefern, damit sie nicht als scheinbar erfolgreiche HTML-Antwort im Browser landen.

In GitHub Actions trenne ich den Ablauf in Build, Artefaktprüfung und Deployment. Der Build verwendet npm ci und das eingecheckte Lockfile. Die Prüfung kontrolliert, dass beide Modelldateien vorhanden sind, der glTF Validator das GLB akzeptiert und der Produktionsbuild keine Referenz auf einen lokalen Entwicklungsserver enthält. Erst danach werden die Dateien veröffentlicht. Liegt davor ein CDN wie Amazon CloudFront, konfiguriere index.html separat ohne langfristiges Caching; sonst kann ein Client alte Referenzen behalten, obwohl die neuen Assets schon bereitstehen.

Beim Rollback bleibt die zuvor veröffentlichte Modellversion erreichbar. Das ist der Grund, warum „Deployment zurücksetzen“ mehr bedeuten muss als nur die alte HTML-Datei erneut hochzuladen. Lösche ältere Release-Verzeichnisse erst nach Ablauf der Cache-Frist und nach einer Prüfung, dass keine noch ausgelieferte Seite sie referenziert. Als Betriebsregel, die ihr einstellen könnt, behalte ich mindestens zwei vollständige Releases gleichzeitig. Das kostet Speicherplatz, spart bei einem fehlerhaften Modell aber eine Notfallkonvertierung.

Du kannst nur den Teil der AR-Sitzung überwachen, den du selbst betreibst

Richte zunächst einen synthetischen Check für Seite, Vorschaubild, GLB und USDZ ein. Ein HTTP-200 allein reicht nicht: Der Check sollte auch Dateityp und eine plausible Dateigröße prüfen. Nutze Playwright für den Weg bis zur sichtbaren 3D-Ansicht und für den Fallback ohne WebGL. Für den Kamerastart bleibt ein kurzer manueller Test auf echten Geräten Bestandteil der Freigabe, weil weder der Webserver noch ein Headless-Browser die Qualität des räumlichen Trackings belegen.

Instrumentiere in der Webanwendung die Zeit vom Seitenaufruf bis zum load-Ereignis von model-viewer. Erfasse außerdem fehlgeschlagene Asset-Requests und AR-Startversuche als getrennte Ereignisse. Bezeichne die erste Metrik ausdrücklich als „Modell geladen“, nicht als „AR bereit“: Nach der Übergabe an AR Quick Look oder Scene Viewer endet ein Teil deiner Beobachtbarkeit. OpenTelemetry kann die Ereignisse an dein bestehendes Backend senden; Prometheus und Grafana eignen sich für die daraus abgeleiteten Zeitreihen und Alarme.

Miss die Ausgangslage auf einem festgelegten Testgerät und einer dokumentierten Netzwerkverbindung. Eine im eigenen Abnahmelauf gemessene Ladezeit wird erst dann zum brauchbaren Vergleichswert, wenn Gerät, Modellversion und Verbindung mit im Protokoll stehen. Als vorläufige Alarmschwelle würde ich erst nach solchen Läufen einen p95-Wert festlegen, statt eine Zahl aus Lighthouse ungeprüft zum Produktionsziel zu erklären. Lighthouse hilft bei reproduzierbaren Webmessungen, misst aber keinen erfolgreichen Wechsel in einen systemnativen AR-Viewer.

Bereite einen knappen Incident-Pfad vor. Meldet Grafana steigende Asset-Fehler, prüfst du zuerst die Release-URLs und CDN-Antworten, dann den letzten Deployment-Diff. Häufen sich nur AR-Startprobleme auf einem Gerätetyp, vergleichst du Browser- und Betriebssystemversion und hältst den Modell-Fallback erreichbar, während du nachstellst. Fehlt eine klare Ursache, rolle HTML und Referenzen gemeinsam zurück, statt Dateien unter bestehenden URLs auszutauschen. So bleibt der Fehler eingrenzbar, auch wenn der Viewer selbst keine Logs an dich liefert.

Ein einziges Testmodell ist der richtige nächste Schritt

Lege heute ein freigegebenes GLB, das passende USDZ und ein Vorschaubild unter einem versionsgebundenen Pfad ab. Baue die Seite, prüfe beide Datei-URLs mit curl -I und öffne denselben Release auf einem iPhone und einem Android-Gerät. Notiere für jeden fehlgeschlagenen Schritt die sichtbare Meldung und die zuständige Komponente. Erst danach lohnt es sich, weitere Modelle in die Pipeline aufzunehmen.