Hi pig_JSDay-v2

79
Javascript y por que no Comparar la Velocidad con el Tocino

Transcript of Hi pig_JSDay-v2

Page 1: Hi pig_JSDay-v2

Javascripty por que no

Comparar la Velocidad

con el Tocino

Page 2: Hi pig_JSDay-v2

Isabel Cabezas@[email protected]@techdencias.net

FrontEnd Sharepointer en pasionaDivulgadora Tecnológica en Fundación Techdencias

Toni Recio@[email protected]@techdencias.net

Responsable de Tecnología e Innovación en pasionaDivulgador Tecnológico en Fundación Techdencias

Page 4: Hi pig_JSDay-v2
Page 5: Hi pig_JSDay-v2

Agenda

1. ¡Jugando con HiPig!2. Navegador y JavaScript3. ¿Por qué mi aplicación va lenta?4. Cinco principios sobre eficiencia: Controla la memoria Eficiencia en la gestión de objetos Rapidez matemática Domina los arrays Obtener objetos del DOM

Principios CERDO

Page 6: Hi pig_JSDay-v2

for (var i = 0; i < 100; i++) {

HighFive.game.onTouch();

}

Contador de FPS

Benchmark mode

La piara

Puntuación

var start = Date.now();

for (var i = 0; i < 100; i++) {

HighFive.game.onTouch();

}

var total = (Date.now()) - start;

Time

Page 7: Hi pig_JSDay-v2

Matriz de cerditos

Cada cerdito se tiene cuatro direcciones

Selecciona un cerdito al

tocarlo

Genera una lista de vecinos

cerdos para rotar

Se rota el cerdito

Repetir toda la lista de vecinos

Matriz => Array

Cerdo => Objeto

Direcciones del jugador => Propiedades del Objeto

Números Operaciones matemáticasy operaciones con arrays

Direcciones de memoria

Animaciones

Page 8: Hi pig_JSDay-v2

Aplicaciones Lentas

El mal código genera aplicaciones lentas.

FPS en Firefox

Glitchs

Page 9: Hi pig_JSDay-v2

Lo que de verdad importa...en el rendimiento visual del juego

Net

wo

rkin

g

HTM

L

CSS

Co

lecc

ion

es

Java

Scri

pt

Loca

lizac

ión

MO

Nat

ivo

Form

ate

o

Co

nst

. b

loq

ue

s

Dis

o

Vis

ual

izac

ión

Pila de subsistemas del navegador

+Código

Dibujar

1

2 7

43 8 9

5 6

DOMTreeAnálisis

1

2 7

43 8 9

5 6

Display TreeMotorJSMotor JS Navegador

Page 10: Hi pig_JSDay-v2

Repetir 60 veces por segundo!

16.67ms

Page 11: Hi pig_JSDay-v2

Profilers... o cómo saber por dónde se van los milisegundos

MotorJS

Tu código

Otrossubsistemas

Page 13: Hi pig_JSDay-v2

Internet Explorer F12 UI Responsiveness Tool

http://msdn.microsoft.com/library/ie/aa740471

DEMO

Page 14: Hi pig_JSDay-v2

Análisis del resultado

MotorJS

GC

Page 15: Hi pig_JSDay-v2

El Garbage Collector (GC)

Page 16: Hi pig_JSDay-v2

¿Cómo funciona el GC?

Obj1 Obj1a Obj1b Root Obj2 Obj2a Obj2b Obj2c

Obj2d C-1 C-2 Obj2e Obj3 ... ... ...

... ... ... ... ... ... ... ...

... C-1a ... C-1b C-1c C-1a1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

Programa ProgramaInicializado

Objetospequeños

Objetosgrandes

Zero out

Page 17: Hi pig_JSDay-v2

Cuándo se llama al GC??

Cada llamada a new, o cada reserva implícita de una asignación de

memoria. Todas las nuevas reservas de memoria son “baratas” (en

coste de ejecución) hasta que el pool se agota.

Cuando el pool se agota y no quedan más localizaciones libres

entonces el motor fuerza una “collecta”. ¿Nos acordamos de los

