Top Banner
@ArturSkowronski CHANGE DETECTION ANNO DOMINI 2016
70

Change Detection Anno Domini 2016

Apr 13, 2017

Download

Engineering

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Change Detection Anno Domini 2016

@ArturSkowronski

CHANGE DETECTIONANNO DOMINI 2016

Page 2: Change Detection Anno Domini 2016

ANGULAR MAGICREACT MAGICEMBER MAGIC

Page 3: Change Detection Anno Domini 2016
Page 4: Change Detection Anno Domini 2016
Page 5: Change Detection Anno Domini 2016

Any su�ciently advancedtechnology isindistinguishable frommagic.

- Arthur C. Clarke

Page 6: Change Detection Anno Domini 2016
Page 7: Change Detection Anno Domini 2016

IT IS ALL ABOUT STATE...... HOW WE MANAGE IT ...... AND HOW WE RENDER IT

Page 8: Change Detection Anno Domini 2016

MODEL -> DOM (RENDERING OR PROJECTION)FUNCTION(JSON) => DOM

Page 9: Change Detection Anno Domini 2016

DOM CHANGES ARE COSTLY

Page 10: Change Detection Anno Domini 2016

ONCE UPON A TIME...

Page 11: Change Detection Anno Domini 2016

FACEBOOK 2004

Page 12: Change Detection Anno Domini 2016

FACEBOOK TODAY

Page 13: Change Detection Anno Domini 2016

SPA

Page 14: Change Detection Anno Domini 2016

CLICK ME

Page 15: Change Detection Anno Domini 2016

IMPERATIVE AS HELL...

7. $("#first-one").css('background-color','green'); 8. $("#second-one").css('background-color','green'); 9. $("#third-one").css('background-color','green');

1. <button id="button">Click Me</button> 2. <div id="first-one"></div> 3. <div id="second-one"></div> 4. <div id="third-one"></div> 5. 6. $( "#button" ).click(function() {

10. }); 11.

Page 16: Change Detection Anno Domini 2016

TWO-WAY DATA-BINDINGSOBSERVERS/WATCHERS

Page 17: Change Detection Anno Domini 2016

MUTATOR FUNCTION

8. $scope.colorToGreen = function(){ 9. $scope.colorVar = "green" 10. }

1. <button ng-click="colorToGreen()">Click Me</button> 2. <div ng-style="{'background-color': colorVar}"></div> 3. <div ng-style="{'background-color': colorVar}"></div> 4. <div ng-style="{'background-color': colorVar}"></div> 5. 6. $scope.colorVar = "white" 7.

11.

Page 18: Change Detection Anno Domini 2016

MAGIC?

Page 19: Change Detection Anno Domini 2016

DIGEST LOOP & DIRTY CHECKING

Page 20: Change Detection Anno Domini 2016

EVENTS NOT CONTROLED BY ANGULAR.JS

15. setTimeout(function () { 16. $scope.message = "delayed message"; 17. $scope.$apply(); 18. }, 2000);

3. $scope.message = {} 4. 5. $watchList = [] 6. 7. scope.$watch('name', function(newValue, oldValue) { 8. scope.counter = scope.counter + 1; 9. }); 10. 11. angular.element(element).on(EVENT, function(){

12. $apply(); 13. }, 500)); 14.

19.

Page 21: Change Detection Anno Domini 2016

OBJECT.OBSERVE()

Page 22: Change Detection Anno Domini 2016

01.2016OBJECT.OBSERVE()

Page 23: Change Detection Anno Domini 2016

PROXIES

Page 24: Change Detection Anno Domini 2016
Page 25: Change Detection Anno Domini 2016

ZONES

Page 26: Change Detection Anno Domini 2016

ZONE.JS

Page 27: Change Detection Anno Domini 2016

MONKEY PATCHING

23. Zone.setInterval() 24. Zone.setTimeout() 25. Zone.alert() 26. Zone.prompt() 27. Zone.requestAnimationFrame() 28. Zone.addEventListener() 29. Zone.removeEventListener() 30. XMLHttpRequest 31.

11. });

12. 13. zone.setTimeout = function(cb, time){ 14. let window = localWindowGlobal; 15. 16. nativeSetTimeout(function(){ 17. angularStuff(); 18. cb(); 19. }, time); 20. 21. } 22.

Page 28: Change Detection Anno Domini 2016

export function patchMethod(target: any, name: string, patchFn: (delegate: Function, delegateName: string, name: string) => (self: any, args: any[]) => any): Function { let proto = target; while (proto && !proto.hasOwnProperty(name)) { proto = Object.getPrototypeOf(proto); } if (!proto && target[name]) { // somehow we did not find it, but we can see it. This happens on IE for Window properties. proto = target; } const delegateName = zoneSymbol(name); let delegate: Function; if (proto && ! (delegate = proto[delegateName])) { delegate = proto[delegateName] = proto[name]; proto[name] = createNamedFn(name, patchFn(delegate, delegateName, name)); } return delegate; } https://github.com/angular/zone.js/blob/master/lib/common/utils.ts

Page 29: Change Detection Anno Domini 2016

Jan Matejko (1862)

LEAD ANGULAR EXPERT AFTER ANNOUNCEMENTABOUT MOVING THE PROJECT TO REACT.JS

Page 30: Change Detection Anno Domini 2016

CLICK ME

Page 31: Change Detection Anno Domini 2016

26. <div style={style}></div>

15. }); 16. } 17. 18. render() { 19. const style = { 20. background: this.state.color, 21. }; 22. 23. return ( 24. <div> 25. <div style={style}></div>

27. <div style={style}></div> 28. <button style={styles} onClick={this.handleClick}>Click Me</button> 29. </div> 30. ); 31. } 32. } 33.

