Performance Web além do carregamento

Preview:

Citation preview

PERFORMANCE WEB ALÉM DO CARREGAMENTO

@sergio_caelum sergiolopes.org

PERFORMANCE?

VÁRIAS PERFORMANCES

VÁRIAS PERFORMANCESCARREGAMENTO

VÁRIAS PERFORMANCESCARREGAMENTOEXECUÇÃO

VÁRIAS PERFORMANCESCARREGAMENTOEXECUÇÃOINTERAÇÃO

VÁRIAS PERFORMANCESCARREGAMENTOEXECUÇÃOINTERAÇÃOANIMAÇÃO

VÁRIAS PERFORMANCESCARREGAMENTOEXECUÇÃOINTERAÇÃOANIMAÇÃOMEMÓRIA, BATERIA

PERFORMANCE

EXECUÇÃO INTERAÇÃO ANIMAÇÃO

PERFORMANCEEXECUÇÃO INTERAÇÃO ANIMAÇÃO

PERFORMANCEEXECUÇÃ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 SPASERVER SIDE RENDERING

MELHORAR TTI DE SPASERVER SIDE RENDERINGMENOS DEPENDÊNCIAS

MELHORAR TTI DE SPASERVER SIDE RENDERINGMENOS DEPENDÊNCIASCODE SPLITTING

MELHORAR TTI DE SPASERVER SIDE RENDERINGMENOS DEPENDÊNCIASCODE SPLITTINGTREE SHAKING

MELHORAR TTI DE SPASERVER SIDE RENDERINGMENOS DEPENDÊNCIASCODE SPLITTINGTREE SHAKINGAOT COMPILER

MELHORAR TTI DE SPASERVER SIDE RENDERINGMENOS DEPENDÊNCIASCODE SPLITTINGTREE SHAKINGAOT COMPILERFRAMEWORK 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

60FPS16ms

.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

opacity: 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 {opacity: 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 ANIMATIONFirst, Last, Invert, Play

PERFORMANCE WEB ALÉM DO CARREGAMENTO

OBRIGADO!

sergiolopes.org @sergio_caelum

Recommended