Secțiuni video conduse de derulare, fără să strici performanța
Cum construiești o secțiune video și galerie fixată, legată de derulare, care arată cinematic dar rămâne rapidă pe telefoane: o singură valoare de progres, un singur video care rulează, fără biblioteci.
3 min de cititGryffin Forge
Site-urile premium iubesc o secțiune fixată în care videoul se deschide la derulare și subtitrările se schimbă capitol cu capitol. E și unul dintre cele mai ușoare moduri de a face o pagină sacadată, grea și mâncătoare de baterie. Iată cum e construită secțiunea de prezentare din biblioteca de demo-uri ca să rămână rapidă.
O singură valoare de progres controlează totul
Secțiunea e un container înalt cu o scenă fixă înăuntru. La derulare, scriptul calculează un singur număr — cât din container a parcurs vizitatorul, de la 0 la 1 — și tot restul derivă din el:
- marginea clip-path care deschide videoul încadrat pe toată lățimea,
- o scalare discretă a videoului activ,
- ce capitol (clip și subtitrare) e activ,
- lățimea barei de progres,
- estomparea și deplasarea titlului.
Valorile sunt scrise ca proprietăți CSS personalizate, iar CSS face restul. Nu există cronologii de animație per element de sincronizat și nicio bibliotecă de descărcat.
const p = clamp(-rect.top / (rect.height - innerHeight));
stage.style.setProperty('--p', p);
Citiri și scrieri într-un singur cadru
Evenimentele de derulare vin mai des decât reîmprospătarea ecranului. Handlerul doar programează munca prin requestAnimationFrame, iar fiecare cadru citește întâi layoutul și apoi scrie stilurile. Amestecarea citirilor cu scrierile forțează recalculări repetate — cea mai comună cauză a derulării sacadate.
Rulează un singur video
Trei videouri pornite automat deodată încing telefonul și consumă date. Regulile:
- Primul clip se încarcă imediat, ca secțiunea să nu fie niciodată goală.
- Celelalte pornesc cu
preload="none". - Când un capitol devine activ, clipul lui rulează, iar clipul următor trece la preîncărcare.
- Clipurile inactive se opresc după ce se termină estomparea.
- Când întreaga secțiune iese din ecran, totul se oprește.
Toate clipurile sunt fără sunet, în buclă și playsinline, necesar pentru redarea automată pe mobil.
Animează proprietăți ieftine
opacity, transform și clip-path pot fi compuse de GPU. Animarea top, width sau background-position pe elemente mari declanșează recalculări sau redesenări. Galeria orizontală se mișcă prin translate3d, iar paralaxa fiecărui card mută o imagine interioară printr-o transformare, nu schimbându-i poziția.
Servește videoul cu cap
Clipurile sunt 720p, câțiva megabytes fiecare, servite printr-un proxy edge care le pune în cache și suportă cereri HTTP pe intervale, ca browserul să poată sări și să facă streaming. Posterele vin din imagini statice, ca ceva cu sens să apară înainte să se decodeze primul cadru.
Respectă mișcarea redusă
Când vizitatorul a cerut sistemului mai puțină mișcare, secțiunea nu se mai fixează, galeria devine un rând normal derulabil, iar textul apare fără animație. Conținutul e identic; doar coregrafia dispare.
Apără-ți stilurile
Secțiunea e injectată în multe șabloane diferite, iar unul avea o regulă grid generică .gal care a strâns în tăcere banda galeriei. Acum fiecare clasă a componentei are prefix. Dacă faci componente care ajung în pagini pe care nu le controlezi, spațiile de nume nu sunt opționale.
Rezumat
- Derivă totul dintr-o singură valoare de progres.
- Programează cu
requestAnimationFrame; citește, apoi scrie. - Un singur video care rulează; preîncărcare la timp; pauză în afara ecranului.
- Animează doar proprietăți prietenoase cu compozitorul.
- Pune în cache și servește videoul pe intervale, la edge.
- Respectă
prefers-reduced-motion. - Dă stilurilor injectate un spațiu de nume.