Reactividad en Angular, React y VueJS

Javier Abadía
Javier Abadíahaving loads of fun as Lead Developer at StyleSage en StyleSage
REACTIVIDADen Angular, React yVue
@javierabadia
FASHION MEETS BIG DATA
2015
Reactividad en Angular, React y VueJS
Reactividad en Angular, React y VueJS
ecosistema comunidad
CLI
enrutado
orientación a
componentes
rendimiento
💩webpack 💩
Reactividad en Angular, React y VueJS
Reactividad en Angular, React y VueJS
FUNDAMENTOS
stack
queue
heap
addToCart()
product1
product2
getDiscount() {
brand: ‘Salomon’,,
name: ‘XMax’,,
price: 399.00,
}
{
brand: ‘Atomic’,,
name: ‘M110’,,
price: 325.00,
}
Las variables
calcPrice(p)
p
discount
newPrice
function getDiscount() {
return 0.20;
}
function calcPrice(p) {
var discount = getDiscount();
var newPrice = p.price *
(1 - discount);
p['finalPrice'] = newPrice;
}
function addToCart() {
var product1 = {
brand: 'Salomon',
name: 'XMax',
price: 399.00,
};
var product2 = {
brand: 'Atomic',
name: 'M110',
price: 325.00,
};
calcPrice(product1);
}
{
brand: ‘Salomon’,,
name: ‘XMax’,,
price: 399.00,
finalPrice 319,20,
}0.20
319,20
stack
queue
heap
{
brand: ‘Atomic’,,
name: ‘M110’,,
price: 325.00,
}
Las variables
function getDiscount() {
return 0.20;
}
function calcPrice(p) {
var discount = getDiscount();
var newPrice = p.price *
(1 - discount);
p['finalPrice'] = newPrice;
}
function addToCart() {
var product1 = {
brand: 'Salomon',
name: 'XMax',
price: 399.00,
};
var product2 = {
brand: 'Atomic',
name: 'M110',
price: 325.00,
};
calcPrice(product1);
}
{
brand: ‘Salomon’,,
name: ‘XMax’,,
price: 399.00,
finalPrice 319,20,
}
stack
queue
heap
El bucle de eventos o “los turnos”
task1 task2 (onclick) task3 (xhr)
fn1.1()
fn1.2()
fn1.3()
fn2.1()
fn2.2()
todo junto
stack
queue
heap
Reactividad en Angular, React y VueJS
¿Pero esto puede funcionar?
AngularJS
scope (MainCtrl) {
additionalDiscount: 0,
products: [
{name: 'XMax X10 2018’, … },
{name: 'Magnum’, …},
{name: 'Amphibio XII’, …},
{name: 'Vector Edge’, …},
{name: 'Fogbreaker’, …},
],
addToCart: function (product) {
alert(`added ${product.name}`);
},
}
scope (ProductCard) {
product: {name: 'XMax X10 2018’, … },
additionalDiscount: 0,
addToCart: fn(),
isDiscounted: fn(),
},
AngularJS en una slide: scopes
<div ng-controller="MainCtrl">
counter: {{counter}}
doubleCounter: {{doubleCounter}}
<button ng-click="increment()">increment</button>
</div>
app.controller('MainCtrl', function ($scope) {
$scope.counter = 0;
$scope.increment = function () {
$scope.counter += 1;
};
$scope.$watch('counter', function () {
$scope.doubleCounter = $scope.counter * 2;
});
});
$scope = {
counter: 0,
doubleCounter: 0,
...
}
AngularJS en una slide: watchers
bindings en
la plantilla
watchers
explícitos
$$watchers do { // "traverse the scopes" loop
if ((watchers = !current.$$suspended && current.$$watchers)) {
// process our watches
watchers.$$digestWatchIndex = watchers.length;
while (watchers.$$digestWatchIndex--) {
try {
watch = watchers[watchers.$$digestWatchIndex];
// Most common watches are on primitives, in which case we can short
// circuit it with === operator, only when === fails do we use .equals
if (watch) {
get = watch.get;
if ((value = get(current)) !== (last = watch.last) &&
!(watch.eq
? equals(value, last)
: (isNumberNaN(value) && isNumberNaN(last)))) {
dirty = true;
lastDirtyWatch = watch;
watch.last = watch.eq ? copy(value, null) : value;
fn = watch.fn;
fn(value, ((last === initWatchVal) ? value : last), current);
if (ttl < 5) {
logIdx = 4 - ttl;
if (!watchLog[logIdx]) watchLog[logIdx] = [];
watchLog[logIdx].push({
msg: isFunction(watch.exp) ? 'fn: ' + (watch.exp.name || watch.exp.toString()) : watch.exp,
newVal: value,
oldVal: last
});
}
} else if (watch === lastDirtyWatch) {
// If the most recently dirty watcher is now clean, short circuit since the remaining watchers
// have already been tested.
dirty = false;
break traverseScopesLoop;
}
}
} catch (e) {
$exceptionHandler(e);
}
}
}
// Insanity Warning: scope depth-first traversal
// yes, this code is a bit crazy, but it works and we have tests to prove it!
// this piece should be kept in sync with the traversal in $broadcast
// (though it differs due to having the extra check for $$suspended and does not
// check $$listenerCount)
if (!(next = ((!current.$$suspended && current.$$watchersCount && current.$$childHead) ||
(current !== target && current.$$nextSibling)))) {
while (current !== target && !(next = current.$$nextSibling)) {
current = current.$parent;
}
}
} while ((current = next));
dirty checking = ciclo de $digest / $apply
• para cada $scope
• para cada watcher en $$watchers
• evalúa la expresión (p.ej. ‘counter’)
• compara con el resultado anterior (p.ej 3 === 2)
• si es distinto, ejecuta el callback
• en caso de un binding de la plantilla, el callback cambia el valor en el DOM
• como los callbacks pueden cambiar cosas, se repite el ciclo hasta que no
haya ningún cambio
scope.$watch(interpolateFn, function interpolateFnWatchAction(value) {
node[0].nodeValue = value;
});
Reactividad en Angular, React y VueJS
¿cuándo?
• al final de cada turno
• siempre y cuando lo haya
iniciado una tarea de
Angular.js
• por ejemplo
• ng-click
• $timeout, $interval
• $http
stack
queue
heap
baz()
foo()
product1
product2
bar()
p
discount
newPrice
ng-click()
ahora!
¿y si ocurre algo fuera?
• AngularJS no se entera
• tenemos que llamar a $scope.$apply() manualmente
• p.ej.
• usando d3.js
• eventos nativos de librerías externas
• eventos que podemos recibir de otro iframe
el doble binding
• ng-model = mola
• se vinieron arriba
• en las directivas propias
• ufff
<the-counter counter='counter'></the-counter>
app.directive('theCounter', function () {
return {
scope: {
counter: '=',
},
template: `
<div>
{{counter}}
<button ng-click="dec()">dec</button>
</div>`,
link(scope, el, attr) {
scope.dec = function() {
scope.counter -= 1;
};
},
};
});
<input type="text" ng-model="passportId" />
Cómo ayudar a AngularJS
• usar pocos watchers
• y si es posible, que cambien pocas cosas?
• no poner muchos bindings
• usar bind once (p.ej {{::brand}})
• ng-repeat track by
• virtualizar listas
• $watch / $watch(…,…,true) / $watchGroup() / $watchCollection()
Los problemas de AngularJS
• la falta de orientación a componentes
• herencia de scopes
• la falta de un mecanismo de gestión de estado
• no tan importantes (EMHO)
• rendimiento con muchos bindings/watchers
• complejidad derivada del doble binding
• Angular2
React
un pasado oscuro…
React en una slide
<App />
<ProductCard />
<DiscountTag /><Price />
<ProductCard />
<DiscountTag /><Price />
render()
props
state
elements
render()
El origen de React es…
• PHP
El origen de React es…
• PHP
PHP? React?
El origen de React es…
• PHP / XHP
• reescrito a JavaScript
• convertido de servidor a cliente
$list = <ul />;
foreach ($items as $item) {
$list->appendChild(<li>{$item}</li>);
}
https://www.facebook.com/notes/facebook-engineering/xhp-a-
new-way-to-write-php/294003943919/
Como los videojuegos
• cambio el estado
• renderizo todo
• DOM LEEEEENTOOOOO
• no tiene por qué
• si se hace mal
• reflow & Paint
• ¡DOM guarda estado!
• selección
• foco
• scroll
por eso - VirtualDOM
{
type: 'button',
props: {
className: 'button button-blue',
children: {
type: 'b',
props: {
children: 'OK!'
}
}
}
}
<button class="button button-blue">
<b>OK!</b>
</button>
objetos que representan el DOM equivale a
VirtualDOMComponentes “parchear”
el DOM real
VirtualDOM
anterior
render()
diff()
¿cuándo hay que renderizar?
• tenemos que avisar a REACT
• this.setState({…})
• encola el componente (y sus hijos) para renderizar
• ¿cuándo se renderiza?
• batched updates - a veces!
¿y la reactividad dato → dato?
• Fuera del alcance de React
• O dicho de otra forma, ¿comunicación entre componentes que están
lejos?
• PubSub
• Eventos
• Redux
• Mobx
• Redux-saga
¿Cómo ayudar a React?
• no todo debe ir en this.state
• se pueden añadir propiedades al componente fuera de la ‘jurisdicción’ de React
• shouldUpdateComponent()
• datos inmutables
• virtualizar listas
• Perf.printWasted() (<16, con Fiber → browserTimeline)
Angular 2+
Para los que echan de menos Java y C#
Detección de Cambios en Angular2
• sigue usando dirty-checking
• igual que AngularJS
• solucionar los problemas de AngularJS
• las múltiples vueltas de $digest/$apply
• los cambios fuera de Angular
• además se les fue la pinza conTypeScript y otras 1000 cosas
1
2
Cómo evitar las multiples vueltas
• se eliminan los watchers de usuario
• por lo tanto, no puedo cambiar el estado en el ciclo de comprobación
1
¿Cómo detectar todos los cambios?
• el problema es cuando se ejecuta código fuera de Angular
• Angular2 lo soluciona mediante ‘zonas’
2
function doSomething() {
console.log('Async task');
}
function foo() {
bar();
setTimeout(doSomething, 2000);
baz();
}
foo();
myZoneSpec = {
beforeTask: () => { console.log('entering zone'); },
afterTask: () => { console.log('leaving zone'); },
};
function doSomething() {
console.log('Async task');
}
function foo() {
bar();
setTimeout(doSomething, 2000);
baz();
}
let myZone = zone.fork(myZoneSpec);
myZone.run(foo);
zones.js
zones.js
• ¿Es mágia?
• No… es monkey-patching de los event listener, setTimeout(),
setInterval(), xhr
• Por eso ya no es necesario usar $timeout o $interval
¿Cómo detectar todos los cambios?
• Zonas
• zones.js permite detectar todas las tareas que ‘nacen’ de una misma tarea (eso
es una zona)
• p.ej. permite hacer call-stacks de llamadas asíncronas
• p.ej. permite registrar eventos al entrar o salir de una zona (empezar a ejecutar
una tarea o finalizarla)
• Se “envuelve” todo el código de Angular en una zona
• detecta cambios cuando la cola de tareas de la zona de Angular está vacía
2
Reactividad dato → dato = RxJS
• Functional Reactie Programming
• Observables
• pipes
• streams
// config.service.ts
getConfig() {
return this.http.get('assets/config.json');
}
// in component.ts
showConfig() {
this.configService.getConfig()
.subscribe(data => this.config = {
heroesUrl: data['heroesUrl'],
textfile: data['textfile']
});
}
¿Cómo ayudar a Angular?
• ChangeDetectionStrategy.OnPush
• Track By
• RxJS
• Pure Pipes
Vue.js
el front vuelve a ser divertido
Vue.js en una slide
<template>
<div class="product-card">
<div class="description">
<div class="name">{{product.name}}</div>
<div class="brand">{{product.brand}}</div>
<div class="price--original" v-if="isDiscounted">
<price :price="product.price"/>
</div>
<div class="price">
<price :price='finalPrice'/>
</div>
<button class="nice-button" @click="addToCart(product)">Add to Cart</button>
</div>
<div class="img">
<discount-tag class="discount" :discount="product.discount"/>
<img v-if="product.img" :src="product.img" :alt="product.name">
</div>
</div>
</template>
sintaxis de las templates
parecida a Angular.js
bindings de atributos
bindings de eventos
Ficheros *.vue
<script>
</script>
<style>
</style>
<template>
</template>
Ficheros *.vue
<script>
</script>
<style>
</style>
<template>
</template>
Ficheros *.vue
javascript
template
estilos
<template>
<div class="product-card">
</div>
</template>
<script>
import Price from './Price';
import DiscountTag from './DiscountTag';
export default {
props: {
product: Object,
overallDiscount: Number,
},
computed: {
…
finalPrice() {
return this.product.price * (1 - this.effectiveDiscount);
},
…
},
methods: {
addToCart(product) {
alert(`added ${product.name}`);
}
},
components: {
Price,
DiscountTag,
},
};
</script>
<style lang="less" rel="stylesheet/less">
…
</style>
las templates se “compilan”
a una función render()
Función render()
<template>
<div class="discount-tag" v-if="discount !== 0">{{discount * 100}}%</div>
</template>
<script>
export default {
props: {
discount: Number,
},
};
</script>
<script>
export default {
functional: true,
render: function (h, context) {
const discount = context.props.discount;
return discount ? h(
'div',
{'class': 'discount-tag ' + context.data.staticClass},
(context.props.discount * 100) + '%',
) : undefined;
},
props: {
discount: Number,
},
};
</script>
<script>
export default {
functional: true,
render: function (h, context) {
const discount = context.props.discount;
return discount ? (
<div class={'discount-tag'} {...context.data}>
{(context.props.discount * 100) + '%'}
</div>
) : undefined;
},
props: {
discount: Number,
},
};
</script>
VirtualDOM
es lo mismo
VirtualDOMComponentes “parchear”
el DOM real
VirtualDOM
anterior
render()
diff()
¿cuándo se llama a render() de
cada componente?
¿como sabe cuándo hay que renderizar?
• Angular.js - dirty-checking
• al final de cada turno, evalúa todos los watchers
y actualiza los nodos correspondientes
• React.js - como los videojuegos
• cuando se llama a setState() de un componente
• re-renderiza todos sus hijos
• Vue.js
• cuando cambia un dato “reactivo”
• re-renderiza los componentes que dependen de el dato
¿que datos son reactivos?
• componente
• data (= estado)
• props
• propiedades computadas
Vue.js
cuando cambia un dato “reactivo”
re-renderiza los componentes
que dependen de el dato
Propiedades Computadas
computed: {
finalPrice() {
return this.product.price * (1 - this.effectiveDiscount);
},
effectiveDiscount() {
return this.product.discount + this.overallDiscount;
},
},
<template>
<div class="product-card">
<span>{{finalPrice}}</span>
</div>
</template>
¿cómo sabe que cambia?
• Vue.js reemplaza los “datos” por propiedades ES5 con getter y setter
Object.defineProperty()
Vue.js
cuando cambia un dato “reactivo”
re-renderiza los componentes
que dependen de el dato
let _p1 = 23;
const state = {
get p1() {
console.log('getting p1’);
return _p1;
},
set p1(value) {
console.log('setting p1=', value);
_p1 = value;
}
}
Reactividad en Angular, React y VueJS
¿cómo sabe qué componentes
dependen del dato?
Vue.js
cuando cambia un dato “reactivo”
re-renderiza los componentes
que dependen de el dato
https://vuejs.org/v2/guide/reactivity.html
getters y setters en vue.js
• los setters
• cambian el dato
• avisa a quien dependa de mi de que
el dato ha cambiado
• los getters
• devuelven el dato
• actualizan la lista de dependencias
para poder avisar
¿Cómo ayudar a Vue.js?
• no necesita mucha ayuda
• mutar objetos, en lugar de
reemplazarlos
• uso ‘extensivo’ de computed
properties
• tener en cuenta los “change
detection caveats”
https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats
RESUMIENDO
Y todo esto… para que sirve?
• un factor más para elegir el framework que más se adapta a
nuestro estilo/proyecto/gusto
• para usar los frameworks mejor
• go with the flow
• evitar ‘trampas’
• optimizar rendimiento
• para migrar de un framework a otro sobre la marcha
• ¿una app donde conviven dos (o más) frameworks?
Reactividad en Angular, React y VueJS
GRACIAS
GRACIAS@javierabadia
Referencias
• MDN Event Loop: https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop
• EvanYou, Reactivity in Frontend JavaScript Frameworks
https://www.dotconferences.com/2016/12/evan-you-reactivity-in-frontend-javascript-frameworks
• Change Detection in JS Frameworks: http://teropa.info/blog/2015/03/02/change-and-its-detection-in-
javascript-frameworks.html
Referencias - Angular
• Improve Angular Performance: https://www.alexkras.com/11-tips-to-improve-angularjs-performance/#watchers
• Angular Code Overview: https://angular.io/guide/architecture
• Change Detection in Angular 2: https://vsavkin.com/change-detection-in-angular-2-4f216b855d4c,
https://codewithstyle.info/change-detection-angular-versus-angularjs/,
https://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html
• Zones: https://blog.thoughtram.io/angular/2016/01/22/understanding-zones.html,
https://www.joshmorony.com/understanding-zones-and-change-detection-in-ionic-2-angular-2/, https://angular-2-training-
book.rangle.io/handout/zones/
• Zone Primer: https://docs.google.com/document/d/1F5Ug0jcrm031vhSMJEOgp1l-Is-Vf0UCNDY-
LsQtAIY/edit#heading=h.s6p06rpu4c13
• RxJS: https://auth0.com/blog/making-use-of-rxjs-angular/, https://medium.com/google-developer-experts/angular-
introduction-to-reactive-extensions-rxjs-a86a7430a61f, https://blog.angular-university.io/functional-reactive-programming-
for-angular-2-developers-rxjs-and-observables/, https://stackoverflow.com/questions/37364973/angular-promise-vs-
observable, https://alligator.io/vuejs/using-rxjs/
• Angular2 performance: https://netbasal.com/optimizing-the-performance-of-your-angular-application-f222f1c16354
• Observables: https://angular-2-training-book.rangle.io/handout/observables/
• State management: https://angular-2-training-book.rangle.io/handout/state-management/
Referencias - React
• XHP: https://www.facebook.com/notes/facebook-engineering/xhp-a-new-way-to-write-php/294003943919/
• From XHP to React: https://reactjs.org/blog/2016/09/28/our-first-50000-stars.html
• History of React: https://thenewstack.io/javascripts-history-and-how-it-led-to-reactjs/
• React Codebase Overview: https://reactjs.org/docs/codebase-overview.html
• VirtualDOM and internals: https://reactjs.org/docs/faq-internals.html, https://reactjs.org/docs/rendering-
elements.html, https://reactjs.org/blog/2015/12/18/react-components-elements-and-instances.html
• Cristopher Chedeau (Facebook), React’s Architecture
https://code.facebook.com/videos/1507312032855537/oscon-2014-react-s-architecture/
• How to communicate between ReactJS components: https://www.ctheu.com/2015/02/12/how-to-communicate-
between-react-components/, https://anthonymineo.com/communication-between-independent-components-
in-react-using-pubsubjs/
• React Props vs State: https://github.com/uberVU/react-guide/blob/master/props-vs-state.md,
http://lucybain.com/blog/2016/react-state-vs-pros/
• React State and Lifecycle: https://reactjs.org/docs/state-and-lifecycle.html
• Optimizing React: https://reactjs.org/docs/optimizing-performance.html,
https://marmelab.com/blog/2017/02/06/react-is-slow-react-is-fast.html
• React + Redux: https://stackoverflow.com/questions/40386128/how-does-a-redux-connected-component-
know-when-to-re-render
Referencias - VueJS
• Vue Code Overview:
https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md
• Vue a better React: https://mattcampbell.net/slides/vue/#0
• Vue.js Reactivity: https://vuejs.org/v2/guide/reactivity.html,
https://vuejsdevelopers.com/2017/03/05/vue-js-reactivity/
• Change Detection Caveats:
https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats
1 de 70

Recomendados

[2D4]Python에서의 동시성_병렬성 por
[2D4]Python에서의 동시성_병렬성[2D4]Python에서의 동시성_병렬성
[2D4]Python에서의 동시성_병렬성NAVER D2
30.5K vistas146 diapositivas
Writing a fast HTTP parser por
Writing a fast HTTP parserWriting a fast HTTP parser
Writing a fast HTTP parserfukamachi
7.3K vistas51 diapositivas
Refactoring tutorial por
Refactoring tutorialRefactoring tutorial
Refactoring tutorialBingu Shim
2K vistas101 diapositivas
Arrays em java por
Arrays em javaArrays em java
Arrays em javaPortal_do_Estudante_Java
1.4K vistas19 diapositivas
채팅서버의 부하 분산 사례 por
채팅서버의 부하 분산 사례채팅서버의 부하 분산 사례
채팅서버의 부하 분산 사례John Kim
9.6K vistas31 diapositivas
Padrão Adapter por
Padrão AdapterPadrão Adapter
Padrão AdapterEduardo Mendes
1.3K vistas24 diapositivas

Más contenido relacionado

La actualidad más candente

人工智慧不是魔法,是數學 por
人工智慧不是魔法,是數學人工智慧不是魔法,是數學
人工智慧不是魔法,是數學Yen-lung Tsai
4.3K vistas138 diapositivas
Tcpdump hunter por
Tcpdump hunterTcpdump hunter
Tcpdump hunterAndrew McNicol
4.9K vistas29 diapositivas
127 Ch 2: Stack overflows on Linux por
127 Ch 2: Stack overflows on Linux127 Ch 2: Stack overflows on Linux
127 Ch 2: Stack overflows on LinuxSam Bowne
190 vistas44 diapositivas
From object oriented to functional domain modeling por
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modelingMario Fusco
15.3K vistas60 diapositivas
Google mock training por
Google mock trainingGoogle mock training
Google mock trainingThierry Gayet
1.1K vistas74 diapositivas
Rodando uma API Com Django Rest Framework no Google Cloud por
Rodando uma API Com Django Rest Framework  no Google CloudRodando uma API Com Django Rest Framework  no Google Cloud
Rodando uma API Com Django Rest Framework no Google CloudAlvaro Viebrantz
589 vistas66 diapositivas

La actualidad más candente(20)

人工智慧不是魔法,是數學 por Yen-lung Tsai
人工智慧不是魔法,是數學人工智慧不是魔法,是數學
人工智慧不是魔法,是數學
Yen-lung Tsai4.3K vistas
127 Ch 2: Stack overflows on Linux por Sam Bowne
127 Ch 2: Stack overflows on Linux127 Ch 2: Stack overflows on Linux
127 Ch 2: Stack overflows on Linux
Sam Bowne190 vistas
From object oriented to functional domain modeling por Mario Fusco
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
Mario Fusco15.3K vistas
Google mock training por Thierry Gayet
Google mock trainingGoogle mock training
Google mock training
Thierry Gayet1.1K vistas
Rodando uma API Com Django Rest Framework no Google Cloud por Alvaro Viebrantz
Rodando uma API Com Django Rest Framework  no Google CloudRodando uma API Com Django Rest Framework  no Google Cloud
Rodando uma API Com Django Rest Framework no Google Cloud
Alvaro Viebrantz589 vistas
[MGDC] 리눅스 게임 서버 성능 분석하기 - 아이펀팩토리 김진욱 CTO por iFunFactory Inc.
[MGDC] 리눅스 게임 서버 성능 분석하기 - 아이펀팩토리 김진욱 CTO[MGDC] 리눅스 게임 서버 성능 분석하기 - 아이펀팩토리 김진욱 CTO
[MGDC] 리눅스 게임 서버 성능 분석하기 - 아이펀팩토리 김진욱 CTO
iFunFactory Inc.1.6K vistas
Working Effectively with Legacy Code por slicklash
Working Effectively with Legacy CodeWorking Effectively with Legacy Code
Working Effectively with Legacy Code
slicklash687 vistas
FMK2017 - Eine Bilddatenbank mit FileMaker erstellen by Karsten Risseeuw por Verein FM Konferenz
FMK2017 - Eine Bilddatenbank mit FileMaker erstellen by Karsten RisseeuwFMK2017 - Eine Bilddatenbank mit FileMaker erstellen by Karsten Risseeuw
FMK2017 - Eine Bilddatenbank mit FileMaker erstellen by Karsten Risseeuw
Verein FM Konferenz921 vistas
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019 por min woog kim
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
min woog kim3.2K vistas
CNIT 127 Ch 8: Windows overflows (Part 1) por Sam Bowne
CNIT 127 Ch 8: Windows overflows (Part 1)CNIT 127 Ch 8: Windows overflows (Part 1)
CNIT 127 Ch 8: Windows overflows (Part 1)
Sam Bowne197 vistas
ScreenPlay Design Patterns for QA Automation por COMAQA.BY
ScreenPlay Design Patterns for QA AutomationScreenPlay Design Patterns for QA Automation
ScreenPlay Design Patterns for QA Automation
COMAQA.BY 3.7K vistas
Ride the database in JUnit tests with Database Rider por Mikalai Alimenkou
Ride the database in JUnit tests with Database RiderRide the database in JUnit tests with Database Rider
Ride the database in JUnit tests with Database Rider
Mikalai Alimenkou2.3K vistas
Introduction to rest.li por Joe Betz
Introduction to rest.liIntroduction to rest.li
Introduction to rest.li
Joe Betz30.3K vistas
Functional Design Patterns (DevTernity 2018) por Scott Wlaschin
Functional Design Patterns (DevTernity 2018)Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)
Scott Wlaschin5.5K vistas

Similar a Reactividad en Angular, React y VueJS

JavaScript no es Vietnam por
JavaScript no es VietnamJavaScript no es Vietnam
JavaScript no es VietnamAlex Casquete
878 vistas23 diapositivas
Curso AngularJS - 7. temas avanzados por
Curso AngularJS - 7. temas avanzadosCurso AngularJS - 7. temas avanzados
Curso AngularJS - 7. temas avanzadosÁlvaro Alonso González
2K vistas17 diapositivas
Introducción a la Progamación en Javascript. Classe 2 por
Introducción a la Progamación en Javascript. Classe 2Introducción a la Progamación en Javascript. Classe 2
Introducción a la Progamación en Javascript. Classe 2xjordi
317 vistas21 diapositivas
Dart como alternativa a TypeScript (Codemotion 2016) por
Dart como alternativa a TypeScript (Codemotion 2016)Dart como alternativa a TypeScript (Codemotion 2016)
Dart como alternativa a TypeScript (Codemotion 2016)Rafael Bermúdez Míguez
354 vistas41 diapositivas
Parte II. Notas Rapidas (sticky notes) App W8: MVVM y SQLite. por
Parte II. Notas Rapidas (sticky notes) App W8: MVVM y SQLite.Parte II. Notas Rapidas (sticky notes) App W8: MVVM y SQLite.
Parte II. Notas Rapidas (sticky notes) App W8: MVVM y SQLite.Juan Manuel
1.2K vistas8 diapositivas
React por
ReactReact
Reactjlpiedrahita
629 vistas66 diapositivas

Similar a Reactividad en Angular, React y VueJS(20)

JavaScript no es Vietnam por Alex Casquete
JavaScript no es VietnamJavaScript no es Vietnam
JavaScript no es Vietnam
Alex Casquete878 vistas
Introducción a la Progamación en Javascript. Classe 2 por xjordi
Introducción a la Progamación en Javascript. Classe 2Introducción a la Progamación en Javascript. Classe 2
Introducción a la Progamación en Javascript. Classe 2
xjordi317 vistas
Parte II. Notas Rapidas (sticky notes) App W8: MVVM y SQLite. por Juan Manuel
Parte II. Notas Rapidas (sticky notes) App W8: MVVM y SQLite.Parte II. Notas Rapidas (sticky notes) App W8: MVVM y SQLite.
Parte II. Notas Rapidas (sticky notes) App W8: MVVM y SQLite.
Juan Manuel1.2K vistas
HTML Tour - Programación de Videojuegos HTML5 por Plain Concepts
HTML Tour - Programación de Videojuegos HTML5HTML Tour - Programación de Videojuegos HTML5
HTML Tour - Programación de Videojuegos HTML5
Plain Concepts1.3K vistas
PARADIGMAS FP Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA por Víctor Bolinches
PARADIGMAS FP  Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONAPARADIGMAS FP  Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
PARADIGMAS FP Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
Víctor Bolinches161 vistas
Introducción al desarrollo Web: Frontend con Angular 6 por Gabriela Bosetti
Introducción al desarrollo Web: Frontend con Angular 6Introducción al desarrollo Web: Frontend con Angular 6
Introducción al desarrollo Web: Frontend con Angular 6
Gabriela Bosetti871 vistas
Arduino: Reporte de diseño controlador acuario con Arduino por SANTIAGO PABLO ALBERTO
Arduino: Reporte de diseño controlador acuario con ArduinoArduino: Reporte de diseño controlador acuario con Arduino
Arduino: Reporte de diseño controlador acuario con Arduino
Curso Swift por Platzi
Curso SwiftCurso Swift
Curso Swift
Platzi2.6K vistas
Silex, desarrollo web ágil y profesional con PHP por Javier Eguiluz
Silex, desarrollo web ágil y profesional con PHPSilex, desarrollo web ágil y profesional con PHP
Silex, desarrollo web ágil y profesional con PHP
Javier Eguiluz15.1K vistas
7090112 Clase Transact Sql Server por Corfapo
7090112 Clase Transact Sql Server7090112 Clase Transact Sql Server
7090112 Clase Transact Sql Server
Corfapo543 vistas
Curva de daño de un transformador c++ por Marco Jiménez
Curva de daño de un transformador c++Curva de daño de un transformador c++
Curva de daño de un transformador c++
Marco Jiménez1.2K vistas

Más de Javier Abadía

Python Asíncrono - Async Python por
Python Asíncrono - Async PythonPython Asíncrono - Async Python
Python Asíncrono - Async PythonJavier Abadía
226 vistas81 diapositivas
Extendiendo Django: Cómo Escribir Tu Propio Backend de Base de Datos - Exasol por
Extendiendo Django: Cómo Escribir Tu Propio Backend de Base de Datos - ExasolExtendiendo Django: Cómo Escribir Tu Propio Backend de Base de Datos - Exasol
Extendiendo Django: Cómo Escribir Tu Propio Backend de Base de Datos - ExasolJavier Abadía
822 vistas52 diapositivas
UX/UI para Desarrolladores por
UX/UI para DesarrolladoresUX/UI para Desarrolladores
UX/UI para DesarrolladoresJavier Abadía
367 vistas118 diapositivas
Las reglas que hay que romper para que tu equipo de desarrollo sea el más RÁPIDO por
Las reglas que hay que romper para que tu equipo de desarrollo sea el más RÁPIDOLas reglas que hay que romper para que tu equipo de desarrollo sea el más RÁPIDO
Las reglas que hay que romper para que tu equipo de desarrollo sea el más RÁPIDOJavier Abadía
415 vistas63 diapositivas
Retos de Programación en Python por
Retos de Programación en PythonRetos de Programación en Python
Retos de Programación en PythonJavier Abadía
1.2K vistas44 diapositivas
Django + Vue, JavaScript de 3ª generación para modernizar Django por
Django + Vue, JavaScript de 3ª generación para modernizar DjangoDjango + Vue, JavaScript de 3ª generación para modernizar Django
Django + Vue, JavaScript de 3ª generación para modernizar DjangoJavier Abadía
4.6K vistas40 diapositivas

Más de Javier Abadía(12)

Python Asíncrono - Async Python por Javier Abadía
Python Asíncrono - Async PythonPython Asíncrono - Async Python
Python Asíncrono - Async Python
Javier Abadía226 vistas
Extendiendo Django: Cómo Escribir Tu Propio Backend de Base de Datos - Exasol por Javier Abadía
Extendiendo Django: Cómo Escribir Tu Propio Backend de Base de Datos - ExasolExtendiendo Django: Cómo Escribir Tu Propio Backend de Base de Datos - Exasol
Extendiendo Django: Cómo Escribir Tu Propio Backend de Base de Datos - Exasol
Javier Abadía822 vistas
Las reglas que hay que romper para que tu equipo de desarrollo sea el más RÁPIDO por Javier Abadía
Las reglas que hay que romper para que tu equipo de desarrollo sea el más RÁPIDOLas reglas que hay que romper para que tu equipo de desarrollo sea el más RÁPIDO
Las reglas que hay que romper para que tu equipo de desarrollo sea el más RÁPIDO
Javier Abadía415 vistas
Retos de Programación en Python por Javier Abadía
Retos de Programación en PythonRetos de Programación en Python
Retos de Programación en Python
Javier Abadía1.2K vistas
Django + Vue, JavaScript de 3ª generación para modernizar Django por Javier Abadía
Django + Vue, JavaScript de 3ª generación para modernizar DjangoDjango + Vue, JavaScript de 3ª generación para modernizar Django
Django + Vue, JavaScript de 3ª generación para modernizar Django
Javier Abadía4.6K vistas
Vue.js + Django - configuración para desarrollo con webpack y HMR por Javier Abadía
Vue.js + Django - configuración para desarrollo con webpack y HMRVue.js + Django - configuración para desarrollo con webpack y HMR
Vue.js + Django - configuración para desarrollo con webpack y HMR
Javier Abadía3.2K vistas
Anatomía de un Bot para Resultados Electorales por Javier Abadía
Anatomía de un Bot para Resultados ElectoralesAnatomía de un Bot para Resultados Electorales
Anatomía de un Bot para Resultados Electorales
Javier Abadía469 vistas
Deep learning image classification aplicado al mundo de la moda por Javier Abadía
Deep learning image classification aplicado al mundo de la modaDeep learning image classification aplicado al mundo de la moda
Deep learning image classification aplicado al mundo de la moda
Javier Abadía1.3K vistas
Análisis de colores: cómo analizar tendencias de moda automáticamente por Javier Abadía
 Análisis de colores: cómo analizar tendencias de moda automáticamente Análisis de colores: cómo analizar tendencias de moda automáticamente
Análisis de colores: cómo analizar tendencias de moda automáticamente
Javier Abadía1.4K vistas
Codemotion 2016 - d3.js un taller divertido y difícil por Javier Abadía
Codemotion 2016 - d3.js un taller divertido y difícilCodemotion 2016 - d3.js un taller divertido y difícil
Codemotion 2016 - d3.js un taller divertido y difícil
Javier Abadía681 vistas

Último

Tecnologia (3).pdf por
Tecnologia (3).pdfTecnologia (3).pdf
Tecnologia (3).pdfnosi6702
7 vistas15 diapositivas
La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1 por
La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1
La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1Angel Borroy López
6 vistas22 diapositivas
MasterMind.pdf por
MasterMind.pdfMasterMind.pdf
MasterMind.pdfrtovarfernandez
18 vistas5 diapositivas
Peña_Anaya_TAREA Reportes Maestro - Detalle con el uso de AJAX.pptx por
Peña_Anaya_TAREA Reportes Maestro - Detalle con el uso de AJAX.pptxPeña_Anaya_TAREA Reportes Maestro - Detalle con el uso de AJAX.pptx
Peña_Anaya_TAREA Reportes Maestro - Detalle con el uso de AJAX.pptxMOISESPENAANAYA
6 vistas8 diapositivas
Tecnologia (1).pdf por
Tecnologia (1).pdfTecnologia (1).pdf
Tecnologia (1).pdfnosi6702
9 vistas13 diapositivas
Qué es el rodamiento hacia adelante.docx por
Qué es el rodamiento hacia adelante.docxQué es el rodamiento hacia adelante.docx
Qué es el rodamiento hacia adelante.docxFabianCarrillo31
7 vistas1 diapositiva

Último(8)

Tecnologia (3).pdf por nosi6702
Tecnologia (3).pdfTecnologia (3).pdf
Tecnologia (3).pdf
nosi67027 vistas
La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1 por Angel Borroy López
La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1
La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1
Peña_Anaya_TAREA Reportes Maestro - Detalle con el uso de AJAX.pptx por MOISESPENAANAYA
Peña_Anaya_TAREA Reportes Maestro - Detalle con el uso de AJAX.pptxPeña_Anaya_TAREA Reportes Maestro - Detalle con el uso de AJAX.pptx
Peña_Anaya_TAREA Reportes Maestro - Detalle con el uso de AJAX.pptx
MOISESPENAANAYA6 vistas
Tecnologia (1).pdf por nosi6702
Tecnologia (1).pdfTecnologia (1).pdf
Tecnologia (1).pdf
nosi67029 vistas
Qué es el rodamiento hacia adelante.docx por FabianCarrillo31
Qué es el rodamiento hacia adelante.docxQué es el rodamiento hacia adelante.docx
Qué es el rodamiento hacia adelante.docx
FabianCarrillo317 vistas
Operations & Data Graph por Neo4j
Operations & Data GraphOperations & Data Graph
Operations & Data Graph
Neo4j42 vistas
Aws Community Day Guatemala Criptografia con AWS KMS por Mario IC
Aws Community Day Guatemala Criptografia con AWS KMSAws Community Day Guatemala Criptografia con AWS KMS
Aws Community Day Guatemala Criptografia con AWS KMS
Mario IC26 vistas

Reactividad en Angular, React y VueJS

  • 1. REACTIVIDADen Angular, React yVue @javierabadia
  • 2. FASHION MEETS BIG DATA 2015
  • 9. stack queue heap addToCart() product1 product2 getDiscount() { brand: ‘Salomon’,, name: ‘XMax’,, price: 399.00, } { brand: ‘Atomic’,, name: ‘M110’,, price: 325.00, } Las variables calcPrice(p) p discount newPrice function getDiscount() { return 0.20; } function calcPrice(p) { var discount = getDiscount(); var newPrice = p.price * (1 - discount); p['finalPrice'] = newPrice; } function addToCart() { var product1 = { brand: 'Salomon', name: 'XMax', price: 399.00, }; var product2 = { brand: 'Atomic', name: 'M110', price: 325.00, }; calcPrice(product1); } { brand: ‘Salomon’,, name: ‘XMax’,, price: 399.00, finalPrice 319,20, }0.20 319,20
  • 10. stack queue heap { brand: ‘Atomic’,, name: ‘M110’,, price: 325.00, } Las variables function getDiscount() { return 0.20; } function calcPrice(p) { var discount = getDiscount(); var newPrice = p.price * (1 - discount); p['finalPrice'] = newPrice; } function addToCart() { var product1 = { brand: 'Salomon', name: 'XMax', price: 399.00, }; var product2 = { brand: 'Atomic', name: 'M110', price: 325.00, }; calcPrice(product1); } { brand: ‘Salomon’,, name: ‘XMax’,, price: 399.00, finalPrice 319,20, }
  • 11. stack queue heap El bucle de eventos o “los turnos” task1 task2 (onclick) task3 (xhr) fn1.1() fn1.2() fn1.3() fn2.1() fn2.2()
  • 14. ¿Pero esto puede funcionar? AngularJS
  • 15. scope (MainCtrl) { additionalDiscount: 0, products: [ {name: 'XMax X10 2018’, … }, {name: 'Magnum’, …}, {name: 'Amphibio XII’, …}, {name: 'Vector Edge’, …}, {name: 'Fogbreaker’, …}, ], addToCart: function (product) { alert(`added ${product.name}`); }, } scope (ProductCard) { product: {name: 'XMax X10 2018’, … }, additionalDiscount: 0, addToCart: fn(), isDiscounted: fn(), }, AngularJS en una slide: scopes
  • 16. <div ng-controller="MainCtrl"> counter: {{counter}} doubleCounter: {{doubleCounter}} <button ng-click="increment()">increment</button> </div> app.controller('MainCtrl', function ($scope) { $scope.counter = 0; $scope.increment = function () { $scope.counter += 1; }; $scope.$watch('counter', function () { $scope.doubleCounter = $scope.counter * 2; }); }); $scope = { counter: 0, doubleCounter: 0, ... } AngularJS en una slide: watchers bindings en la plantilla watchers explícitos
  • 17. $$watchers do { // "traverse the scopes" loop if ((watchers = !current.$$suspended && current.$$watchers)) { // process our watches watchers.$$digestWatchIndex = watchers.length; while (watchers.$$digestWatchIndex--) { try { watch = watchers[watchers.$$digestWatchIndex]; // Most common watches are on primitives, in which case we can short // circuit it with === operator, only when === fails do we use .equals if (watch) { get = watch.get; if ((value = get(current)) !== (last = watch.last) && !(watch.eq ? equals(value, last) : (isNumberNaN(value) && isNumberNaN(last)))) { dirty = true; lastDirtyWatch = watch; watch.last = watch.eq ? copy(value, null) : value; fn = watch.fn; fn(value, ((last === initWatchVal) ? value : last), current); if (ttl < 5) { logIdx = 4 - ttl; if (!watchLog[logIdx]) watchLog[logIdx] = []; watchLog[logIdx].push({ msg: isFunction(watch.exp) ? 'fn: ' + (watch.exp.name || watch.exp.toString()) : watch.exp, newVal: value, oldVal: last }); } } else if (watch === lastDirtyWatch) { // If the most recently dirty watcher is now clean, short circuit since the remaining watchers // have already been tested. dirty = false; break traverseScopesLoop; } } } catch (e) { $exceptionHandler(e); } } } // Insanity Warning: scope depth-first traversal // yes, this code is a bit crazy, but it works and we have tests to prove it! // this piece should be kept in sync with the traversal in $broadcast // (though it differs due to having the extra check for $$suspended and does not // check $$listenerCount) if (!(next = ((!current.$$suspended && current.$$watchersCount && current.$$childHead) || (current !== target && current.$$nextSibling)))) { while (current !== target && !(next = current.$$nextSibling)) { current = current.$parent; } } } while ((current = next));
  • 18. dirty checking = ciclo de $digest / $apply • para cada $scope • para cada watcher en $$watchers • evalúa la expresión (p.ej. ‘counter’) • compara con el resultado anterior (p.ej 3 === 2) • si es distinto, ejecuta el callback • en caso de un binding de la plantilla, el callback cambia el valor en el DOM • como los callbacks pueden cambiar cosas, se repite el ciclo hasta que no haya ningún cambio scope.$watch(interpolateFn, function interpolateFnWatchAction(value) { node[0].nodeValue = value; });
  • 20. ¿cuándo? • al final de cada turno • siempre y cuando lo haya iniciado una tarea de Angular.js • por ejemplo • ng-click • $timeout, $interval • $http stack queue heap baz() foo() product1 product2 bar() p discount newPrice ng-click() ahora!
  • 21. ¿y si ocurre algo fuera? • AngularJS no se entera • tenemos que llamar a $scope.$apply() manualmente • p.ej. • usando d3.js • eventos nativos de librerías externas • eventos que podemos recibir de otro iframe
  • 22. el doble binding • ng-model = mola • se vinieron arriba • en las directivas propias • ufff <the-counter counter='counter'></the-counter> app.directive('theCounter', function () { return { scope: { counter: '=', }, template: ` <div> {{counter}} <button ng-click="dec()">dec</button> </div>`, link(scope, el, attr) { scope.dec = function() { scope.counter -= 1; }; }, }; }); <input type="text" ng-model="passportId" />
  • 23. Cómo ayudar a AngularJS • usar pocos watchers • y si es posible, que cambien pocas cosas? • no poner muchos bindings • usar bind once (p.ej {{::brand}}) • ng-repeat track by • virtualizar listas • $watch / $watch(…,…,true) / $watchGroup() / $watchCollection()
  • 24. Los problemas de AngularJS • la falta de orientación a componentes • herencia de scopes • la falta de un mecanismo de gestión de estado • no tan importantes (EMHO) • rendimiento con muchos bindings/watchers • complejidad derivada del doble binding • Angular2
  • 26. React en una slide <App /> <ProductCard /> <DiscountTag /><Price /> <ProductCard /> <DiscountTag /><Price /> render() props state elements render()
  • 27. El origen de React es… • PHP
  • 28. El origen de React es… • PHP PHP? React?
  • 29. El origen de React es… • PHP / XHP • reescrito a JavaScript • convertido de servidor a cliente $list = <ul />; foreach ($items as $item) { $list->appendChild(<li>{$item}</li>); } https://www.facebook.com/notes/facebook-engineering/xhp-a- new-way-to-write-php/294003943919/
  • 30. Como los videojuegos • cambio el estado • renderizo todo • DOM LEEEEENTOOOOO • no tiene por qué • si se hace mal • reflow & Paint • ¡DOM guarda estado! • selección • foco • scroll
  • 31. por eso - VirtualDOM { type: 'button', props: { className: 'button button-blue', children: { type: 'b', props: { children: 'OK!' } } } } <button class="button button-blue"> <b>OK!</b> </button> objetos que representan el DOM equivale a
  • 32. VirtualDOMComponentes “parchear” el DOM real VirtualDOM anterior render() diff()
  • 33. ¿cuándo hay que renderizar? • tenemos que avisar a REACT • this.setState({…}) • encola el componente (y sus hijos) para renderizar • ¿cuándo se renderiza? • batched updates - a veces!
  • 34. ¿y la reactividad dato → dato? • Fuera del alcance de React • O dicho de otra forma, ¿comunicación entre componentes que están lejos? • PubSub • Eventos • Redux • Mobx • Redux-saga
  • 35. ¿Cómo ayudar a React? • no todo debe ir en this.state • se pueden añadir propiedades al componente fuera de la ‘jurisdicción’ de React • shouldUpdateComponent() • datos inmutables • virtualizar listas • Perf.printWasted() (<16, con Fiber → browserTimeline)
  • 36. Angular 2+ Para los que echan de menos Java y C#
  • 37. Detección de Cambios en Angular2 • sigue usando dirty-checking • igual que AngularJS • solucionar los problemas de AngularJS • las múltiples vueltas de $digest/$apply • los cambios fuera de Angular • además se les fue la pinza conTypeScript y otras 1000 cosas 1 2
  • 38. Cómo evitar las multiples vueltas • se eliminan los watchers de usuario • por lo tanto, no puedo cambiar el estado en el ciclo de comprobación 1
  • 39. ¿Cómo detectar todos los cambios? • el problema es cuando se ejecuta código fuera de Angular • Angular2 lo soluciona mediante ‘zonas’ 2
  • 40. function doSomething() { console.log('Async task'); } function foo() { bar(); setTimeout(doSomething, 2000); baz(); } foo();
  • 41. myZoneSpec = { beforeTask: () => { console.log('entering zone'); }, afterTask: () => { console.log('leaving zone'); }, }; function doSomething() { console.log('Async task'); } function foo() { bar(); setTimeout(doSomething, 2000); baz(); } let myZone = zone.fork(myZoneSpec); myZone.run(foo); zones.js
  • 42. zones.js • ¿Es mágia? • No… es monkey-patching de los event listener, setTimeout(), setInterval(), xhr • Por eso ya no es necesario usar $timeout o $interval
  • 43. ¿Cómo detectar todos los cambios? • Zonas • zones.js permite detectar todas las tareas que ‘nacen’ de una misma tarea (eso es una zona) • p.ej. permite hacer call-stacks de llamadas asíncronas • p.ej. permite registrar eventos al entrar o salir de una zona (empezar a ejecutar una tarea o finalizarla) • Se “envuelve” todo el código de Angular en una zona • detecta cambios cuando la cola de tareas de la zona de Angular está vacía 2
  • 44. Reactividad dato → dato = RxJS • Functional Reactie Programming • Observables • pipes • streams // config.service.ts getConfig() { return this.http.get('assets/config.json'); } // in component.ts showConfig() { this.configService.getConfig() .subscribe(data => this.config = { heroesUrl: data['heroesUrl'], textfile: data['textfile'] }); }
  • 45. ¿Cómo ayudar a Angular? • ChangeDetectionStrategy.OnPush • Track By • RxJS • Pure Pipes
  • 46. Vue.js el front vuelve a ser divertido
  • 47. Vue.js en una slide <template> <div class="product-card"> <div class="description"> <div class="name">{{product.name}}</div> <div class="brand">{{product.brand}}</div> <div class="price--original" v-if="isDiscounted"> <price :price="product.price"/> </div> <div class="price"> <price :price='finalPrice'/> </div> <button class="nice-button" @click="addToCart(product)">Add to Cart</button> </div> <div class="img"> <discount-tag class="discount" :discount="product.discount"/> <img v-if="product.img" :src="product.img" :alt="product.name"> </div> </div> </template> sintaxis de las templates parecida a Angular.js bindings de atributos bindings de eventos
  • 50. Ficheros *.vue javascript template estilos <template> <div class="product-card"> </div> </template> <script> import Price from './Price'; import DiscountTag from './DiscountTag'; export default { props: { product: Object, overallDiscount: Number, }, computed: { … finalPrice() { return this.product.price * (1 - this.effectiveDiscount); }, … }, methods: { addToCart(product) { alert(`added ${product.name}`); } }, components: { Price, DiscountTag, }, }; </script> <style lang="less" rel="stylesheet/less"> … </style> las templates se “compilan” a una función render()
  • 51. Función render() <template> <div class="discount-tag" v-if="discount !== 0">{{discount * 100}}%</div> </template> <script> export default { props: { discount: Number, }, }; </script> <script> export default { functional: true, render: function (h, context) { const discount = context.props.discount; return discount ? h( 'div', {'class': 'discount-tag ' + context.data.staticClass}, (context.props.discount * 100) + '%', ) : undefined; }, props: { discount: Number, }, }; </script> <script> export default { functional: true, render: function (h, context) { const discount = context.props.discount; return discount ? ( <div class={'discount-tag'} {...context.data}> {(context.props.discount * 100) + '%'} </div> ) : undefined; }, props: { discount: Number, }, }; </script> VirtualDOM es lo mismo
  • 52. VirtualDOMComponentes “parchear” el DOM real VirtualDOM anterior render() diff()
  • 53. ¿cuándo se llama a render() de cada componente?
  • 54. ¿como sabe cuándo hay que renderizar? • Angular.js - dirty-checking • al final de cada turno, evalúa todos los watchers y actualiza los nodos correspondientes • React.js - como los videojuegos • cuando se llama a setState() de un componente • re-renderiza todos sus hijos • Vue.js • cuando cambia un dato “reactivo” • re-renderiza los componentes que dependen de el dato
  • 55. ¿que datos son reactivos? • componente • data (= estado) • props • propiedades computadas Vue.js cuando cambia un dato “reactivo” re-renderiza los componentes que dependen de el dato
  • 56. Propiedades Computadas computed: { finalPrice() { return this.product.price * (1 - this.effectiveDiscount); }, effectiveDiscount() { return this.product.discount + this.overallDiscount; }, }, <template> <div class="product-card"> <span>{{finalPrice}}</span> </div> </template>
  • 57. ¿cómo sabe que cambia? • Vue.js reemplaza los “datos” por propiedades ES5 con getter y setter Object.defineProperty() Vue.js cuando cambia un dato “reactivo” re-renderiza los componentes que dependen de el dato let _p1 = 23; const state = { get p1() { console.log('getting p1’); return _p1; }, set p1(value) { console.log('setting p1=', value); _p1 = value; } }
  • 59. ¿cómo sabe qué componentes dependen del dato? Vue.js cuando cambia un dato “reactivo” re-renderiza los componentes que dependen de el dato https://vuejs.org/v2/guide/reactivity.html
  • 60. getters y setters en vue.js • los setters • cambian el dato • avisa a quien dependa de mi de que el dato ha cambiado • los getters • devuelven el dato • actualizan la lista de dependencias para poder avisar
  • 61. ¿Cómo ayudar a Vue.js? • no necesita mucha ayuda • mutar objetos, en lugar de reemplazarlos • uso ‘extensivo’ de computed properties • tener en cuenta los “change detection caveats” https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats
  • 63. Y todo esto… para que sirve? • un factor más para elegir el framework que más se adapta a nuestro estilo/proyecto/gusto • para usar los frameworks mejor • go with the flow • evitar ‘trampas’ • optimizar rendimiento • para migrar de un framework a otro sobre la marcha • ¿una app donde conviven dos (o más) frameworks?
  • 67. Referencias • MDN Event Loop: https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop • EvanYou, Reactivity in Frontend JavaScript Frameworks https://www.dotconferences.com/2016/12/evan-you-reactivity-in-frontend-javascript-frameworks • Change Detection in JS Frameworks: http://teropa.info/blog/2015/03/02/change-and-its-detection-in- javascript-frameworks.html
  • 68. Referencias - Angular • Improve Angular Performance: https://www.alexkras.com/11-tips-to-improve-angularjs-performance/#watchers • Angular Code Overview: https://angular.io/guide/architecture • Change Detection in Angular 2: https://vsavkin.com/change-detection-in-angular-2-4f216b855d4c, https://codewithstyle.info/change-detection-angular-versus-angularjs/, https://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html • Zones: https://blog.thoughtram.io/angular/2016/01/22/understanding-zones.html, https://www.joshmorony.com/understanding-zones-and-change-detection-in-ionic-2-angular-2/, https://angular-2-training- book.rangle.io/handout/zones/ • Zone Primer: https://docs.google.com/document/d/1F5Ug0jcrm031vhSMJEOgp1l-Is-Vf0UCNDY- LsQtAIY/edit#heading=h.s6p06rpu4c13 • RxJS: https://auth0.com/blog/making-use-of-rxjs-angular/, https://medium.com/google-developer-experts/angular- introduction-to-reactive-extensions-rxjs-a86a7430a61f, https://blog.angular-university.io/functional-reactive-programming- for-angular-2-developers-rxjs-and-observables/, https://stackoverflow.com/questions/37364973/angular-promise-vs- observable, https://alligator.io/vuejs/using-rxjs/ • Angular2 performance: https://netbasal.com/optimizing-the-performance-of-your-angular-application-f222f1c16354 • Observables: https://angular-2-training-book.rangle.io/handout/observables/ • State management: https://angular-2-training-book.rangle.io/handout/state-management/
  • 69. Referencias - React • XHP: https://www.facebook.com/notes/facebook-engineering/xhp-a-new-way-to-write-php/294003943919/ • From XHP to React: https://reactjs.org/blog/2016/09/28/our-first-50000-stars.html • History of React: https://thenewstack.io/javascripts-history-and-how-it-led-to-reactjs/ • React Codebase Overview: https://reactjs.org/docs/codebase-overview.html • VirtualDOM and internals: https://reactjs.org/docs/faq-internals.html, https://reactjs.org/docs/rendering- elements.html, https://reactjs.org/blog/2015/12/18/react-components-elements-and-instances.html • Cristopher Chedeau (Facebook), React’s Architecture https://code.facebook.com/videos/1507312032855537/oscon-2014-react-s-architecture/ • How to communicate between ReactJS components: https://www.ctheu.com/2015/02/12/how-to-communicate- between-react-components/, https://anthonymineo.com/communication-between-independent-components- in-react-using-pubsubjs/ • React Props vs State: https://github.com/uberVU/react-guide/blob/master/props-vs-state.md, http://lucybain.com/blog/2016/react-state-vs-pros/ • React State and Lifecycle: https://reactjs.org/docs/state-and-lifecycle.html • Optimizing React: https://reactjs.org/docs/optimizing-performance.html, https://marmelab.com/blog/2017/02/06/react-is-slow-react-is-fast.html • React + Redux: https://stackoverflow.com/questions/40386128/how-does-a-redux-connected-component- know-when-to-re-render
  • 70. Referencias - VueJS • Vue Code Overview: https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md • Vue a better React: https://mattcampbell.net/slides/vue/#0 • Vue.js Reactivity: https://vuejs.org/v2/guide/reactivity.html, https://vuejsdevelopers.com/2017/03/05/vue-js-reactivity/ • Change Detection Caveats: https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats

Notas del editor

  1. Hola, buenos días… gracias por venir a tiempo y elegir estar aquí un sábado por la mañana en lugar de estar haciendo otra cosa. Me hace mucha ilusión estar aquí, y especialmente abrir el fuego de un día que promete que va a ser muy intenso. Voy a empezar hablando de Reactividad en los principales frameworks de JavaScript… va a ser una charla muy muy técnica. Yo he aprendido mucho preparándola y espero saber transmitiros las ideas tan interesantes que hay en los tres frameworks. arrancar demos: 1. event-loop: cd /Users/jami/devel/charlas/frontfest2018-reactividad/snippets; open event-loop.html  desactivar async stack traces 2. angularjs cd /Users/jami/devel/charlas/frontfest2018-reactividad/demos/ng-ecommerce; live-server abrir las dev tools y borrar la consola 3. react cd /Users/jami/devel/charlas/frontfest2018-reactividad/demos/react-ecommerce; yarn start 4. vue cd /Users/jami/devel/charlas/frontfest2018-reactividad/demos/vue-ecommerce; yarn dev OCULTAR BOOKMARKS CERRAR RESTO PESTAÑAS DESACTIVAR NOTIFICACIONES
  2. En febrero de 2015 empezamos a desarrollar nuestra plataforma usando AngularJS. Era lo que molaba y nos funcionó estupendamente durante casi dos años. Teníamos la sensación de ser super-productivos y pudimos evolucionar y añadir features con bastante velocidad. Nuestra plataforma fue creciendo y creciendo y dos años mas tarde, (el año pasado por estas fechas) empezamos a plantearnos que el framework ya no nos estaba funcionando tan bien. Así que empezamos a analizar las tres alternativas obvias: Angular2, React y VueJS
  3. EL PROBLEMA DE LA REACTIVIDAD cambia un dato -> debe cambiar la UI cambia un dato -> deben cambiar otros datos así que esta charla va de eso de comparar cómo resuelven la reactividad los tres frameworks principales en 2018
  4. a mi me dan mucha rabia las charlas de este tipo se supone que te van a explicar algo muy difícil, pero luego se quedan solo en lo fácil y al terminar la charla, te quedas con cara de idiota diciendo… si, pero.. ¿cómo hago el paso 5?
  5. en javascript, los parámetros se pasan por valor pero se pasan referencias a los objetos o arrays
  6. en javascript, los parámetros se pasan por valor pero se pasan referencias a los objetos o arrays
  7. hay una cola de tareas el motor de JavaScript toma la primera tarea de la cola, y la ejecuta HASTA EL FINAL esa tarea puede encolar nuevas tareas, que se ejecutarán más tarde (asíncronas) cada evento da lugar a una nueva tarea (handler)
  8. en angular para cada trozo del dom tenemos un scope, que es un objeto que contiene todas las variables y funciones que están disponibles en la plantilla cada controladora o directiva que usamos crea un scope que va asociado con una parte del DOM
  9. el enlace entre la plantilla y los datos el scope se hace mediante watchers un watcher es una función que evalúa una expresión y compara el resultado con el resultado anterior, si el resultado es distinto, se llama al callback
  10. un scope tiene una lista de $$watchers: todos los bindings implícitos y explícitos vamos a verlo angular.element($0) sobre el padre, ver los $$watchers angular.element($0) sobre una product-card, ver los $$watchers cuando AngularJS tiene que detectar cambios, recorre todos los scopes, evaluando todos los $watchers y aplicando los cambios… como en los callback se pueden cambiar las variables, cuando termina, vuelve a repetir el proceso hasta que todos los $watchers se estabilizan
  11. cuando AngularJS tiene que detectar cambios, recorre todos los scopes, evaluando todos los $watchers y aplicando los cambios… como en los callback se pueden cambiar las variables, cuando termina, vuelve a repetir el proceso hasta que todos los $watchers se estabilizan vamos a verlo
  12. https://imgflip.com/memegenerator
  13. vamos a verlo
  14. ???
  15. https://www.alexkras.com/11-tips-to-improve-angularjs-performance/#watchers
  16. la falta de orientación a componentes (es difícil definir componentes con plantilla + js + estilo) la gestión del estado el estado acaba repartido en controladoras y directivas (tiene la estructura del DOM) el estado de una aplicación mediana o grande no tiene la misma estructura que su presentación en la página otras críticas que se han hecho a AngularJS = rendimiento y la complejidad del doble-binding el principal problema de AngularJS es Angular2
  17. Arbol de componentes Un componente genera HTML a partir de datos crudos (render()) Componentes tienen props y [state] (los datos crudos) Componentes “tontos” o funcionales (solo props) Componentes con estado (props + state) El estado es privado de un componente Los datos van hacia abajo (a través de las props) Las modificaciones van hacia arriba (a través de callbacks) JSX
  18. https://www.facebook.com/notes/facebook-engineering/xhp-a-new-way-to-write-php/294003943919/ reescrito a JavaScript convertido de servidor a cliente
  19. https://www.facebook.com/notes/facebook-engineering/xhp-a-new-way-to-write-php/294003943919/ reescrito a JavaScript convertido de servidor a cliente
  20. https://www.facebook.com/notes/facebook-engineering/xhp-a-new-way-to-write-php/294003943919/ https://reactjs.org/blog/2016/09/28/our-first-50000-stars.html reescrito a JavaScript convertido de servidor a cliente
  21. https://reactjs.org/docs/rendering-elements.html https://reactjs.org/blog/2015/12/18/react-components-elements-and-instances.html
  22. React llama al render() de la raíz del árbol de componentes El componente raíz se renderiza (genera nodos del VirtualDOM) y llama a los componentes hijos para que se rendericen. Los elementos son objetos planos Javascript que dicen la etiqueta, los atributos y los hijos de cada nodo. React compara el VirtualDOM resultante con el VirtualDOM anterior y extrae las diferencias. Finalmente esas diferencias se aplican al DOM real para actualizar lo que el usuario está viendo
  23. https://groups.google.com/forum/#!topic/reactjs/G6pljvpTGX0 $r.setState({...$r.state, products: [{...$r.state.products[0], discount: 0.1}, ...$r.state.products.slice(1)]})
  24. https://www.ctheu.com/2015/02/12/how-to-communicate-between-react-components/ https://anthonymineo.com/communication-between-independent-components-in-react-using-pubsubjs/
  25. https://reactjs.org/docs/optimizing-performance.html https://marmelab.com/blog/2017/02/06/react-is-slow-react-is-fast.html
  26. https://docs.google.com/document/d/1F5Ug0jcrm031vhSMJEOgp1l-Is-Vf0UCNDY-LsQtAIY/edit#heading=h.s6p06rpu4c13
  27. https://auth0.com/blog/making-use-of-rxjs-angular/ https://medium.com/google-developer-experts/angular-introduction-to-reactive-extensions-rxjs-a86a7430a61f https://blog.angular-university.io/functional-reactive-programming-for-angular-2-developers-rxjs-and-observables/ https://stackoverflow.com/questions/37364973/angular-promise-vs-observable
  28. https://netbasal.com/optimizing-the-performance-of-your-angular-application-f222f1c16354
  29. en Vue, las templates son muy parecidas a Angujar.js se pueden interpolar expresiones de javascript se pueden asociar valores con los atributos y se pueden asociar métodos con los eventos también hay directivas condicionales, y bucles eso era una buena idea en Angular, y se ha mantenido
  30. donde realmente mejora Vue es en la orientación a componentes una app vue se escribr a base de ficheros *.vue, uno por cada componente donde tenemos la template, el código javascript y los estilos TODO en el mismo fichero
  31. donde realmente mejora Vue es en la orientación a componentes una app vue se escribr a base de ficheros *.vue, uno por cada componente donde tenemos la template, el código javascript y los estilos TODO en el mismo fichero
  32. cada uno en su lenguaje HTML/Javascript/CSS y todo en el mismo fichero para que esto se convierta en algo que pueda cargar un navegador, hace falta que webpack “compile” todos los ficheros .vue y los empaquete en un javascript único y un css único. Hay un plugin de webpack que se llama vue-loader que hace precisamente eso. Y además, compila las templates a una función render() en javascript (igual que en React)
  33. Si queremos, podemos escribir nosotros la función render() en Javascript. El objetivo es convertir los “datos” en nodos del DOM. La función render genera un VirtualDOM (igual que en react) y luego ese VirtualDOM se compara con el anterior y se aplican los cambios a DOM del navegador. Incluso, si queremos, podemos escribir las funciones render con JSX… pero… teniendo la posibilidad de escribir el DOM en HTML… ¿para qué querríamos usar JSX? en fin, cada uno elije la droga con la que se mata
  34. La parte final del renderizado de Vue es igual que la de React Vue llama a la función render de cada componente y monta el VirtualDOM que es un árbol de “elementos”. Los elementos son objetos planos Javascript que dicen la etiqueta, los atributos y los hijos de cada nodo. Vue compara el VirtualDOM resultante con el VirtualDOM anterior y extrae las diferencias. Finalmente esas diferencias se aplican al DOM real para actualizar lo que el usuario está viendo
  35. demo reactividad
  36. se cachean, es casi declarativo
  37. let _p1 = 23;const state = { get p1() { console.log('getting p1'); return _p1; }, set p1(value) { console.log('setting p1=', value); _p1 = value;}}
  38. https://vuejs.org/v2/guide/reactivity.html
  39. el año de la convergencia la reactividad es la diferencia angularjs abrió el camino react cambió el enfoque angular2 se vino arriba vue combinó lo mejor
  40. no es un tutorial no es una comparativa para vuer cual elijo conoce tu framework y no le pongas las cosas difíciles los fundamentos turnos identidad / mutabilidad / inmutabilidad mutar o no mutar, esa es la cuestión