Page 32: Change Detection Anno Domini 2016

setState() -> generate whole new DOM

Page 33: Change Detection Anno Domini 2016

DOM CHANGES ARE COSTLY?

Page 34: Change Detection Anno Domini 2016

VIRTUALDOM

Page 35: Change Detection Anno Domini 2016
Page 36: Change Detection Anno Domini 2016
Page 37: Change Detection Anno Domini 2016
Page 38: Change Detection Anno Domini 2016

RECONCILATION (DIFF)

Page 39: Change Detection Anno Domini 2016

O(N3)1000 x 1000 x 1000

Page 40: Change Detection Anno Domini 2016

HEURISTIC

Page 41: Change Detection Anno Domini 2016

...RECONCILE EVERYTHING

9. Remove style color, Add style font-weight - difference

1. renderA: <div /> 2. renderB: <span /> 3. 4. Remove Node <div>, Insert Node <span> - full rerender 5. 6. renderA: <div style="{{color:red}}"/> 7. renderB: <div style="{{fontWeight:bold}}"/> 8.

10.

Page 42: Change Detection Anno Domini 2016

shouldComponentUpdate()LIGHTWEIGHT AS POSSIBLE

Page 43: Change Detection Anno Domini 2016

ANGULAR 2 ALSO HAS COMPONENT TREE

Page 44: Change Detection Anno Domini 2016
Page 45: Change Detection Anno Domini 2016
Page 46: Change Detection Anno Domini 2016

DEVELOPERS + ABSTRACTION = LOVE

Page 47: Change Detection Anno Domini 2016

OVER AND OVER

1. while (op) { 2. var getter = getterFor(op.fieldName); 3. 4. var oldValue = op.value; 5. var newValue = getter(op.context); 6. 7. if (oldValue != newValue) { 8. op.value = newValue; 9. 10. var fn = reconcilationFunctionFor(op); 11. fn(oldValue, newValue)

12. }

Page 48: Change Detection Anno Domini 2016

12. }

VM + ABSTRACTION = ...

Page 49: Change Detection Anno Domini 2016

MONOMORPHISM

Page 50: Change Detection Anno Domini 2016

POLIMORPHICAL STRUCTURE

10. checkWeapon(thor) 11. checkWeapon(cap)

1. function checkWeapon(hero) { 2. console.log(hero.weapon) 3. } 4. 5. // ... 6. 7. var thor = {weapon: 'hammer'} 8. var cap = {weapon: 'shield', citizenship: "America"} 9.

12.

Page 51: Change Detection Anno Domini 2016

CODE GENERATION FOR RESCUE

Page 52: Change Detection Anno Domini 2016

...JUST ON THIS SPECIFIC OBJECT

7. if(hammer != this.previousHammer){ 8. this.previousHammer = hammer; 9. this.heroComponent.hammer = hammer; 10. }

1. <hero [weapon]="thor.hammer"></hero> 2. 3. Class Thor_ChangeDetector { 4. detectChanges() { 5. var thor = obj.thor; 6. var hammer = thor.hammer

11. } 12. } 13.

Page 53: Change Detection Anno Domini 2016

3-10X FASTER

Page 54: Change Detection Anno Domini 2016

IMMUTABILITYNEWVALUE == OLDVALUE? :(

Page 55: Change Detection Anno Domini 2016

NEW OBJECT

9. x === y //false

1. var thor = {weapon: "hammer"} 2. var newThor = thor; 3. newThor.weapon = "shield" 4. x === y // true 5. 6. var ImmutableHero = Immutable.Record({ weapon: null }); 7. var thor = new ImmutableHero({ weapon: 'hammer'}); 8. var newThor = hero.set('weapon', 'shield');

10.

Page 56: Change Detection Anno Domini 2016

TOOLINGOBJECT.ASSIGN, IMMUTABLE.JS

Page 57: Change Detection Anno Domini 2016

ANGULAR METADATA

1. @Component({changeDetection:ChangeDetectionStrategy.OnPush}) 2. class ImmutableHammerCmp { 3. hammer:Hammer; 4. } 5.

Page 58: Change Detection Anno Domini 2016
Page 59: Change Detection Anno Domini 2016

PureRenderMixin

Page 60: Change Detection Anno Domini 2016

USE SHOULD COMPONENT UPDATE

5. this.shouldComponentUpdate = mx.shouldComponentUpdate.bind(this);

1. import mx from 'react-addons-pure-render-mixin'; 2. class FooComponent extends React.Component { 3. constructor(props) { 4. super(props);

6. } 7. 8. render() { 9. return <div className={this.props.className}>foo</div>; 10. } 11. } 12.

Page 61: Change Detection Anno Domini 2016

LAST BUT NOT LEAST... RX

Page 62: Change Detection Anno Domini 2016

DEFINE OBSERVABLES

1. @Component({selector:'weapon'}) 2. class ObservableHeroCmp { 3. weapon:ObservableWeapons ; 4. } 5.

Page 63: Change Detection Anno Domini 2016
Page 64: Change Detection Anno Domini 2016
Page 65: Change Detection Anno Domini 2016
Page 66: Change Detection Anno Domini 2016

WRAPPING UP

Page 67: Change Detection Anno Domini 2016
Page 68: Change Detection Anno Domini 2016
Page 69: Change Detection Anno Domini 2016
Page 70: Change Detection Anno Domini 2016

THANK YOUAND WAITING FOR QUESTIONS