Gryffin Forge
FrontendDesempenhoMovimento

Secções de vídeo guiadas pelo scroll, sem estragar o desempenho

Como construir uma secção fixada de vídeo e galeria ligada ao scroll que parece cinematográfica mas continua rápida no telemóvel: um único valor de progresso, um único vídeo a reproduzir, sem bibliotecas.

3 min de leituraGryffin Forge

Os sites premium adoram uma secção fixada em que o vídeo se abre com o scroll e as legendas mudam capítulo a capítulo. É também uma das formas mais fáceis de tornar uma página aos solavancos, pesada e gastadora de bateria. Eis como é construída a secção de apresentação da biblioteca de demos para continuar rápida.

Um único valor de progresso controla tudo

A secção é um contentor alto com um palco fixo lá dentro. No scroll, o script calcula um único número — quanto do contentor o visitante já percorreu, de 0 a 1 — e tudo o resto deriva dele:

  • a margem do clip-path que abre o vídeo emoldurado a toda a largura,
  • uma escala discreta do vídeo ativo,
  • que capítulo (clip e legenda) está ativo,
  • a largura da barra de progresso,
  • o desvanecimento e o deslocamento do título.

Os valores são escritos como propriedades CSS personalizadas e o CSS faz o resto. Não há cronologias de animação por elemento para sincronizar nem nenhuma biblioteca para descarregar.

const p = clamp(-rect.top / (rect.height - innerHeight));
stage.style.setProperty('--p', p);

Leituras e escritas num só frame

Os eventos de scroll chegam mais vezes do que o ecrã se atualiza. O handler apenas agenda o trabalho com requestAnimationFrame, e cada frame lê primeiro o layout e depois escreve os estilos. Misturar leituras e escritas força recálculos repetidos — a causa mais comum de um scroll aos solavancos.

Só um vídeo a reproduzir

Três vídeos a arrancar automaticamente ao mesmo tempo aquecem o telemóvel e gastam dados. As regras:

  • O primeiro clip carrega de imediato, para a secção nunca ficar vazia.
  • Os outros começam com preload="none".
  • Quando um capítulo fica ativo, o seu clip reproduz e o clip seguinte passa a pré-carregar.
  • Os clips inativos param depois de terminar o desvanecimento.
  • Quando a secção inteira sai do ecrã, tudo para.

Todos os clips são sem som, em loop e playsinline, necessário para a reprodução automática no telemóvel.

Anime propriedades baratas

opacity, transform e clip-path podem ser compostas pela GPU. Animar top, width ou background-position em elementos grandes provoca recálculos ou redesenhos. A galeria horizontal move-se com translate3d, e a paralaxe de cada cartão desloca uma imagem interior através de uma transformação, não mudando a sua posição.

Sirva o vídeo com cabeça

Os clips são 720p, alguns megabytes cada, servidos através de um proxy edge que os põe em cache e suporta pedidos HTTP por intervalos, para o browser poder saltar e fazer streaming. Os posters vêm de imagens estáticas, para aparecer algo com sentido antes de ser descodificado o primeiro frame.

Respeite o movimento reduzido

Quando o visitante pediu ao sistema menos movimento, a secção deixa de ser fixada, a galeria passa a uma linha normal com scroll e o texto aparece sem animação. O conteúdo é idêntico; só a coreografia desaparece.

Defenda os seus estilos

A secção é injetada em muitos modelos diferentes, e um deles tinha uma regra de grelha genérica .gal que encolheu silenciosamente a faixa da galeria. Agora cada classe do componente tem prefixo. Se faz componentes que acabam em páginas que não controla, os espaços de nomes não são opcionais.

Resumo

  • Derive tudo de um único valor de progresso.
  • Agende com requestAnimationFrame; leia, depois escreva.
  • Um só vídeo a reproduzir; pré-carregamento a tempo; pausa fora do ecrã.
  • Anime apenas propriedades amigas do compositor.
  • Ponha o vídeo em cache e sirva-o por intervalos, na edge.
  • Respeite prefers-reduced-motion.
  • Dê um espaço de nomes aos estilos injetados.