Videos sind schwer zu verwalten. Das Streamen erfordert viel Bandbreite und das Caching ist nicht einfach. Diese Probleme werden noch verstärkt, wenn Videos in einer Schleife wiedergegeben werden, wie bei einem Kioskdisplay. Wenn ein Unternehmen beispielsweise Hunderte von Geräten hat, auf denen den ganzen Tag über 30 Videos in Dauerschleife abgespielt werden, kann das Netzwerk schnell überlastet werden. Wenn die Videos aus dem Cache statt per Streaming bereitgestellt werden, fallen die Downloadkosten nur einmal an. Außerdem werden nachfolgende Wiedergaben beschleunigt und die Videos können offline wiedergegeben werden. Dazu können Sie die Speicherfunktionen des Browsers nutzen. Die Cache Storage API und IndexedDB eignen sich am besten zum Speichern von Videodateien. Beide sind gute Optionen, aber wir konzentrieren uns auf die Cache Storage API, da sie in die beliebte Service Worker-Bibliothek Workbox integriert ist.
Video über einen Service Worker im Cache speichern
Das Herunterladen und Zwischenspeichern großer Assets wie Videos kann besonders zeit- und prozessorintensiv sein. Daher sollten Sie diese Vorgänge im Hintergrund außerhalb des Haupt-Threads ausführen. Service Worker sind besonders nützlich, um Caching-Aufgaben auszulagern. Sie fungieren als Proxy zwischen der Seite und dem Netzwerk, sodass Anfragen abgefangen und zusätzliche Logik auf die Netzwerkantwort angewendet werden kann, z. B. eine Caching-Strategie.
Es gibt viele verschiedene Caching-Strategien, die jeweils für unterschiedliche Anwendungsfälle entwickelt wurden. Wenn Sie beispielsweise eine Datei aus dem Cache bereitstellen möchten, falls sie verfügbar ist, oder andernfalls auf das Netzwerk zurückgreifen möchten, können Sie den folgenden Code schreiben.
self.addEventListener('fetch', function (event) { event.respondWith( caches.match(event.request).then(function (response) { return response || fetch(event.request); }), ); });
Die Verwaltung für verschiedene Asset-Typen oder URLs, für die unterschiedliche Caching-Strategien erforderlich sind, kann ein sich wiederholender und fehleranfälliger Prozess sein. Workbox bietet eine Reihe von Tools, darunter Routing-Helfer und Caching-Strategien, mit denen Sie Service Worker-Code deklarativer und wiederverwendbarer schreiben können.
Die vorherige Strategie wird als Cache First bezeichnet. Wenn Sie dasselbe mit Workbox schreiben möchten, würden Sie Folgendes einfügen:
registerRoute( ({ request }) => request.destination === 'video', new CacheFirst() );
Workbox bietet ähnliche Rezepte für andere Caching-Strategien und gängige Service Worker-Aufgaben, einschließlich der Integration in Build-Tools wie Webpack und Rollup.
Nachdem Sie Workbox eingerichtet haben, müssen Sie festlegen, wann Ihre Videos im Cache gespeichert werden sollen. Hier gibt es zwei Ansätze: das Laden beim Seitenaufruf oder das verzögerte Laden, wenn das Video angefordert wird.
Eager-Ansatz
Precaching ist eine Technik, bei der Dateien während der Installation des Service Workers im Cache gespeichert werden. Dadurch sind sie verfügbar, sobald der Service Worker aktiv ist. Workbox kann das Precaching für Dateien, auf die während des Build-Prozesses zugegriffen werden kann, automatisch einrichten.
Der folgende Workbox-Code kann in Ihrem Service Worker verwendet werden, um Dateien vorab im Cache zu speichern:
import { addPlugins, precacheAndRoute } from 'workbox-precaching'; import { RangeRequestsPlugin } from 'workbox-range-requests'; addPlugins([new RangeRequestsPlugin()]); precacheAndRoute(self.__WB_MANIFEST);
import(s) – Die erforderlichen Bindungen aus den entsprechenden Workbox-Modulen werden geladen. Da Service Worker ESModules noch nicht universell unterstützen, muss Ihr Workbox-basierter Service Worker durch einen Bundler geleitet werden, damit er in der Produktion funktioniert.RangeRequestsPlugin: Ermöglicht, dass eine Anfrage mit einemRange-Header durch eine Antwort aus dem Cache erfüllt wird. Das ist erforderlich, da Browser in der Regel einenRange-Header für Media-Inhalte verwenden.addPlugins: Ermöglicht es Ihnen, jeder Workbox-Anfrage Workbox-Plug-ins hinzuzufügen.precacheAndRoute: Fügt der Precache-Liste Einträge hinzu und erstellt eine Route zur Verarbeitung der entsprechenden Fetch-Anfragen.__WB_MANIFEST: Ein Platzhalter, der von der Workbox-Befehlszeile (oder Build-Tool-Plug-ins) durch das Precache-Manifest ersetzt wird.
Übergeben Sie Ihren Service Worker entweder an die Workbox-CLI oder an Ihr bevorzugtes Build-Tool und konfigurieren Sie, wie Ihr Precache generiert werden soll. Eine workbox-config.js-Datei wie die folgende gibt der CLI an,wie sie Ihren Service Worker rendern soll:
module.exports = { globDirectory: '.', globPatterns: ['**/*.{html,mp4}'], maximumFileSizeToCacheInBytes: 5000000, swSrc: 'sw.js', swDest: 'sw.js', };
globDirectory: Der Stammordner, in dem mit der Suche nach Precache-Dateien begonnen werden soll.globPatterns: Die Dateimuster (Globs), die vorab im Cache gespeichert werden sollen.maximumFileSizeToCacheInBytes: Eine Obergrenze für die Größe einer Datei, die vorab im Cache gespeichert werden kann, in Byte.swSrc: Der Speicherort der Datei, die zum Generieren Ihres Service Workers verwendet wird.swDest: Das Ziel für den generierten Service Worker. Es kann dasselbe wie die Quelldatei sein, aberself.__WB_MANIFESTmuss bei jeder Ausführung vorhanden sein.
Wenn der Buildprozess ausgeführt wird, wird eine neue Version des Service Workers generiert und self.__WB_MANIFEST wird durch eine Liste von Dateien ersetzt, die jeweils einen Hash zur Kennzeichnung ihrer Überarbeitung enthalten:
precacheAndRoute([ { revision: '524ac4b453c83f76eb9caeec11854ca5', url: 'ny.mp4', }, ]);
Jedes Mal, wenn der Build-Prozess ausgeführt wird, wird diese Liste mit den aktuellen übereinstimmenden Dateien und ihren aktuellen Revisions-Hashes neu geschrieben. So wird sichergestellt, dass der Service Worker den Cache bei der nächsten Installation aktualisiert, wenn eine Datei hinzugefügt, entfernt oder geändert wird.
Lazy-Ansatz
Wenn Sie nicht alle Videos zur Build-Zeit verfügbar haben oder Videos nur bei Bedarf im Cache speichern möchten, sollten Sie einen verzögerten Ansatz verwenden. Bei diesem Ansatz müssen das Caching und die Bereitstellung getrennt werden, da während der Videowiedergabe nur teilweise Inhalte aus dem Netzwerk abgerufen werden. Das Zwischenspeichern von Dateien während des Streamings funktioniert daher nicht.
Dateien im Cache speichern
Caches können mit Cache.open() erstellt und Dateien mit Cache.add() oder Cache.addAll() zum Cache hinzugefügt werden. Wenn Ihre App eine JSON-Liste von Videos zum Zwischenspeichern erhält, können diese wie folgt zu einem Video-Cache hinzugefügt werden:
// Open video cache const cache = await caches.open('video-cache'); // Fetch list of videos const videos = await (await fetch('/video-list.json')).json(); // Add videos to cache await cache.addAll(videos);
Der Vorteil dieses Ansatzes besteht darin, dass Sie den Caching-Schritt unabhängig vom Lebenszyklus des Service Workers steuern können, auch von anderen Webworkern. Der Nachteil ist, dass die Speicherverwaltung dem Entwickler obliegt. Sie müssen einen eigenen Algorithmus schreiben, um Dateiänderungen zu verfolgen, die aktuell im Browser zwischengespeicherten Dateien zu verfolgen und Dateiaktualisierungen zu verwalten, damit nur geänderte Dateien aktualisiert werden.
Im Cache gespeicherte Videodateien ausliefern
Eine Laufzeit-Caching-Strategie für Service Worker, z. B. Cache First, kann dann verwendet werden, um die zuvor im Cache gespeicherten Videodateien bereitzustellen:
import { registerRoute } from 'workbox-routing'; import { CacheFirst } from 'workbox-strategies'; import { CacheableResponsePlugin } from 'workbox-cacheable-response'; import { RangeRequestsPlugin } from 'workbox-range-requests'; registerRoute( ({ request }) => request.destination === 'video', new CacheFirst({ cacheName: 'video-cache', plugins: [ new CacheableResponsePlugin({ statuses: [200], }), new RangeRequestsPlugin(), ], }), );
import(s): Lädt die erforderlichen Bindungen aus den entsprechenden Workbox-Modulen.registerRoute: Leitet Anfragen an Funktionen (Caching-Strategien und ‑Plug-ins) weiter, die Antworten liefern.CacheFirst: Caching-Strategie, bei der die Anfrage, falls verfügbar, aus dem Cache erfüllt wird. Andernfalls wird sie aus dem Netzwerk abgerufen und der Cache wird aktualisiert.CacheableResponsePlugin: Gibt an, welche Header vorhanden sein müssen, damit die Antwort im Cache gespeichert werden kann. Achten Sie darauf, dass nur 200-Status für Routen zum Zwischenspeichern von Videos enthalten sind, damit keine Antworten mit Teilinhalten (206) zwischengespeichert werden, während Videos gestreamt werden.RangeRequestsPlugin: Ein Plug-in, das es ermöglicht, dass eine Anfrage mit einemRange-Header durch eine Antwort aus dem Cache erfüllt wird. Das ist erforderlich, da Browser in der Regel einenRange-Header für Media-Inhalte verwenden.
Das Optimieren des Videoladens ist eine wichtige Aufgabe für Apps, die intensives Streaming nutzen. Mithilfe der Cache Storage API des Browsers und Workbox können Sie diese ansonsten schwierige Aufgabe bewältigen. So sparen Sie Bandbreite für Ihre Nutzer, reduzieren die Serverlast, ermöglichen eine schnellere Videowiedergabe und sorgen dafür, dass Ihre Videos auch offline abgespielt werden können.