PERFORMANCE WEB ALM DO CARREGAMENTO @sergio_caelum sergiolopes.org - - PowerPoint PPT Presentation
PERFORMANCE WEB ALM DO CARREGAMENTO @sergio_caelum sergiolopes.org - - PowerPoint PPT Presentation
PERFORMANCE WEB ALM DO CARREGAMENTO @sergio_caelum sergiolopes.org PERFORMANCE? VRIAS PERFORMANCES VRIAS PERFORMANCES CARREGAMENTO VRIAS PERFORMANCES CARREGAMENTO EXECUO VRIAS PERFORMANCES CARREGAMENTO EXECUO
@sergio_caelum sergiolopes.org
PERFORMANCE?
VÁRIAS PERFORMANCES
VÁRIAS PERFORMANCES
CARREGAMENTO
VÁRIAS PERFORMANCES
CARREGAMENTO EXECUÇÃO
VÁRIAS PERFORMANCES
CARREGAMENTO EXECUÇÃO INTERAÇÃO
VÁRIAS PERFORMANCES
CARREGAMENTO EXECUÇÃO INTERAÇÃO ANIMAÇÃO
VÁRIAS PERFORMANCES
CARREGAMENTO EXECUÇÃO INTERAÇÃO ANIMAÇÃO MEMÓRIA, BATERIA
PERFORMANCE
EXECUÇÃO INTERAÇÃO ANIMAÇÃO
PERFORMANCE
EXECUÇÃO INTERAÇÃO ANIMAÇÃO
PERFORMANCE
EXECUÇÃO INTERAÇÃO ANIMAÇÃO MAIN THREAD OCUPADA. MUITO LAYOUT / PAINT.
MAIN THREAD
RESPONSE 100ms
QUEBRAR EM BLOCOS MENORES NÃO USAR A MAIN THREAD
QUEBRAR EM BLOCOS MENORES NÃO USAR A MAIN THREAD
setTimeout(funcao, 10);
setTimeout(funcao, 10); setImmediate(funcao);
setTimeout(funcao, 10); setImmediate(funcao); requestAnimationFrame(funcao);
setTimeout(funcao, 10); setImmediate(funcao); requestAnimationFrame(funcao); requestIdleCallback(funcao);
IDLE TIME
QUEBRAR EM BLOCOS MENORES NÃO USAR A MAIN THREAD
WEB WORKERS
MULTI THREAD
MELHORAR TTI DE SPA
MELHORAR TTI DE SPA
SERVER SIDE RENDERING
MELHORAR TTI DE SPA
SERVER SIDE RENDERING MENOS DEPENDÊNCIAS
MELHORAR TTI DE SPA
SERVER SIDE RENDERING MENOS DEPENDÊNCIAS CODE SPLITTING
MELHORAR TTI DE SPA
SERVER SIDE RENDERING MENOS DEPENDÊNCIAS CODE SPLITTING TREE SHAKING
MELHORAR TTI DE SPA
SERVER SIDE RENDERING MENOS DEPENDÊNCIAS CODE SPLITTING TREE SHAKING AOT COMPILER
MELHORAR TTI DE SPA
SERVER SIDE RENDERING MENOS DEPENDÊNCIAS CODE SPLITTING TREE SHAKING AOT COMPILER FRAMEWORK COM WEB WORKER
QUEBRAR EM BLOCOS MENORES NÃO USAR A MAIN THREAD
@keyframes anima { to { left: 200px; width: 250px; } } @keyframes animaGPU { to { transform: translateX(200px) scale(1.7); } }
60FPS
60FPS 16ms
.container { top: 0; transition: top 500ms; } .container.buscaVisivel { top: 100px; }
.container { top: 0; transition: top 500ms; } .container.buscaVisivel { top: 100px; }
.container { transition: transform 500ms; } .container.buscaVisivel { transform: translateY(100px); }
.container { transition: transform 500ms; will-change: transform; } .container.buscaVisivel { transform: translateY(100px); }
.container { transition: transform 500ms; will-change: transform; } .container.buscaVisivel { transform: translateY(100px); } .container { transition: transform 500ms; transform: translateZ(0); } .container.buscaVisivel { transform: translateY(100px); }
INICIAL
INICIAL FINAL
INICIAL FINAL
INICIAL FINAL
- pacity: 0;
transition: opacity 500ms ease-out;
INICIAL
INICIAL FINAL
INICIAL FINAL
var posInicial = cartao.getBoundingClientRect();
INICIAL FINAL
var posInicial = cartao.getBoundingClientRect(); cartaoARemover.classList.add('remove');
INICIAL FINAL
var posInicial = cartao.getBoundingClientRect(); cartaoARemover.classList.add('remove'); var posFinal = cartao.getBoundingClientRect();
INICIAL FINAL
INICIAL FINAL
var x = posInicial.left - posFinal.left;
INICIAL FINAL
var x = posInicial.left - posFinal.left; var y = posInicial.top - posFinal.top;
INICIAL FINAL
var x = posInicial.left - posFinal.left; var y = posInicial.top - posFinal.top;
INICIAL FINAL
var x = posInicial.left - posFinal.left; var y = posInicial.top - posFinal.top; cartao.style.transform = `translate(${x}px, ${y}px)`;
INICIAL FINAL INVERTE
var x = posInicial.left - posFinal.left; var y = posInicial.top - posFinal.top; cartao.style.transform = `translate(${x}px, ${y}px)`;
INICIAL FINAL INVERTE
INICIAL FINAL INVERTE
transform: none; transition: transform 500ms ease-out;
INICIAL FINAL INVERTE PLAY
transform: none; transition: transform 500ms ease-out;
FIRST LAST INVERT PLAY
FLIP
FIRST LAST INVERT PLAY
FLIP
cartoes.forEach((cartao) => cartao.addEventListener('click', cartaoOnClick)); function cartaoOnClick() { // preparaAnimacao // disparaAnimacao // aposAnimacao }
cartoes.forEach((cartao) => cartao.addEventListener('click', cartaoOnClick)); function cartaoOnClick() { preparaAnimacao(this); // disparaAnimacao // aposAnimacao } function preparaAnimacao(cartaoARemover) { }
cartoes.forEach((cartao) => cartao.addEventListener('click', cartaoOnClick)); function cartaoOnClick() { preparaAnimacao(this); // disparaAnimacao // aposAnimacao } function preparaAnimacao(cartaoARemover) { }
cartoes.forEach((cartao) => cartao.addEventListener('click', cartaoOnClick)); function cartaoOnClick() { preparaAnimacao(this); // disparaAnimacao // aposAnimacao } function preparaAnimacao(cartaoARemover) { } var posInicial = cartoes.map((cartao) => cartao.getBoundingClientRect());
cartoes.forEach((cartao) => cartao.addEventListener('click', cartaoOnClick)); function cartaoOnClick() { preparaAnimacao(this); // disparaAnimacao // aposAnimacao } function preparaAnimacao(cartaoARemover) { } var posInicial = cartoes.map((cartao) => cartao.getBoundingClientRect()); cartaoARemover.classList.add('remove');
cartoes.forEach((cartao) => cartao.addEventListener('click', cartaoOnClick)); function cartaoOnClick() { preparaAnimacao(this); // disparaAnimacao // aposAnimacao } function preparaAnimacao(cartaoARemover) { } var posInicial = cartoes.map((cartao) => cartao.getBoundingClientRect()); cartaoARemover.classList.add('remove');
.cartao.remove { position: absolute; }
cartoes.forEach((cartao) => cartao.addEventListener('click', cartaoOnClick)); function cartaoOnClick() { preparaAnimacao(this); // disparaAnimacao // aposAnimacao } function preparaAnimacao(cartaoARemover) { var posInicial = cartoes.map((cartao) => cartao.getBoundingClientRect()); cartaoARemover.classList.add('remove'); }
cartoes.forEach((cartao) => cartao.addEventListener('click', cartaoOnClick)); function cartaoOnClick() { preparaAnimacao(this); // disparaAnimacao // aposAnimacao } function preparaAnimacao(cartaoARemover) { var posInicial = cartoes.map((cartao) => cartao.getBoundingClientRect()); cartaoARemover.classList.add('remove'); } cartoes.forEach((cartao, i) => {
cartoes.forEach((cartao) => cartao.addEventListener('click', cartaoOnClick)); function cartaoOnClick() { preparaAnimacao(this); // disparaAnimacao // aposAnimacao } function preparaAnimacao(cartaoARemover) { var posInicial = cartoes.map((cartao) => cartao.getBoundingClientRect()); cartaoARemover.classList.add('remove'); } cartoes.forEach((cartao, i) => { var posFinal = cartao.getBoundingClientRect();
cartoes.forEach((cartao) => cartao.addEventListener('click', cartaoOnClick)); function cartaoOnClick() { preparaAnimacao(this); // disparaAnimacao // aposAnimacao } function preparaAnimacao(cartaoARemover) { var posInicial = cartoes.map((cartao) => cartao.getBoundingClientRect()); cartaoARemover.classList.add('remove'); } cartoes.forEach((cartao, i) => { var posFinal = cartao.getBoundingClientRect(); var x = posInicial[i].left - posFinal.left;
cartoes.forEach((cartao) => cartao.addEventListener('click', cartaoOnClick)); function cartaoOnClick() { preparaAnimacao(this); // disparaAnimacao // aposAnimacao } function preparaAnimacao(cartaoARemover) { var posInicial = cartoes.map((cartao) => cartao.getBoundingClientRect()); cartaoARemover.classList.add('remove'); } cartoes.forEach((cartao, i) => { var posFinal = cartao.getBoundingClientRect(); var x = posInicial[i].left - posFinal.left; var y = posInicial[i].top - posFinal.top;
cartoes.forEach((cartao) => cartao.addEventListener('click', cartaoOnClick)); function cartaoOnClick() { preparaAnimacao(this); // disparaAnimacao // aposAnimacao } function preparaAnimacao(cartaoARemover) { var posInicial = cartoes.map((cartao) => cartao.getBoundingClientRect()); cartaoARemover.classList.add('remove'); } cartoes.forEach((cartao, i) => { var posFinal = cartao.getBoundingClientRect(); var x = posInicial[i].left - posFinal.left; var y = posInicial[i].top - posFinal.top; cartao.style.transform = `translate(${x}px, ${y}px)`;
cartoes.forEach((cartao) => cartao.addEventListener('click', cartaoOnClick)); function cartaoOnClick() { preparaAnimacao(this); // disparaAnimacao // aposAnimacao } function preparaAnimacao(cartaoARemover) { var posInicial = cartoes.map((cartao) => cartao.getBoundingClientRect()); cartaoARemover.classList.add('remove'); } cartoes.forEach((cartao, i) => { var posFinal = cartao.getBoundingClientRect(); var x = posInicial[i].left - posFinal.left; var y = posInicial[i].top - posFinal.top; cartao.style.transform = `translate(${x}px, ${y}px)`; });
cartoes.forEach((cartao) => cartao.addEventListener('click', cartaoOnClick)); function cartaoOnClick() { preparaAnimacao(this); // disparaAnimacao // aposAnimacao } function preparaAnimacao(cartaoARemover) { var posInicial = cartoes.map((cartao) => cartao.getBoundingClientRect()); cartaoARemover.classList.add('remove'); cartoes.forEach((cartao, i) => { var posFinal = cartao.getBoundingClientRect(); var x = posInicial[i].left - posFinal.left; var y = posInicial[i].top - posFinal.top; cartao.style.transform = `translate(${x}px, ${y}px)`; }); } function disparaAnimacao() { cartoes.forEach((cartao) => cartao.style.transform = '' ); lista.classList.add('anima'); }
cartoes.forEach((cartao) => cartao.addEventListener('click', cartaoOnClick)); function cartaoOnClick() { preparaAnimacao(this); // disparaAnimacao // aposAnimacao } function preparaAnimacao(cartaoARemover) { var posInicial = cartoes.map((cartao) => cartao.getBoundingClientRect()); cartaoARemover.classList.add('remove'); cartoes.forEach((cartao, i) => { var posFinal = cartao.getBoundingClientRect(); var x = posInicial[i].left - posFinal.left; var y = posInicial[i].top - posFinal.top; cartao.style.transform = `translate(${x}px, ${y}px)`; }); } function disparaAnimacao() { cartoes.forEach((cartao) => cartao.style.transform = '' ); lista.classList.add('anima'); }
.anima .cartao { transition: 500ms ease-out; } .anima .cartao.remove {
- pacity: 0;
}
cartoes.forEach((cartao) => cartao.addEventListener('click', cartaoOnClick)); function cartaoOnClick() { preparaAnimacao(this); disparaAnimacao(); // aposAnimacao } function preparaAnimacao(cartaoARemover) { var posInicial = cartoes.map((cartao) => cartao.getBoundingClientRect()); cartaoARemover.classList.add('remove'); cartoes.forEach((cartao, i) => { var posFinal = cartao.getBoundingClientRect(); var x = posInicial[i].left - posFinal.left; var y = posInicial[i].top - posFinal.top; cartao.style.transform = `translate(${x}px, ${y}px)`; }); } function disparaAnimacao() { cartoes.forEach((cartao) => cartao.style.transform = '' ); lista.classList.add('anima'); }
cartoes.forEach((cartao) => cartao.addEventListener('click', cartaoOnClick)); function cartaoOnClick() { preparaAnimacao(this); requestAnimationFrame(disparaAnimacao); // aposAnimacao } function preparaAnimacao(cartaoARemover) { var posInicial = cartoes.map((cartao) => cartao.getBoundingClientRect()); cartaoARemover.classList.add('remove'); cartoes.forEach((cartao, i) => { var posFinal = cartao.getBoundingClientRect(); var x = posInicial[i].left - posFinal.left; var y = posInicial[i].top - posFinal.top; cartao.style.transform = `translate(${x}px, ${y}px)`; }); } function disparaAnimacao() { cartoes.forEach((cartao) => cartao.style.transform = '' ); lista.classList.add('anima'); }
cartoes.forEach((cartao) => cartao.addEventListener('click', cartaoOnClick)); function cartaoOnClick() { preparaAnimacao(this); requestAnimationFrame(disparaAnimacao); // aposAnimacao } function preparaAnimacao(cartaoARemover) { var posInicial = cartoes.map((cartao) => cartao.getBoundingClientRect()); cartaoARemover.classList.add('remove'); cartoes.forEach((cartao, i) => { var posFinal = cartao.getBoundingClientRect(); var x = posInicial[i].left - posFinal.left; var y = posInicial[i].top - posFinal.top; cartao.style.transform = `translate(${x}px, ${y}px)`; }); } function disparaAnimacao() { cartoes.forEach((cartao) => cartao.style.transform = '' ); lista.classList.add('anima'); } function aposAnimacao() { lista.classList.remove('anima'); this.remove(); }
cartoes.forEach((cartao) => cartao.addEventListener('click', cartaoOnClick)); function cartaoOnClick() { preparaAnimacao(this); requestAnimationFrame(disparaAnimacao); this.addEventListener('transitionend', aposAnimacao); } function preparaAnimacao(cartaoARemover) { var posInicial = cartoes.map((cartao) => cartao.getBoundingClientRect()); cartaoARemover.classList.add('remove'); cartoes.forEach((cartao, i) => { var posFinal = cartao.getBoundingClientRect(); var x = posInicial[i].left - posFinal.left; var y = posInicial[i].top - posFinal.top; cartao.style.transform = `translate(${x}px, ${y}px)`; }); } function disparaAnimacao() { cartoes.forEach((cartao) => cartao.style.transform = '' ); lista.classList.add('anima'); } function aposAnimacao() { lista.classList.remove('anima'); this.remove(); }
cartoes.forEach((cartao) => cartao.addEventListener('click', cartaoOnClick)); function cartaoOnClick() { preparaAnimacao(this); requestAnimationFrame(disparaAnimacao); this.addEventListener('transitionend', aposAnimacao); } function preparaAnimacao(cartaoARemover) { var posInicial = cartoes.map((cartao) => cartao.getBoundingClientRect()); cartaoARemover.classList.add('remove'); cartoes.forEach((cartao, i) => { var posFinal = cartao.getBoundingClientRect(); var x = posInicial[i].left - posFinal.left; var y = posInicial[i].top - posFinal.top; cartao.style.transform = `translate(${x}px, ${y}px)`; }); } function disparaAnimacao() { cartoes.forEach((cartao) => cartao.style.transform = '' ); lista.classList.add('anima'); } function aposAnimacao() { lista.classList.remove('anima'); this.remove(); }
FLIP ANIMATION
First, Last, Invert, Play
PERFORMANCE WEB
ALÉM DO CARREGAMENTO
OBRIGADO!
sergiolopes.org @sergio_caelum