
So funktioniert es
Der DataProcessor analysiert Medienelemente und setzt Markierungen, die angeben, welche Assets erforderlich sind (RenderDecisionResolver::resolveAssetFlags()):
| Flag | Lädt | Wann |
|---|---|---|
needsPrivacyLayer | PrivacyLayer.js + privacy-layer.css | YouTube, Vimeo oder SoundCloud vorhanden |
needsVidPlay | VidPly-Kern (vidply/vidply.esm.min.js + Code-Split-Blöcke; aus TypeScript kompiliert, enthält den Puffer-Indikator, den optionalen Download-Button und den SoundCloud-Renderer) | Lokale Video- oder Audiodateien, alle Wiedergabelisten sowie einzelne YouTube-/Vimeo-Elemente, während mpcVidply.embedChrome ist vidply (Standard) |
needsPlaylist | PlaylistInit.js | Immer wenn der VidPly-Kern geladen wird (Player-Initialisierung, Playlists) |
needsHLS | hls.js 1.7.3 (hls.min.js) | HLS-Quelle (.m3u8) in Mediendateien erkannt |
needsDASH | dash.js 5.2.1 (dash.all.min.js, modernes UMD) | DASH-Quelle (.mpd) in Mediendateien erkannt |
Die Episoden-Layouts fügen zwei weitere Assets hinzu, die VidPly/EpisodeLayout.html
anstatt über ein Flag geladen werden: episode.min.css und EpisodeInit.min.js (verbindet die
Wiedergabetaste der Karte mit dem Player). Sie werden nur ausgegeben, wenn das Feld „Layout“ des
content-Elements auf card oder episodes.
CSS immer geladen wird – vidply.min.css ist schlank und wird für ein einheitliches Styling immer mitgeliefert. Es enthält außerdem die Stile für den zentrierten Puffer-Spinner (.vidply-loading / .vidply-buffering) sowie für die Download-Schaltfläche.
YouTube- und Vimeo-Inhalte werden standardmäßig im VidPly-Player abgespielt — Einzelne YouTube-/Vimeo-Elemente laden den VidPly-Kern und PlaylistInit.js neben der Datenschutzebene, sodass sie nach der Einwilligung die VidPly-Steuerleiste, Untertitel und das Transkript erhalten. Legen Sie die Website-Einstellung mpcVidply.embedChrome so ein, provider , um sie auf dem schlankeren Pfad „nur Datenschutzebene“ mit dem anbieter-eigenen Player zu belassen (siehe „SettingsArchitecture“).
SoundCloud verwendet standardmäßig den Datenschutz-Layer-Pfad – mpc-vidply einzelne SoundCloud-Medienelemente wird nur PrivacyLayer.js + privacy-layer.css (nicht der VidPly-Kern), da der SoundCloud-Widget-iframe eine eigene Benutzeroberfläche mitbringt. Das gebündelte eigenständige SoundCloudRenderer wird im VidPly-Kernpaket mitgeliefert und daher nur für Seiten abgerufen, die den VidPly-Kern bereits aus anderen Gründen benötigen (lokale Video-/Audiodateien, HLS, DASH). Siehe „PrivacyLayer → SoundCloud in den Renderer-Modus umschalten“, um diese Option zu aktivieren.
Beispiele
Einzelnes YouTube-/Vimeo-Element (Standard, embedChrome: vidply)
geladen:
- vidply.min.css
- privacy-layer.css
- PrivacyLayer.js (Datenschutz-Overlay)
- VidPly-Player (
vidply/vidply.esm.min.js+ Chunks; der YouTube-/Vimeo-Renderer wird nach der Einwilligung geladen) - PlaylistInit.js (Initialisierung des Players hinter dem Datenschutz-Overlay)
Nicht geladen:
- hls.js
- dash.js
Einzelnes SoundCloud-Element oder einzelnes YouTube-/Vimeo-Video mit embedChrome: provider
Geladen:
- vidply.min.css (Styling, inkl. Spinner- und Download-Button-Stile)
- privacy-layer.css (Stile für die Datenschutzebene)
- PrivacyLayer.js (Einwilligungsabwicklung, bindet den Service-Iframe nach Einwilligung ein)
Nicht geladen:
- VidPly-Player-Kern (und somit auch nicht die mitgelieferte
SoundCloudRenderer– siehe „PrivacyLayer“ für die Aktivierung des Renderer-Modus) - PlaylistInit.js
- hls.js
- dash.js
Einzelnes lokales MP4-Video
Geladen:
- vidply.min.css
- VidPly-Player (
vidply/vidply.esm.min.js+ Chunks) - PlaylistInit.js (Player-Initialisierung)
Nicht geladen:
- PrivacyLayer.js
- hls.js
Video mit HLS-Quelle
Geladen:
- vidply.min.css
- VidPly-Player
- PlaylistInit.js
- hls.js (adaptives Streaming)
Nicht geladen:
- PrivacyLayer.js
- dash.js
Video mit DASH-Quelle
Geladen:
- vidply.min.css
- VidPly-Player
- PlaylistInit.js
- dash.js (MPEG-DASH-Streaming)
Nicht geladen:
- PrivacyLayer.js
- hls.js
Playlist mit 3 MP4-Videos
Geladen:
- vidply.min.css
- VidPly-Player
- PlaylistInit.js (Wiedergabeliste + Player)
Nicht geladen:
- PrivacyLayer.js
- hls.js
Gemischte Wiedergabeliste (YouTube + Vimeo + SoundCloud)
Geladen:
- vidply.min.css
- privacy-layer.css
- PrivacyLayer.js
- VidPly-Player (Benutzeroberfläche der Wiedergabeliste; YouTube-/Vimeo-Titel werden über deren Renderer abgespielt)
- PlaylistInit.js (für die Verwaltung von Wiedergabelisten)
Nicht geladen:
- hls.js
- dash.js
Gemischte Wiedergabeliste (lokale MP4-Dateien + YouTube)
Geladen:
- vidply.min.css
- privacy-layer.css
- PrivacyLayer.js (für das YouTube-Element)
- VidPly-Kern (für das MP4-Element – enthält auch den Puffer-Indikator, den Download-Button und den SoundCloud-Renderer, auch wenn diese nicht alle verwendet werden)
- PlaylistInit.js
Auswirkungen auf die Leistung
Vor der Optimierung:
- Alle JavaScript-Dateien werden auf jeder Seite mit VidPly geladen
- Gesamt: ~605 KB (einschließlich des eingebundenen hls.js 1.7.3)
Nach der Optimierung:
- Ein einzelnes SoundCloud-Element oder ein einzelnes YouTube-/Vimeo-Element mit
embedChrome: provider: ~7 KB (PrivacyLayer.js + privacy-layer.css) - Einzelnes YouTube- oder Vimeo-Video (Standard
embedChrome: vidply): ~187 KB (Privacy Layer + VidPly-Kern + PlaylistInit) - Ein einzelnes lokales Video: ~180 KB (VidPly-Kern + PlaylistInit) – enthält bereits den Puffer-Indikator, den optionalen Download-Button und den SoundCloud-Renderer
- Video mit HLS-Quelle: ~314 KB (VidPly + PlaylistInit + hls.js)
- Video mit DASH-Quelle: ~380 KB (VidPly + PlaylistInit + dash.js)
- Video mit HLS- und DASH-Quellen: ~514 KB (VidPly + PlaylistInit + hls.js + dash.js)
Einsparungen:
- Externe Dienste auf dem „Privacy-Layer-Only“-Pfad: 97 % Reduzierung (~350 KB → ~7 KB)
- Lokales Video ohne Streaming: ~65 % Reduzierung im Vergleich zur nicht optimierten „Alles laden“-Baseline
Die Größenangaben beziehen sich auf minimierte, unkomprimierte Dateien. Die tatsächliche Übertragungsgröße beträgt nach gzip/brotli in der Regel 30–40 % dieser Werte.
Implementierung
DataProcessor (VidPlyProcessor.php → RenderDecisionResolver.php)
// $serviceType: 'youtube' | 'vimeo' | 'soundcloud' for a single external item, null otherwise.
// $singleEmbedInPlayer: true for a single YouTube/Vimeo item while embedChrome is 'vidply'
// (always false for SoundCloud, whose chrome is fixed to 'provider').
$isPlaylist = $trackResult['isPlaylist'];
$needsPrivacyLayer = $serviceType !== null || ($isPlaylist && $trackResult['hasExternalMedia']);
$needsVidPlay = $isPlaylist || $serviceType === null || $singleEmbedInPlayer;
$needsPlaylist = $isPlaylist || $needsVidPlay;
// HLS and DASH streams are detected by MIME type on every track and its sources
// (MediaMimeType::isHls() / MediaMimeType::isDash()).
Vorlage (Partials/VidPly/Player.html)
<f:render partial="VidPly/Assets" arguments="{
needsPrivacyLayer: vidply.needsPrivacyLayer,
needsVidPlay: vidply.needsVidPlay,
needsPlaylist: vidply.needsPlaylist,
needsHLS: vidply.needsHLS,
needsDASH: vidply.needsDASH
}" />
Assets-Partial (VidPly/Assets.html)
<!-- Privacy Layer JS - only for external services -->
<f:if condition="{needsPrivacyLayer}">
<f:asset.script identifier="vidPlyPrivacy" src="..." type="module"/>
</f:if>
<!-- HLS.js 1.7.3 - only for HLS streams -->
<f:if condition="{needsHLS}">
<f:asset.script identifier="vidPlyHLS" src="EXT:mpc_vidply/Resources/Public/JavaScript/hls.min.js" defer="true"/>
</f:if>
<!-- dash.js 5.2.1 (modern UMD) - only for DASH streams -->
<f:if condition="{needsDASH}">
<f:asset.script identifier="vidPlyDASH" src="EXT:mpc_vidply/Resources/Public/JavaScript/dash.all.min.js" defer="true"/>
</f:if>
<!-- VidPly Core - local media, playlists, single YouTube/Vimeo with embedChrome: vidply -->
<f:if condition="{needsVidPlay}">
<f:asset.script identifier="vidPlyWrapper" src="..." />
<f:asset.script identifier="vidPly" src="..." type="module"/>
</f:if>
<!-- Playlist Init - for playlists or player initialization -->
<f:if condition="{needsPlaylist}">
<f:asset.script identifier="playlistInit" src="..." type="module"/>
</f:if>
Vorteile
- Schnelleres Laden der Seite – insbesondere für SoundCloud sowie für YouTube und Vimeo mit
embedChrome: provider - geringerem Bandbreitenverbrauch – Nutzer laden nur das herunter, was sie benötigen
- Besseres Caching – Nicht verwendete Skripte belasten den Browser-Cache nicht
- Automatisch – Keine Konfiguration erforderlich, funktioniert basierend auf Medientypen
- Intelligente Erkennung – Seitenspezifische Optimierung basierend auf den tatsächlichen Inhalten
Browserkompatibilität
Alle gängigen Browser unterstützen das bedingte Laden von Assets über die TYPO3-Asset-API:
- Chrome/Edge 90+
- Firefox 88+
- Safari 14+
- Mobile Browser
Testen
So überprüfen Sie das bedingte Laden:
- Öffnen Sie die Entwicklertools des Browsers → Registerkarte „Netzwerk“
- Erstellen Sie eine Seite mit einem einzelnen SoundCloud-Element
- Lade die Seite neu und überprüfe, ob nur „PrivacyLayer.js“ geladen wird (kein VidPly-Kern)
- Erstellen Sie eine Seite mit einem einzelnen YouTube-Video
- Laden Sie die Seite neu und stellen Sie sicher, dass „PrivacyLayer.js“, der VidPly-Kern und „PlaylistInit.js“ geladen werden – es darf jedoch keine Anfrage an YouTube erfolgen, bevor Sie auf „Abspielen“ klicken
- Erstellen Sie eine Seite mit einer lokalen MP4-Datei
- Seite neu laden und überprüfen, ob der VidPly-Kern geladen wird, PrivacyLayer.js jedoch nicht
Fehlerbehebung
Assets werden nicht geladen:
- Leeren Sie alle TYPO3-Caches
- Browserkonsole auf Fehler überprüfen
- Überprüfen Sie, ob DataProcessor registriert ist
Falsche Assets werden geladen:
- Überprüfen Sie die Medientyp-Erkennung im DataProcessor
- Überprüfen Sie, ob Flags an die Vorlage übergeben werden
- Leeren Sie den Vorlagen-Cache
Externe Dienste funktionieren nicht:
- Stellen Sie sicher, dass PrivacyLayer.js für YouTube/Vimeo/SoundCloud geladen wird
- Überprüfen Sie die Browserkonsole auf JavaScript-Fehler
Zukünftige Verbesserungen
Mögliche zukünftige Optimierungen:
- Lazy-Load für CSS (wird derzeit immer geladen)
- Aufteilung des VidPly-Kerns in kleinere Module (der SoundCloud-Renderer, der Download-Button und der Puffer-Indikator lassen sich bereits als separate Teile über dynamische TypeScript-
import()s – durch die Bereitstellung von Funktions-Flags für den DataProcessor könnten wir diese weglassen, wenn sie nicht benötigt werden) - Vorpflügen kritischer Assets basierend auf den Inhalten oberhalb der Falz
- Service Worker für Offline-Caching