SlideShare une entreprise Scribd logo
1  sur  70
REACTIVIDADen Angular, React yVue
@javierabadia
FASHION MEETS BIG DATA
2015
ecosistema comunidad
CLI
enrutado
orientación a
componentes
rendimiento
💩webpack 💩
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
¿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;
});
¿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;
}
}
¿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?
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

Contenu connexe

Tendances

NoSQL Data Stores in Research and Practice - ICDE 2016 Tutorial - Extended Ve...
NoSQL Data Stores in Research and Practice - ICDE 2016 Tutorial - Extended Ve...NoSQL Data Stores in Research and Practice - ICDE 2016 Tutorial - Extended Ve...
NoSQL Data Stores in Research and Practice - ICDE 2016 Tutorial - Extended Ve...
Felix Gessert
 
IB Biology cellular respiration 2015.ppt
IB Biology cellular respiration 2015.pptIB Biology cellular respiration 2015.ppt
IB Biology cellular respiration 2015.ppt
Bob Smullen
 
AWS와 부하테스트의 절묘한 만남 :: 김무현 솔루션즈 아키텍트 :: Gaming on AWS 2016
AWS와 부하테스트의 절묘한 만남 :: 김무현 솔루션즈 아키텍트 :: Gaming on AWS 2016AWS와 부하테스트의 절묘한 만남 :: 김무현 솔루션즈 아키텍트 :: Gaming on AWS 2016
AWS와 부하테스트의 절묘한 만남 :: 김무현 솔루션즈 아키텍트 :: Gaming on AWS 2016
Amazon Web Services Korea
 

Tendances (20)

Apache Airflow in the Cloud: Programmatically orchestrating workloads with Py...
Apache Airflow in the Cloud: Programmatically orchestrating workloads with Py...Apache Airflow in the Cloud: Programmatically orchestrating workloads with Py...
Apache Airflow in the Cloud: Programmatically orchestrating workloads with Py...
 
MSDN - ASP.NET MVC
MSDN - ASP.NET MVCMSDN - ASP.NET MVC
MSDN - ASP.NET MVC
 
Kotlin coroutines 톺아보기
Kotlin coroutines 톺아보기Kotlin coroutines 톺아보기
Kotlin coroutines 톺아보기
 
NoSQL Data Stores in Research and Practice - ICDE 2016 Tutorial - Extended Ve...
NoSQL Data Stores in Research and Practice - ICDE 2016 Tutorial - Extended Ve...NoSQL Data Stores in Research and Practice - ICDE 2016 Tutorial - Extended Ve...
NoSQL Data Stores in Research and Practice - ICDE 2016 Tutorial - Extended Ve...
 
Redis
RedisRedis
Redis
 
Svelte
SvelteSvelte
Svelte
 
IB Biology cellular respiration 2015.ppt
IB Biology cellular respiration 2015.pptIB Biology cellular respiration 2015.ppt
IB Biology cellular respiration 2015.ppt
 
Left and Right Folds - Comparison of a mathematical definition and a programm...
Left and Right Folds- Comparison of a mathematical definition and a programm...Left and Right Folds- Comparison of a mathematical definition and a programm...
Left and Right Folds - Comparison of a mathematical definition and a programm...
 
Ch6 대용량서비스레퍼런스아키텍처 part.1
Ch6 대용량서비스레퍼런스아키텍처 part.1Ch6 대용량서비스레퍼런스아키텍처 part.1
Ch6 대용량서비스레퍼런스아키텍처 part.1
 
Hexagonal architecture in PHP
Hexagonal architecture in PHPHexagonal architecture in PHP
Hexagonal architecture in PHP
 
AWS와 부하테스트의 절묘한 만남 :: 김무현 솔루션즈 아키텍트 :: Gaming on AWS 2016
AWS와 부하테스트의 절묘한 만남 :: 김무현 솔루션즈 아키텍트 :: Gaming on AWS 2016AWS와 부하테스트의 절묘한 만남 :: 김무현 솔루션즈 아키텍트 :: Gaming on AWS 2016
AWS와 부하테스트의 절묘한 만남 :: 김무현 솔루션즈 아키텍트 :: Gaming on AWS 2016
 
Zero Downtime Schema Changes in Galera Cluster
Zero Downtime Schema Changes in Galera ClusterZero Downtime Schema Changes in Galera Cluster
Zero Downtime Schema Changes in Galera Cluster
 
코드의 품질 (Code Quality)
코드의 품질 (Code Quality)코드의 품질 (Code Quality)
코드의 품질 (Code Quality)
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript Promises
 
Asynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFutureAsynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFuture
 
Creating Continuously Up to Date Materialized Aggregates
Creating Continuously Up to Date Materialized AggregatesCreating Continuously Up to Date Materialized Aggregates
Creating Continuously Up to Date Materialized Aggregates
 
Node js overview
Node js overviewNode js overview
Node js overview
 
Scalable webservice
Scalable webserviceScalable webservice
Scalable webservice
 
Java Interview Questions and Answers | Spring and Hibernate Interview Questio...
Java Interview Questions and Answers | Spring and Hibernate Interview Questio...Java Interview Questions and Answers | Spring and Hibernate Interview Questio...
Java Interview Questions and Answers | Spring and Hibernate Interview Questio...
 
