Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Performance Web além do carregamento

485 views

Published on

Execução, Interação, Animação.

Palestra do Sérgio Lopes

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Performance Web além do carregamento

  1. 1. PERFORMANCE WEB ALÉM DO CARREGAMENTO
  2. 2. @sergio_caelum sergiolopes.org
  3. 3. PERFORMANCE?
  4. 4. VÁRIAS PERFORMANCES
  5. 5. VÁRIAS PERFORMANCES CARREGAMENTO
  6. 6. VÁRIAS PERFORMANCES CARREGAMENTO EXECUÇÃO
  7. 7. VÁRIAS PERFORMANCES CARREGAMENTO EXECUÇÃO INTERAÇÃO
  8. 8. VÁRIAS PERFORMANCES CARREGAMENTO EXECUÇÃO INTERAÇÃO ANIMAÇÃO
  9. 9. VÁRIAS PERFORMANCES CARREGAMENTO EXECUÇÃO INTERAÇÃO ANIMAÇÃO MEMÓRIA,BATERIA
  10. 10. PERFORMANCE EXECUÇÃO INTERAÇÃO ANIMAÇÃO
  11. 11. PERFORMANCE EXECUÇÃO INTERAÇÃO ANIMAÇÃO
  12. 12. PERFORMANCE EXECUÇÃO INTERAÇÃO ANIMAÇÃO MAIN THREAD OCUPADA. MUITO LAYOUT / PAINT.
  13. 13. MAIN THREAD
  14. 14. RESPONSE 100ms
  15. 15. QUEBRAR EM BLOCOS MENORES NÃO USAR A MAIN THREAD
  16. 16. QUEBRAR EM BLOCOS MENORES NÃO USAR A MAIN THREAD
  17. 17. setTimeout(funcao, 10);
  18. 18. setTimeout(funcao, 10); setImmediate(funcao);
  19. 19. setTimeout(funcao, 10); setImmediate(funcao); requestAnimationFrame(funcao);
  20. 20. setTimeout(funcao, 10); setImmediate(funcao); requestAnimationFrame(funcao); requestIdleCallback(funcao);
  21. 21. IDLE TIME
  22. 22. QUEBRAR EM BLOCOS MENORES NÃO USAR A MAIN THREAD
  23. 23. WEB WORKERS
  24. 24. MULTI THREAD
  25. 25. MELHORAR TTI DE SPA
  26. 26. MELHORAR TTI DE SPA SERVER SIDE RENDERING
  27. 27. MELHORAR TTI DE SPA SERVER SIDE RENDERING MENOS DEPENDÊNCIAS
  28. 28. MELHORAR TTI DE SPA SERVER SIDE RENDERING MENOS DEPENDÊNCIAS CODE SPLITTING
  29. 29. MELHORAR TTI DE SPA SERVER SIDE RENDERING MENOS DEPENDÊNCIAS CODE SPLITTING TREE SHAKING
  30. 30. MELHORAR TTI DE SPA SERVER SIDE RENDERING MENOS DEPENDÊNCIAS CODE SPLITTING TREE SHAKING AOT COMPILER
  31. 31. MELHORAR TTI DE SPA SERVER SIDE RENDERING MENOS DEPENDÊNCIAS CODE SPLITTING TREE SHAKING AOT COMPILER FRAMEWORK COM WEB WORKER
  32. 32. QUEBRAR EM BLOCOS MENORES NÃO USAR A MAIN THREAD
  33. 33. @keyframes anima { to { left: 200px; width: 250px; } } @keyframes animaGPU { to { transform: translateX(200px) scale(1.7); } }
  34. 34. 60FPS
  35. 35. 60FPS 16ms
  36. 36. .container { top: 0; transition: top 500ms; } .container.buscaVisivel { top: 100px; }
  37. 37. .container { top: 0; transition: top 500ms; } .container.buscaVisivel { top: 100px; }
  38. 38. .container { transition: transform 500ms; } .container.buscaVisivel { transform: translateY(100px); }
  39. 39. .container { transition: transform 500ms; will-change: transform; } .container.buscaVisivel { transform: translateY(100px); }
  40. 40. .container { transition: transform 500ms; will-change: transform; } .container.buscaVisivel { transform: translateY(100px); } .container { transition: transform 500ms; transform: translateZ(0); } .container.buscaVisivel { transform: translateY(100px); }
  41. 41. INICIAL
  42. 42. INICIAL FINAL
  43. 43. INICIAL FINAL
  44. 44. INICIAL FINAL opacity: 0; transition: opacity 500ms ease-out;
  45. 45. INICIAL
  46. 46. INICIAL FINAL
  47. 47. INICIAL FINAL var posInicial = cartao.getBoundingClientRect();
  48. 48. INICIAL FINAL var posInicial = cartao.getBoundingClientRect(); cartaoARemover.classList.add('remove');
  49. 49. INICIAL FINAL var posInicial = cartao.getBoundingClientRect(); cartaoARemover.classList.add('remove'); var posFinal = cartao.getBoundingClientRect();
  50. 50. INICIAL FINAL
  51. 51. INICIAL FINAL var x = posInicial.left - posFinal.left;
  52. 52. INICIAL FINAL var x = posInicial.left - posFinal.left; var y = posInicial.top - posFinal.top;
  53. 53. INICIAL FINAL var x = posInicial.left - posFinal.left; var y = posInicial.top - posFinal.top;
  54. 54. INICIAL FINAL var x = posInicial.left - posFinal.left; var y = posInicial.top - posFinal.top; cartao.style.transform = `translate(${x}px, ${y}px)`;
  55. 55. INICIAL FINAL INVERTE var x = posInicial.left - posFinal.left; var y = posInicial.top - posFinal.top; cartao.style.transform = `translate(${x}px, ${y}px)`;
  56. 56. INICIAL FINAL INVERTE
  57. 57. INICIAL FINAL INVERTE transform: none; transition: transform 500ms ease-out;
  58. 58. INICIAL FINAL INVERTE PLAY transform: none; transition: transform 500ms ease-out;
  59. 59. FIRST LAST INVERT PLAY FLIP
  60. 60. FIRST LAST INVERT PLAY FLIP
  61. 61. cartoes.forEach((cartao) => cartao.addEventListener('click', cartaoOnClick)); function cartaoOnClick() { // preparaAnimacao // disparaAnimacao // aposAnimacao }
  62. 62. cartoes.forEach((cartao) => cartao.addEventListener('click', cartaoOnClick)); function cartaoOnClick() { preparaAnimacao(this); // disparaAnimacao // aposAnimacao } function preparaAnimacao(cartaoARemover) { }
  63. 63. cartoes.forEach((cartao) => cartao.addEventListener('click', cartaoOnClick)); function cartaoOnClick() { preparaAnimacao(this); // disparaAnimacao // aposAnimacao } function preparaAnimacao(cartaoARemover) { }
  64. 64. cartoes.forEach((cartao) => cartao.addEventListener('click', cartaoOnClick)); function cartaoOnClick() { preparaAnimacao(this); // disparaAnimacao // aposAnimacao } function preparaAnimacao(cartaoARemover) { } var posInicial = cartoes.map((cartao) => cartao.getBoundingClientRect());
  65. 65. 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');
  66. 66. 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; }
  67. 67. 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'); }
  68. 68. 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) => {
  69. 69. 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();
  70. 70. 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;
  71. 71. 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;
  72. 72. 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)`;
  73. 73. 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)`; });
  74. 74. 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'); }
  75. 75. 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; }
  76. 76. 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'); }
  77. 77. 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'); }
  78. 78. 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(); }
  79. 79. 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(); }
  80. 80. 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(); }
  81. 81. FLIP ANIMATION First, Last, Invert, Play
  82. 82. PERFORMANCE WEB ALÉM DO CARREGAMENTO
  83. 83. OBRIGADO! sergiolopes.org @sergio_caelum

×