16.67ms?

Cada petición de memoria te lleva más cerca de una

pausa causada por el GC.

Page 18: Hi pig_JSDay-v2

Principio #1Controla la memoria

Page 19: Hi pig_JSDay-v2

Un poquito de codigo...

8. var HiPig = {};9.10. (function (root) {11.12. function Game() {13. this.boardSize = 26;14. this.matrix = new Array(this.boardSize);15. this.tmpMatrix = new Array();16. this.nextNodesStack = new Array();17. this.currentNodesList = new Array();18. this.gameInProgress = false;19. this.gameScore = 0;20. this.recordScore = 0;21. }

Page 20: Hi pig_JSDay-v2

Un poquito de codigo...

28. function Pig(n, e, s, w) {29. Object.defineProperty(this, "north", {30. get: function () { return nVal; },31. set: function (value) { nVal = value; }32. enumerable: true,33. configurable: true34. });

/** Se han omitido las propiedades east, south, west **/

53. var nVal = n;54. var eVal = e;55. var sVal = s;56. var wVal = w;

}

Page 21: Hi pig_JSDay-v2

Un poquito de codigo...56. function Toni(n, e, s, w) {57. Pig.apply(this, arguments);58. this.name = "Toni";59. } 60. Toni.prototype = new Pig();61.62. function Isa(n, e, s, w) {63. Pig.apply(this, arguments);64. this.name = "Isa";65. }66. Isa.prototype = new Pig();67.68. Game.prototype.initialize = function () {69. for (var i = 0; i < this.boardSize; i++) {70. this.matrix[i] = new Array(this.boardSize);71. } 72. }

Page 22: Hi pig_JSDay-v2

Las posturas de Isa

new Isa(0, 1, 1, 0) = “ES”

Isa(n, e, s, o) {

N

E

S

O

(0, 0, 1, 1)

(1, 0, 0, 1) (1, 1, 0, 0)

(0, 1, 1, 0)

Page 23: Hi pig_JSDay-v2

Rotando330. Game.prototype.rotate = function (node) {

331. var x = node[0]; var y = node[1];

332.

333. if (root.game.matrix[x][y]["north"] &&

root.game.matrix[x][y]["east"]) {

330. //si el pig mira al NE, su nueva posición es NO

331. root.game.tmpMatrix.push([x, y, "NO", 1]);332. }

333. else if (root.game.matrix[x][y]["east"] &&

root.game.matrix[x][y]["south"]) {

//si el jugador mira al ES, su nueva posición es SW

330. root.game.tmpMatrix.push([x, y, "SO", 1]);331. }

332. /** Se han omitido los otros dos giros **/

333. }

i j

17 23 “NO” 1

Page 24: Hi pig_JSDay-v2

Dibujando el giro

366.Game.prototype.commitRotation = function () {367.

368. var node = this.tmpMatrix.pop();369. while (node) {

370. if (node[2] == "NE") {371. if (this.matrix[node[0]][node[1]].name == "Toni") {

372. this.matrix[node[0]][node[1]] = new Toni(1, 1, 0, 0);373. } else {

374. this.matrix[node[0]][node[1]] = new Isa(1, 1, 0, 0);375. }

/** y mas if’s **/

17 23 “NE” 1

¿Dónde va “old” Toni?

Page 25: Hi pig_JSDay-v2

Reduciendo la reserva de memoria

(0, 0, 1, 1)

(1, 0, 0, 1) (1, 1, 0, 0)

(0, 1, 1, 0)

N =1

S = 0

Isa(n, e, s, o) {

E =0

O=1

N =0

S = 1

E =1

O= 0

Page 26: Hi pig_JSDay-v2

Rotacion mejorada

347.Game.prototype.rotateFast = function (node) {348. var x = node[0];349. var y = node[1];350. if (root.game.matrix[x][y].north && root.game.matrix[x][y].east) {351. root.game.tmpMatrix.push([x, y, "north", 0]);

352. root.game.tmpMatrix.push([x, y, "south", 1]);353. } else if (... )

17 23 “north” 0

17 23 “south” 1

Page 27: Hi pig_JSDay-v2

Rotacion mejorada

399. Game.prototype.commitRotation = function () {400.401. var node = this.tmpMatrix.pop();402. while (node) {403. if (node[2] == "north") {

404. this.matrix[node[0]][node[1]].north = node[3];405. } else if (node[2] == "east") {

406. this.matrix[node[0]][node[1]].east = node[3];407.

17 23 “north” 0

17 23 “south” 1

Page 28: Hi pig_JSDay-v2
Page 29: Hi pig_JSDay-v2

Resultados

Page 30: Hi pig_JSDay-v2

0 2000 4000 6000 8000 10000 12000 14000

Original

Memoria

ResultadosOriginal Tiempo: 13001 milisegundos

Cerditos rotados: 11814

Ahorro de Memoria Tiempo: 4248 milisegundos

Cerditos rotados: 11814

Page 31: Hi pig_JSDay-v2

Novedades en Chakra

• Ventajas de la Recolección de basura concurrente.

• Reducir esperas gracias a recursos hardware libres.

• Recolecciones parciales (tiempo restringido)

• Páginas separadas para objetos grandes y pequeños (evita la fragmentación)

ProgramaBarrido

InicioPrograma

BarridoZero

Pages

FOREGROUND THREAD

BACKGROUND THREAD

Inicio Programa Rescan Marcado

Page 32: Hi pig_JSDay-v2

Resumiendo principio 1 - Controla la memoria

Evitar crear objetos innecesarios.

Usar colecciones de objetos, cuando se posible.

Ser cuidadoso con los patrones de petición de memoria.

Page 33: Hi pig_JSDay-v2

Principio #2Eficiencia en la gestión de objetos

Page 34: Hi pig_JSDay-v2

var p1;p1.north = 1;p1.south = 0;

var p2;p2.south = 0;p2.north = 1;

north 1

south 0

north 1

north

south

south 0

north 1

south 0

south

north

Base Type “{}”

Type “{north}” Type “{south}”

Base Type “{}”

Type “{south, north}”Type “{north, south}”

Tipado interno y la importancia del orden

Page 35: Hi pig_JSDay-v2

No añadir propiedades de forma condicionalfunction Player(direction) {

if (direction = “NE”) {this.n = 1;this.e = 1;

}else if (direction = “ES”) {

this.e = 1;this.s = 1;

}...

}

var p1 = new Player(“NE”); // p1 type {n,e}var p2 = new Player(“ES”); // p2 type {e,s}

function Player(north,east,south,west) {this.n = north;this.e = east;this.s = south;this.w = west;

}

var p1 = new Player(1,1,0,0);//p1 type {n,e,s,w}var p2 = new Player(0,0,1,1);//p2 type {n,e,s,w}

p1.type != p2.type p1.type == p2.type

Page 36: Hi pig_JSDay-v2

No inicializar en el prototipo

function Player(name) {...

};

Player.prototype.n = null;Player.prototype.e = null;Player.prototype.s = null;Player.prototype.w = null;

var p1 = new Player("Jodi"); //p1 type{}var p2 = new Player("Mia"); //p2 type{}var p3 = new Player("Jodi"); //p3 type{}

p1.n = 1; //p1 type {n}p2.e = 1; //p2 type {e}

function Player(name) {this.n = null;this.e = null;this.s = null;this.w = null;...

}

var p1 = new Player("Jodi"); //p1 type{n,e,s,w}var p2 = new Player("Mia"); //p2 type{n,e,s,w}var p3 = new Player("Jodi"); //p3 type{n,e,s,w}

p1.n = 1; //p1 type{n,e,s,w}p2.e = 1; //p2 type{n,e,s,w}

p1.type != p2.type != p3.type p1.type == p2.type == p3.type

Page 37: Hi pig_JSDay-v2

Getters y Setters

function Player(north, east, south, west) {Object.defineProperty(this, "n", {

get : function() { return nVal; }, set : function(value) { nVal=value; }, enumerable: true, configurable: true

});Object.defineProperty(this, "e", {

get : function() { return eVal; }, set : function(value) { eVal=value; }, enumerable: true, configurable: true

});...

}var p = new Player(1,1,0,0);var n = p.n;p.n = 0;...

function Player(north, east, south, west) {this.n = north;this.e = east;this.s = south;this.w = west;...

}

var p = new Player(1,1,0,0);var n = p.n;p.n = 0;...

LENTO RÁPIDO

Page 38: Hi pig_JSDay-v2

Corrigiendo el código - Lo que tenemos (I)function Player(n, e, s, w) {

Object.defineProperty(this, "north", {

get: function () { return nVal; },

set: function (value) { nVal = value; },

enumerable: true,

configurable: true

});

Object.defineProperty(this, "east", {

get: function () { return eVal; },

set: function (value) { eVal = value; },

enumerable: true,

configurable: true

});

...

Page 39: Hi pig_JSDay-v2

Corrigiendo el código - Lo que tenemos (II)...

Object.defineProperty(this, "south", {

get: function () { return sVal; },

set: function (value) { sVal = value; },

enumerable: true,

configurable: true

});

Object.defineProperty(this, "west", {

get: function () { return wVal; },

set: function (value) { wVal = value; },

enumerable: true,

configurable: true

});

...

Page 40: Hi pig_JSDay-v2

Corrigiendo el código - Lo que tenemos (III)...

var nVal = n;

var eVal = e;

var sVal = s;

var wVal = w;

}

Page 41: Hi pig_JSDay-v2

Corrigiendo el código - Lo que deberíamos tener

function FastPlayer(n, e, s, w) {

this.north = n;

this.east = e;

this.south = s;

this.west = w;

}

Page 42: Hi pig_JSDay-v2

0 2000 4000 6000 8000 10000 12000 14000

Original

Memoria

Objetosrápidos

Original Tiempo: 13001 milisegundos

Cerditos rotados: 11814

Ahorro de Memoria Tiempo: 4248 milisegundos

Cerditos rotados: 11814

Objetos rápidos Tiempo: 3020 milisegundos

Cerditos rotados: 11814

Resultados

Page 43: Hi pig_JSDay-v2

Resumiendo principio 2 - Eficiencia en la gestión de objetos

No añadir propiedades de forma condicional.

Añadir propiedades en el constructor.

Getters i Setters sólo cuando sean necesarios

Page 44: Hi pig_JSDay-v2

Principio #3Rapidez Matemática

Page 45: Hi pig_JSDay-v2

Números en JavaScript

31 bits

Entero 31-bit (tipado = “smi”) 1 bit

1

31 bits

Dirección de memoria1 bit

032 bits

32 bits

FloatsEnteros de 32-bit

PILA (STACK) MONTÓN (HEAP)

Longitud fija, acceso rápido Longitud variable, acceso lento

Boxed

Todos los números en JS son flotantes:• Muy flexible• Muy poco eficientes

Page 46: Hi pig_JSDay-v2

Usando numeros de 31 bits

STACK

0x00000003north:

0x005e4148east:

0x005e4160south:

String

“east”

Number

0.1

Number

0x1

0x005e4170west:

HEAP

Posición de memoria0…01001000

LENTO

LENTO

LENTO

var north = 1;

var east = "east";var south = 0.1;var west = 0x1;

function Pig(north, south, east, west) {

...}

var p = new Pig(north,south,east,west);

Representación de un 1= 0…00000011

Page 47: Hi pig_JSDay-v2

Formas de usar un entero (smi)

1) Declarando enteros

var north = 1;

• Internamente sabe que es un entero.

• Mientras no forcemos una conversión se guardará en el stack.

• Esta es una de las mejoras de los motores JS de navegadores modernos

Page 48: Hi pig_JSDay-v2

Formas de usar un entero (smi)

1) Declarando enteros

2) Operaciones con enteros

var a = 5;var b = 2;r = ((a + b) / 2) |0 ;

• Añadir |0 es una forma de especificar el tipo en el cálculo

Page 49: Hi pig_JSDay-v2

Formas de usar un entero (smi)

3) Especialización de los cálculos

function Distance(p1, p2) {var dx = p1.x - p2.x;var dy = p1.y - p2.y;var d2 = dx * dx + dy * dy;return Math.sqrt(d2);

}

var point1 = {x:10, y:10};var point2 = {x:20, y:20};var point3 = {x:1.5, y:1.5}; var point4 = {x:0x0AB, y:0xBC};

Distance(point1, point3);Distance(point2, point4);

Page 50: Hi pig_JSDay-v2

Formas de usar un entero (smi)

3) Especialización de los cálculos

function DistanceFloat(p1, p2) {var dx = p1.x - p2.x;var dy = p1.y - p2.y;var d2 = dx * dx + dy * dy;return Math.sqrt(d2);

}

var point1 = {x:10, y:10};var point2 = {x:20, y:20};var point3 = {x:1.5, y:1.5}; var point4 = {x:0x0AB, y:0xBC};

DistanceInt(point1, point2);

DistanceFloat(point3, point4);

function DistanceInt(p1,p2) {var dx = p1.x - p2.x;var dy = p1.y - p2.y;var d2 = dx * dx + dy * dy;return (Math.sqrt(d2) | 0);

}

Page 51: Hi pig_JSDay-v2

• Declarando enteros

• Operaciones con enteros

• Especialización de los cálculos

Resumiendo principio 3 - Rapidez matemática

Page 52: Hi pig_JSDay-v2

Principio #4Domina los arrays

Page 53: Hi pig_JSDay-v2

Arrays pre-reservados

var a = new Array(100);for (var i = 0; i < 100; i++) {a[i] = i + 2;

}

var a = new Array();for (var i = 0; i < 100; i++) {a.push(i + 2);

}

0 ?

?+1 ??

…0 100

LENTO RÁPIDO

Page 54: Hi pig_JSDay-v2

Recorrer arrays eficientemente

var a = new Array(100);var total = 0;

for (var item in a) {total += item;

};

a.forEach(function(item){total += item;

});

for (var i = 0; i < a.length; i++) { total += a[i];

}

var a = new Array(100);var total = 0;cachedLength = a.length;for (var i = 0; i < cachedLength; i++) { total += a[i];

}

LENTO

RÁPIDO

Comparativa: http://jsperf.com/for-vs-foreach/5

SUPER RÁPIDO

var a = new Array(100);var cachedLength = a.length-1;do {

total += a[i]);} while (cachedLength--);

Page 55: Hi pig_JSDay-v2

Representación de un array en memoria

var a = new Array();

a[0] = 1;

a[1] = 2.3;

a[2] = "str";

Type: Int Array

Type: Int Array 1

Type: Float Array 1 2.3

Type: Var Array 1 2.3 “str”

Page 56: Hi pig_JSDay-v2

Si mezclamos... “avisemos”

LENTO RÁPIDO

var a = new Array(100000);

for (var i = 0; i < a.length; i++) {a[i] = i;

}...//operations on the array...a[99] = “str”;

var a = new Array(100000);

a[0] = “hint”;

for (var i = 0; i < a.length; i++) {a[i] = i;

}...//operations on the array...a[99] = “str”;

Page 57: Hi pig_JSDay-v2

Arrays tipados explícitamente

var value = 5;

var a = new Array(100);a[0] = value; // 5 - taggeda[1] = value / 2; // 2.5 - boxeda[2] = "text"; // "text" – var array

var value = 5;

var a = new Float64Array(100);a[0] = value; // 5 - no tagging requireda[1] = value / 2; // 2.5 - no boxing requireda[2] = "text"; // 0

var a = new Int32Array(100);a[0] = value; // 5 - no tagging requireda[1] = value / 2; // 2 - no tagging requireda[2] = "text"; // 0

LENTO RÁPIDO

Page 58: Hi pig_JSDay-v2

Arrays tipados explícitamente

Type Size Description Equivalent C type

Int8Array 1 8-bit twos complement signed integer signed char

Uint8Array 1 8-bit unsigned integer unsigned char

Uint8ClampedArray 1 8-bit unsigned integer unsigned char

Int16Array 2 16-bit twos complement signed integer short

Uint16Array 2 16-bit unsigned integer unsigned short

Int32Array 4 32-bit twos complement signed integer int

Uint32Array 4 32-bit unsigned integer unsigned int

Float32Array 4 32-bit IEEE floating point number float

Float64Array 8 64-bit IEEE floating point number double

Page 59: Hi pig_JSDay-v2

Mantener la “densidad” del array

var a = new Array(1000); //type int...for (var i = 0; i < boardSize; i++) {

matrix[i] = [1,1,0,0];}

//operating on the array...delete matrix[23];...//operating on the array

var a = new Array(1000); //type int...for (var i = 0; i < boardSize; i++) {

matrix[i] = [1,1,0,0];}

//operating on the array...matrix[23] = 0;...//operating on the array

LENTO RÁPIDO

Page 60: Hi pig_JSDay-v2

Resumiendo principio 4 - Domina los arrays

• Pre reserva de arrays

• Recorrer arrays eficientemente

• Tipos internos y copia de arrays

• Si mezclamos avisamos

• Arrays tipados explícitamente

• Mantener la “densidad”

Page 61: Hi pig_JSDay-v2

Principio #5Obtener objetos del DOM

Page 62: Hi pig_JSDay-v2

Llamadas al DOMLlamar al DOM es una operación costosa, y suele ser el cuello de botella más grande de las app web.

document.getElementById('here').innerHTML += 'a';

function innerHTMLLoop() {for (var count = 0; count < 15000; count++) {

}}

function innerHTMLLoop2() {var content = '';for (var count = 0; count < 15000; count++) {

content += 'a';}document.getElementById('here').innerHTML += content;

}

150 veces más rápido

Page 63: Hi pig_JSDay-v2

Cachea elementos completos

1) Evita estar constantemente accediendo al DOM: mejor una llamada y cachear el elemento entero

JavaScript

DOM

...//for each rotationdocument.body.game.getElementById(elID).classList.remove(oldClass)document.body.game.getElementById(elID).classList.add(newClass)...

var element = document.getElementById(elID).classList;

//for each rotationelement.remove(oldClass)element.add(newClass)...

JavaScript

DOM

Page 64: Hi pig_JSDay-v2

this.boardSize = document.getElementById("benchmarkBox").value;

string string

this.boardSize = parseInt(document.getElementById("benchmarkBox").value);

int

El DOM devuelve siempre un string.

2) Cuidado con las conversiones: Los valores DOM por defecto son String! ¿¿¿Os había contado ya por qué no se debe comparar la velocidad con el tocino???

for (var i = 0; i < this.boardSize; i++) { for (var j = 0; j < this.boardSize; j++) {

...}

}

Page 65: Hi pig_JSDay-v2

NOIf Type(x) == String && Type(y) == Number

Como compara JS la velocidad y el tocino

X == y?

Type(x) == Type(y)

SI

NO

Type(x) == Undefined

SI

Type(x) == Null NO Type(x) == NumberNOType(x) == String

NO NO …

true

X == null && y==undefined

SI

X == undefined && y==null

NO NOType (x) == number &&

Type (y) == stringNO …

Page 66: Hi pig_JSDay-v2

El algoritmo de la comparacion de igualdad “abstracta”:Type(x) == Type(y)

X == y?

true

False

Si No

Type(x) == Undefined

Type(x) == Null

Si

No

Type(x) == Number

No

Si

Type(x) == String

Si

No

Type(x) == Boolean

X es el mismo objeto que y

X == y

Si

No

x == true &&x == true

X == NaN

Y == NaN

X==y

X == +0 && y == -0

X == -0 && y == +0

X == null && y==undefined

X == undefined && y==null

Type (x) == number && Type (y) == string

23,1071

If Type(x) == Boolean

Type(y) == Boolean

(Type(x) == String || Type(x) == Number) &&

Type(y) == Object

(Type(y) == String || Type(y) == Number) &&

Type(x) == Object

x == ToNumber(y)

ToNumber(x) == y.

ToNumber(x) == y.

x == ToNumber(y)

x == ToPrimitive(y)

x == ToPrimitive(y)

Page 67: Hi pig_JSDay-v2

Más rápido que tu ojo...

setInterval(animate, 0);

setTimeout(animate, 0);

requestAnimationFrame(animate);

setInterval(animate, 1000 / 60);setTimeout(animate, 1000 / 60);

Page 68: Hi pig_JSDay-v2

Los últimos cambios

requestAnimationFrame(animate);

setTimeout(animate, 0);

Page 69: Hi pig_JSDay-v2

Los últimos cambios

var x = $(elID);

if (x.hasClass('imageClass2')){var newClass = 'imageClass1';var oldClass = 'imageClass2';

} else if (x.hasClass('imageClass3')){var newClass = 'imageClass1';var oldClass = 'imageClass3';

} /** … **/

x.removeClass(oldClass).addClass(newClass);

if ($(elID).hasClass('imageClass2')){$(elID).removeClass('imageClass2');$(elID).addClass('imageClass1');

} else if ($(elID).hasClass('imageClass3')){$(elID).removeClass('imageClass3');$(elID).addClass('imageClass1');

} /** … **/

Page 70: Hi pig_JSDay-v2
Page 71: Hi pig_JSDay-v2

Resultados

requestAnimationFrame(animate);setTimeout(animate, 0);

El uso de la CPU se reduce un 10%

Page 72: Hi pig_JSDay-v2

ResultadosEl uso de la CPU se reduce un 10%

Page 73: Hi pig_JSDay-v2

Resultados

0 10000 20000 30000 40000 50000 60000

Original

Memoria

Objetos rápidos

Mat, Arrays y DOM

11814 Iteraciones (tiempos)

IE Chrome Firefox

Page 74: Hi pig_JSDay-v2

1) Cachea los elementos enteros en JS con una llamada, en lugar de hacer varias llamadas para acceder a sus nodos hijos.

