Máxima Performance en Navegadores Web

Eduardo Sada

Kairós DS

 

@aeroalquimia

¡Hola!

En el principio...

<button
  style="font-size: 10px;"
  onclick="_submitForm">Enviar</button>

HTML

CSS

JS

¡Todo bien separa'o!

¿Cómo es la web en 2017?

var React = require('react/addons');

require('./css')('\
.dialog {\
  z-index: 100;\
  position: absolute;\
  top: 0;\
  margin: 10px;\
  opacity: 0;\
  transform: scale(0.9) translateY(200%);\
}\
');

var Dialog = React.createClass({displayName: 'Dialog',
  render: function() {
    var open = this.props.open || false;

    var dialogClass = React.addons.classSet({
      dialog: true,
      open: open
    });

    return (
      React.createElement("div", {className: dialogClass}, 
        React.createElement(Shadow, null), 
        React.createElement("div", {className: "dialog-content"}, 
          this.props.children
        )
      )
    );
  },
});

¿   ?

La web en 2017 es...

  • 📱 Para pantallas pequeñas

  • 👆 Interactiva

  • 💃 Animada

  •     Con emojis universales

La web en 2017 es...

  • Increíble

  • Jugable

  • Para todos (accesible)

  • Offline

La web en 2017 es...

  • Lenta de c*(*&nes

Un montón de juguetes nuevos

VUE, INFERNOJS, REDUX, REACT, VIRTUAL DOM

¡Nos olvidamos del CSS!

Máxima Performance

Network Performance

Paint Performance

Quiero que mi web cargue rápido

Quiero que mi web se sienta ágil

Máxima Performance

10 cuadros por segundo

Ese gato no se mueve... son imágenes individuales

25 cuadros por segundo

Entiendo el movimiento

60 cuadros por segundo

la rehostia!

.box {
    animation: movebox 1s;
}

@keyframes movebox {
    from { left: 0 }
    to   { left: 100px }
}

60 Cuadros = 1 Segundo

1 Cuadro = 16 milisegundos

¿Cómo pinta el navegador mi código?

JS

Style

Layout

Paint

Composite

1 Cuadro

16ms x cuadro

upss

Partir el JS en varios cuadros

requestAnimationFrame(()=>{

  // run in each frame

});

el.addEventListener('click', () => {
  // la rehostia de cosas
});

16ms x cuadro

el.addEventListener('click', () => {
  // la rehostia de cosas
});
el.addEventListener('click', () => {

  requestAnimationFrame(() => {
    // la rehostia de cosas
  });

});

16ms x cuadro

click event

your shit

16ms x cuadro

click event

your shit

el.addEventListener('click', () => {

  requestAnimationFrame(() => {
    // la rehostia de cosas
  });

});
el.addEventListener('click', () => {

  requestAnimationFrame(() => {
    requestAnimationFrame(() => {
      // una cosa de 16ms
      // ¿necesito más frames?
    });
  });

});

Prioriza lo que quieras ejecutar

Evento Click

Responde inmediatamente a la acción

Siguientes Cuadros

Tus movidas

Hilo de Ejecución Principal

Main Thread

.show {
    animation: fadeIn 1s;
}

@keyframes fadeIn {
    from { opacity: 0 }
    to   { opacity: 1 }
}
element.classList.add('show');

// block the main thread for 3s just for fun
const t = performance.now();
while (performance.now() - t < 3000);

Hilo de Ejecución Principal

Main Thread

JS

Todo código JS se ejecuta en un hilo

¿Puedo abrir más hilos?

Sí, con WebWorkers

JS

CPU

GPU

JS

Main

GPU

JS

JS

CPU

Es preciso, pero sólo puede hacer una cosa a la vez

JS

CPU

element.top = 
    window.scrollY + node.height;

JS

GPU

Especialista en pintar

JS

GPU

transform: 
    translateY(calc(100vh - 100%));

JS

zoom x 100

JS

100px
100px
3 colores + alpha
100 x 100 x 4 = 40000 bytes
40KB

JS

40KB
4 bytes
.box {
  width: 1px;
  height: 1px;
  transform: scale(100, 100);
  will-change: transform;
}
.overlay {
  background-color: rgba(0, 0, 0, 0.1);
  width: 10vw;
  height: 10vh;
  will-change: transform;
  transform: scale(10);
  transform-origin: left top;
}

En una resolución 1433 x 738 nos ahorramos...

4MB de memoria

JS

Style

1 Cuadro

Style

Calcula y relaciona los estilos del CSS con lo que debe pintar en pantalla

Si agrego una clase al body...

¿afecta a esos 500 divs que tengo de hijos?

JS

Style

Layout

1 Cuadro

Layout

Reflow

Layout

Cálculos geométricos

CPU

Por las dudas, calculo todo de nuevo

Layout

contain: layout;

Layout

JS

Style

Layout

Paint

1 Cuadro

Paint

Paint

Calculo las zonas que se han modificado

Paint

CPU

GPU

JS

Style

Layout

Paint

Composite

1 Cuadro

Compositing

2d

Compositing

Compositing

Ciertas propiedades promueven un elemento a nueva capa

Compositing

  • 3D transforms: translate3d, scale, rotate, etc;
  • <video>, <canvas> and <iframe> elements;
  • animation of transform and opacity;
  • position: fixed;
  • will-change;
  • filter;

Compositing

left: 100px
transform:
  translateX(100px)

Use translateZ for everything!!!

Use translateZ for everything!!!

Compositing

Imaginaros que...

  • Animo      con left

  •     no se ha promovido a una nueva capa

La GPU promocionará     a una nueva capa

Composición Implícita! agg

Compositing

Evitar la composición implícita

Un elemento está quieto.

No hay capas de composición.

hostia, que se mueve

Compositing

Evitar la composición implícita

La animación ha terminado.

Poner todo en su lugar.

ha terminao!

Use translateZ for everything!!!

will-change

CSS es declarativo: El navegador intentará optimizarlo antes de que se ejecute

JS es imperativo

JS

Style

Layout

Paint

Composite

1 Cuadro

Optimizar es un trabajo artesanal

¡No hay atajos!

Yo, justificando mi sueldo ante mi jefe

@aeroalquimia

Eduardo Sada

Trabajo en Kairós

web components a tope!

¡Gracias!

@aeroalquimia

Eduardo Sada

Máxima Performance 2

By Eduardo Sada

Máxima Performance 2

  • 967