framebudget
Uma biblioteca JavaScript que mede quanto de cada frame de 16,7 ms um aparelho tem de verdade e liga só os efeitos visuais que cabem. Celular lento fica fluido, celular rápido fica com tudo.
A 60 Hz, cada frame tem um orçamento de 16,7 ms. Cada efeito visual de uma página, parallax, transição de página, animação em canvas, blur, som, gasta uma parte dele. O framebudget mede quanto orçamento o aparelho tem de verdade e libera só os efeitos que cabem, então um celular lento nunca engasga e um rápido fica com tudo.
Por que eu fiz
Os sites que eu faço se apoiam em motion: fios de cabelo vivos na home de um salão, uma galeria de estilos de screenshot com faixas em parallax. A maioria dos sites entrega o mesmo conjunto de efeitos para todo mundo, e a saída de costume é um chute pelo número de núcleos, pela memória ou por ser celular. A galeria deste site chutava exatamente assim, até o framebudget assumir. Eu queria que o aparelho fosse medido, não adivinhado.
Como funciona
- Antes do primeiro paint. Um script pequeno inline no
<head>roda um benchmark de uns 2 ms e escreve a decisão no<html>, então uma animação nunca começa só para travar. O CSS consegue condicionar um efeito sem JavaScript nenhum:html[data-framebudget-effects~="parallax"]. - Uma nota, não um tier. O benchmark dá uma nota em que 100 é o celular de referência. Cada efeito tem o próprio limite e o próprio custo por frame, com uma margem para que um aparelho no limite não fique alternando a cada visita.
- Uma segunda olhada. Depois que a página carrega e a engine esquenta, um benchmark mais longo refina a nota e guarda para a próxima página.
- Um governador. Ele observa os intervalos reais entre frames. Quando eles seguem atrasados, desliga o efeito mais caro, ou justamente o efeito cujo loop está engasgando.
- Aprendizado local. Os efeitos que engasgaram ficam guardados no aparelho e voltam a ser testados depois de algumas visitas limpas. Nada sai do aparelho a não ser que o desenvolvedor do site ligue o compartilhamento anônimo, que vem desligado.
A decisão inteira é um único objeto de limites e custos, então um site pode registrar os próprios efeitos e ajustar os que já vêm. Os números de referência ainda são provisórios e estão sendo calibrados em aparelhos reais.
A decisão desta página
-
hoverestados de hover -
entrancesassinatura e fita desenhadas -
shimmerbrilho na fita -
pageTransitioncostura entre páginas -
ribbonRedrawfita redesenhada -
ribbonFullfita com todos os fios -
carouselcarrossel do lab -
previewLoopsprévias animadas -
bluraviso e barra foscos -
parallaxgaleria em parallax -
soundsons da interface -
canvasHiRescostura em alta resolução
Neste site
Este site roda o framebudget em todas as páginas, com alguns efeitos
próprios registrados ao lado dos que já vêm. A assinatura e a fita se
desenham sob entrances, o brilho que segue percorrendo a fita é shimmer,
e a costura que prende uma página sobre a outra é pageTransition, com o
canvas em resolução cheia só sob canvasHiRes. A fita tem todos os fios sob
ribbonFull e menos abaixo disso; nos aparelhos mais lentos ela chega como
uma imagem parada. A costura, o carrossel e a fita reportam os próprios
frames ao governador, então um loop que engasga se desliga sozinho. A
galeria de estilos de screenshot cai para a versão
leve sem parallax. O site do Espaço Dora Santos
também usa.
Este site também compartilha as medições anônimas do framebudget com o framebudget.dev, que é como os números de referência são calibrados em aparelhos reais. A privacidade lista o que é enviado e como desligar.
Para ver a decisão do seu aparelho, abra
esta página com ?framebudget: um painel mostra a nota, o estado de cada
efeito e botões para forçar um tier. Para ver o site como um celular lento
vê, force o tier Lite
(e volte).
Como usar
import { bootScript } from 'framebudget/boot';
import { budget } from 'framebudget';
// No <head>, antes do CSS:
const head = `<script>${bootScript}</script>`;
// Em qualquer lugar depois:
if (budget.allows('parallax')) startParallax();
budget.on('change', (snapshot) => setEffects(snapshot.effects));
O pacote é escrito em TypeScript e vem com hooks para React. O site tem o tour completo, com um simulador que roda a página como um topo de linha, um intermediário ou um celular básico de 2019.