Os temporizadores sempre foram a tecnologia central da animação JavaScript. A chave para escrever um loop de animação é saber quanto tempo é o atraso. Por um lado, o intervalo do loop deve ser curto o suficiente para fazer com que diferentes efeitos de animação pareçam suaves; por outro lado, o intervalo do loop deve ser longo o suficiente para garantir que o navegador tenha a capacidade de renderizar as alterações resultantes;
A taxa de atualização da maioria dos monitores de computador é de 60 Hz, o que equivale aproximadamente a 60 redesenhos por segundo. A maioria dos navegadores limitará as operações de redesenho a não mais do que a frequência de redesenho da exibição, porque mesmo além dessa frequência a experiência do usuário não será melhorada. Portanto, o intervalo de loop ideal para a animação mais suave é 1000 ms/60, que é aproximadamente igual a 16,6 ms.
O problema com setTimeout e setInterval é que eles não são precisos. Seu mecanismo operacional interno determina que o parâmetro de intervalo de tempo, na verdade, apenas especifica o tempo para adicionar o código de animação à fila de threads da IU do navegador para aguardar a execução. Se outras tarefas foram adicionadas ao início da fila, o código de animação deverá aguardar até que a tarefa anterior seja concluída antes de executá-la.
requestAnimationFrame usa o intervalo de tempo do sistema para manter a melhor eficiência de desenho. Não causará excesso de desenho e aumentará a sobrecarga porque o intervalo é muito curto. Também não fará com que a animação fique presa e irregular porque o intervalo é muito longo, permitindo. vários efeitos de animação de páginas da web a serem alcançados. Existe um mecanismo de atualização unificado para economizar recursos do sistema, melhorar o desempenho do sistema e melhorar os efeitos visuais.
CaracterísticasO método requestAnimationFrame recebe um retorno de chamada como parâmetro, e a função de retorno de chamada será passada em um parâmetro, DOMHighResTimeStamp, indicando o momento em que a função de retorno de chamada atualmente classificada por requestAnimationFrame() é acionada. O valor de retorno é um ID de solicitação, que representa um identificador exclusivo na lista de retorno de chamada. Este valor pode ser passado para window.cancelAnimationFrame() para cancelar a função de retorno de chamada.
requestID = window.requestAnimationFrame(retorno de chamada);
Usando esta API, determinados códigos podem ser executados durante a próxima nova renderização para evitar o acionamento de um grande número de refluxos em um curto período de tempo.
Por exemplo, a função de retorno de chamada do evento de rolagem da página (scroll) é muito adequada para usar esta API, adiando a operação de retorno de chamada até a próxima nova renderização. No entanto, deve-se observar que requestAnimationFrame não gerencia funções de retorno de chamada, ou seja, chamar requestAnimationFrame com a mesma função de retorno de chamada várias vezes antes de o retorno de chamada ser executado fará com que o retorno de chamada seja executado várias vezes no mesmo quadro. A maneira mais simples é usar uma função de otimização para resolver esse problema, ou você pode encontrar uma maneira de ter apenas uma mesma função de retorno de chamada na fila de requestAnimationFrame:
deixe agendadoAnimationFrame = false;document.body.onscroll = () => { if (scheduledAnimationFrame) return;
É claro que o melhor cenário de aplicação ainda é a animação de quadros, que pode otimizar bastante o desempenho.
Perguntas da entrevista Como renderizar dezenas de milhares de dados sem ficar preso na interfaceEsta questão examina como renderizar dados sem bloquear a página. Ou seja, você não pode renderizar dezenas de milhares de itens de uma vez, mas deve renderizar parte do DOM de uma só vez.
<!DOCTYPE html><html lang=en><head> <meta charset=UTF-8> <meta name=viewport content=width=device-width, escala inicial=1.0> <meta http-equiv=X-UA -Conteúdo compatível=ie=edge> <title>Documento</title></head><body> <ul>Controle</ul> <script> setTimeout(() => { // Insira 100.000 dados const total = 100.000 // Insira 20 dados por vez Se você acha que o desempenho não está bom, reduza const uma vez = 20 // Quantas vezes serão necessárias para renderizar os dados? uma vez let countOfRender = 0 let ul = document. querySelector(ul); function add() { // Otimizar o desempenho, a inserção não causará refluxo const fragment = document.createDocumentFragment(); uma vez; i++) { const li = document.createElement(li); li.innerText = Math.floor(Math.random() * total); 1; loop(); } function loop() { if (countOfRender < loopCount) { window.requestAnimationFrame(add); loop(); }, 0); </script></body></html>compatibilidade
Alguns navegadores antigos não suportam esta API. Para usar esta API, você pode personalizar este método e montá-lo na janela:
(function() { var lastTime = 0; var vendors = ['webkit', 'moz']; for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { window.requestAnimationFrame = janela[vendors[x]+'RequestAnimationFrame']; window.cancelAnimationFrame = janela[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame']; 0, 16 - (currTime - lastTime)); timeToCall); }, timeToCall); lastTime = currTime + timeToCall; return id };
O texto acima é todo o conteúdo deste artigo. Espero que seja útil para o estudo de todos. Também espero que todos apoiem a Rede VeVb Wulin.