[MLOps KR 행사] MLOps 춘추 전국 시대 정리(210605)
[MLOps KR 행사] MLOps 춘추 전국 시대 정리(210605)[MLOps KR 행사] MLOps 춘추 전국 시대 정리(210605)
[MLOps KR 행사] MLOps 춘추 전국 시대 정리(210605)
 

Similaire à Reactividad en Angular, React y VueJS

Arduino: Reporte de diseño controlador acuario con Arduino
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
SANTIAGO PABLO ALBERTO
 
7090112 Clase Transact Sql Server
7090112 Clase Transact Sql Server7090112 Clase Transact Sql Server
7090112 Clase Transact Sql Server
Corfapo
 

Similaire à Reactividad en Angular, React y VueJS (20)

JavaScript no es Vietnam
JavaScript no es VietnamJavaScript no es Vietnam
JavaScript no es Vietnam
 
Curso AngularJS - 7. temas avanzados
Curso AngularJS - 7. temas avanzadosCurso AngularJS - 7. temas avanzados
Curso AngularJS - 7. temas avanzados
 
Introducción a la Progamación en Javascript. Classe 2
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
 
Dart como alternativa a TypeScript (Codemotion 2016)
Dart como alternativa a TypeScript (Codemotion 2016)Dart como alternativa a TypeScript (Codemotion 2016)
Dart como alternativa a TypeScript (Codemotion 2016)
 
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.
Parte II. Notas Rapidas (sticky notes) App W8: MVVM y SQLite.
 
React
ReactReact
React
 
Concurrencia en Java
Concurrencia en Java Concurrencia en Java
Concurrencia en Java
 
HTML Tour - Programación de Videojuegos HTML5
HTML Tour - Programación de Videojuegos HTML5HTML Tour - Programación de Videojuegos HTML5
HTML Tour - Programación de Videojuegos HTML5
 
PARADIGMAS FP Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
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
 
Introducción al desarrollo Web: Frontend con Angular 6
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
 
Arduino: Reporte de diseño controlador acuario con Arduino
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
 
No hagas ahora lo que puedes dejar para otro momento (Celery)
No hagas ahora lo que puedes dejar para otro momento (Celery)No hagas ahora lo que puedes dejar para otro momento (Celery)
No hagas ahora lo que puedes dejar para otro momento (Celery)
 
ECMAScript 6
ECMAScript 6ECMAScript 6
ECMAScript 6
 
Curso Swift
Curso SwiftCurso Swift
Curso Swift
 
Hablemos de promesas
Hablemos de promesasHablemos de promesas
Hablemos de promesas
 
Segunda sesion
Segunda sesionSegunda sesion
Segunda sesion
 
MATERIAL DE UTP S01.s2-Tipos de funciones.pptx
MATERIAL DE UTP S01.s2-Tipos de funciones.pptxMATERIAL DE UTP S01.s2-Tipos de funciones.pptx
MATERIAL DE UTP S01.s2-Tipos de funciones.pptx
 
(Muy breve) Introduccion a jQuery
(Muy breve) Introduccion a jQuery(Muy breve) Introduccion a jQuery
(Muy breve) Introduccion a jQuery
 
Silex, desarrollo web ágil y profesional con PHP
Silex, desarrollo web ágil y profesional con PHPSilex, desarrollo web ágil y profesional con PHP
Silex, desarrollo web ágil y profesional con PHP
 
7090112 Clase Transact Sql Server
7090112 Clase Transact Sql Server7090112 Clase Transact Sql Server
7090112 Clase Transact Sql Server
 

Plus de Javier Abadía

Plus de Javier Abadía (12)

Python Asíncrono - Async Python
Python Asíncrono - Async PythonPython Asíncrono - Async Python
Python Asíncrono - Async Python
 
Extendiendo Django: Cómo Escribir Tu Propio Backend de Base de Datos - Exasol
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
 
UX/UI para Desarrolladores
UX/UI para DesarrolladoresUX/UI para Desarrolladores
UX/UI para Desarrolladores
 
Las 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Á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
 
Retos de Programación en Python
Retos de Programación en PythonRetos de Programación en Python
Retos de Programación en Python
 
Django + Vue, JavaScript de 3ª generación para modernizar Django
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
 
Vue.js + Django - configuración para desarrollo con webpack y HMR
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
 
Anatomía de un Bot para Resultados Electorales
Anatomía de un Bot para Resultados ElectoralesAnatomía de un Bot para Resultados Electorales
Anatomía de un Bot para Resultados Electorales
 
Deep learning image classification aplicado al mundo de la moda
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
 
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
Análisis de colores: cómo analizar tendencias de moda automáticamente
 
Codemotion 2016 - d3.js un taller divertido y difícil
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
 
La Noche Electoral
La Noche ElectoralLa Noche Electoral
La Noche Electoral
 

Reactividad en Angular, React y VueJS

  • 1. REACTIVIDADen Angular, React yVue @javierabadia
  • 2. FASHION MEETS BIG DATA 2015
  • 3.
  • 4.
  • 6.
  • 7.
  • 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()
  • 13.
  • 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; });
  • 19.
  • 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; } }
  • 58.
  • 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?
  • 64.
  • 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

Notes de l'éditeur

  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