2) Cuidado con las conversiones: Los valores DOM por defecto son String!

3) No dibujes más rápido de lo que usuario pueda apreciar: sobrecarga el sistema inutilmente

Resumiendo principio 5 - Obtener objetos del DOM

Page 75: Hi pig_JSDay-v2

1) Buena experiencia de usuario2) Larga duración en la vida de la bateria

Problema resuelto!

Page 76: Hi pig_JSDay-v2

• Principio nº1: Controla la memoria• Principio nº2: Eficiencia en la gestión de objetos• Principio nº3: Rapidez matemática• Principio nº4: Domina los arrays• Principio nº5: Obtener objetos del DOM

En resumen...

Page 77: Hi pig_JSDay-v2

Developing High Performance Websites and Modern Apps with JavaScript Performance Toolshttp://channel9.msdn.com/Events/Build/2013/3-316

Building High-Performing JavaScript for Modern Engineshttp://channel9.msdn.com/Events/Build/2012/4-000

Developing high performance websites and modern apps with JavaScript performance tools http://channel9.msdn.com/Events/Build/2013/3-316

CHAKRA: UNDER THE HOOD http://gotocon.com/dl/goto-aar-2012/slides/SteveLucco_TheInnerWorkingsOfTheChakraJavascriptEngine.pdfhttp://wingolog.org/

Writing Fast, Memory-Efficient JavaScripthttp://coding.smashingmagazine.com/2012/11/05/writing-fast-memory-efficient-javascript/

Performance Tips for JavaScript in V8http://www.html5rocks.com/en/tutorials/speed/v8/

Explaining JavaScript VMs in JavaScript - Inline Caches http://mrale.ph/blog/2012/06/03/explaining-js-vms-in-js-inline-caches.html

Info, info, info...

Page 78: Hi pig_JSDay-v2

Q&A

Page 79: Hi pig_JSDay-v2

Isabel Cabezas@[email protected]

Toni Recio@[email protected]

MUCHAS GRACIAS!