Perf: optimisation vidéos page d'accueil

- Vidéos recompressées (CRF 23, faststart, full res/fps) : 22MB → 5.8MB et 4.8MB
- Champs Kirby dynamiques pour vidéo desktop/mobile + posters
- Source vidéo dynamique via data.backgroundVideo (corrige le hardcode)
- Lecture déclenchée sur canplay plutôt qu'immédiatement (évite freeze)
- preload="auto" pour un buffering plus agressif

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
isUnknown 2026-03-11 15:39:19 +01:00
parent 0233a6a4a4
commit 2373b81db7
5 changed files with 67 additions and 36 deletions

Binary file not shown.

Binary file not shown.

View file

@ -41,7 +41,7 @@ tabs:
type: fields type: fields
fields: fields:
backgroundVideo: backgroundVideo:
label: Vidéo d'arrière-plan label: Vidéo d'arrière-plan (desktop)
type: files type: files
layout: cards layout: cards
max: 1 max: 1
@ -52,3 +52,35 @@ tabs:
cover: true cover: true
uploads: uploads:
template: video template: video
backgroundVideoPoster:
label: Poster vidéo desktop (affiché pendant le chargement)
type: files
layout: cards
max: 1
accept: image/*
translate: false
image:
ratio: 16/9
cover: true
backgroundVideoMobile:
label: Vidéo d'arrière-plan (mobile)
type: files
layout: cards
max: 1
accept: video/*
translate: false
image:
ratio: 9/16
cover: true
uploads:
template: video
backgroundVideoMobilePoster:
label: Poster vidéo mobile (affiché pendant le chargement)
type: files
layout: cards
max: 1
accept: image/*
translate: false
image:
ratio: 9/16
cover: true

View file

@ -10,6 +10,9 @@ $specificData = [
'image' => $page->heroImage()->toFile()?->url() 'image' => $page->heroImage()->toFile()?->url()
], ],
'backgroundVideo' => $page->backgroundVideo()->toFile()?->url(), 'backgroundVideo' => $page->backgroundVideo()->toFile()?->url(),
'backgroundVideoPoster' => $page->backgroundVideoPoster()->toFile()?->url(),
'backgroundVideoMobile' => $page->backgroundVideoMobile()->toFile()?->url(),
'backgroundVideoMobilePoster' => $page->backgroundVideoMobilePoster()->toFile()?->url(),
'floatingBubbles' => $page->floatingBubbles()->toStructure()->map(function($bubble) { 'floatingBubbles' => $page->floatingBubbles()->toStructure()->map(function($bubble) {
return [ return [
'text' => $bubble->text()->value(), 'text' => $bubble->text()->value(),

View file

@ -7,36 +7,34 @@
const currentLang = $derived(locale.current) const currentLang = $derived(locale.current)
onMount(() => { function playWhenReady(video) {
const playVideo = async (videoId) => { if (!video) return
const video = document.getElementById(videoId)
if (video) { const attempt = () => {
try {
video.muted = true video.muted = true
video.playsInline = true video.playsInline = true
const playPromise = video.play() video.play().catch(() => {
if (playPromise !== undefined) { // Autoplay bloqué : on attend une interaction
await playPromise const onInteraction = () => {
video.play().catch(() => {})
document.removeEventListener('click', onInteraction)
document.removeEventListener('touchstart', onInteraction)
} }
} catch (error) { document.addEventListener('click', onInteraction)
console.log(`Autoplay failed for ${videoId}:`, error) document.addEventListener('touchstart', onInteraction)
const playOnInteraction = () => { })
video.play().catch(e => console.log('Fallback play failed:', e))
document.removeEventListener('click', playOnInteraction)
document.removeEventListener('touchstart', playOnInteraction)
}
document.addEventListener('click', playOnInteraction)
document.addEventListener('touchstart', playOnInteraction)
} }
if (video.readyState >= 3) {
attempt()
} else {
video.addEventListener('canplay', attempt, { once: true })
} }
} }
const timer = setTimeout(() => { onMount(() => {
playVideo('home-video') playWhenReady(document.getElementById('home-video'))
playVideo('home-video-mobile') playWhenReady(document.getElementById('home-video-mobile'))
}, 100)
return () => clearTimeout(timer)
}) })
function handleExplore() { function handleExplore() {
@ -49,27 +47,25 @@
<figure class="home-figure"> <figure class="home-figure">
<video <video
muted muted
autoplay
playsinline playsinline
loop loop
controls={false} preload="auto"
preload="metadata"
id="home-video" id="home-video"
class="home-video home-video-desktop" class="home-video home-video-desktop"
poster={data.backgroundVideoPoster ?? undefined}
> >
<source src="/assets/video/Website_version.mp4" type="video/mp4" /> <source src={data.backgroundVideo ?? '/assets/video/Website_version.mp4'} type="video/mp4" />
</video> </video>
<video <video
muted muted
autoplay
playsinline playsinline
loop loop
controls={false} preload="auto"
preload="metadata"
id="home-video-mobile" id="home-video-mobile"
class="home-video home-video-mobile" class="home-video home-video-mobile"
poster={data.backgroundVideoMobilePoster ?? undefined}
> >
<source src="/assets/video/mobile_version_texte_fixe.mp4" type="video/mp4" /> <source src={data.backgroundVideoMobile ?? '/assets/video/mobile_version_texte_fixe.mp4'} type="video/mp4" />
</video> </video>
</figure> </figure>
</div> </div>