render to dom

127
from render() to DOM Boris Dinkevich [email protected]

Upload: 500tech

Post on 21-Jan-2017

185 views

Category:

Engineering


2 download

TRANSCRIPT

Page 1: Render to DOM

from

render() to

DOM

Boris Dinkevich [email protected]

Page 2: Render to DOM

COMPLICATEDBAD ARCHITECTURE OPTIMISATIONS

Page 3: Render to DOM

Boris Dinkevich

- React evangelist - Cat aficionado - Co-Author of “The complete Redux book”

Co-Founder @ 500Tech

Page 4: Render to DOM

A WORD ON TREES

Page 5: Render to DOM

Our code today

const Todos = () => ( <ul> <li>Todo</li> </ul>);

Page 6: Render to DOM

De-JSX

const Todos = () => ( <ul> <li>Stuff</li> </ul>);

const Todos = () => ( React.createElement("ul", null, React.createElement("li", null, "Stuff" ), ); );

Page 7: Render to DOM

Chrome dev tools?

Page 8: Render to DOM

WHY REACT?

Page 9: Render to DOM

DOM is slowLets minimise writes…

Page 10: Render to DOM

Our Sample App

TodosHeader

TodoTodo

App

Page 11: Render to DOM

Tree & DOM

TodosHeader

“div”

“Welcome”

“h1”

“div”

Todo

“Two”

“li”

“ul”

Todo

“One”

“li”

“div”

“Welcome”

“h1”

“div”

“Two”

“li”

“ul”

“One”

“li”

Our tree Our DOM

App

Page 12: Render to DOM

Introducing BorisJS!1.Call render() to build tree - ”Future Tree”

2.Compare each element to DOM

3.Change when needed

4.Win!

Page 13: Render to DOM

React docs: “reads are slow”Lets open PR

Page 14: Render to DOM

Simple diff

function updateNode(node, value) { if (node.innerText !== value) { node.innerText = value; } }

Page 15: Render to DOM

60fpsTime per frame: 16.6ms

Time for 1000 read / write cycles: 36.15ms

Page 16: Render to DOM

Read & Write

Read then Write

Page 17: Render to DOM

Introducing BorisJS 2.01.Call render() to build tree

2.Read DOM into temp tree - “Current Tree" 3.Compare each element to temp tree

4.Change when needed

5.Win!

“temp tree”… sounds familiar

Page 18: Render to DOM

Pre cache1. Call render() to build “Future Tree”

2. Compare each element to “Current Tree“

3. Change DOM when needed

4.Save “Future Tree” as “Current Tree” 5. Win!

What about first “Current Tree”?

Page 19: Render to DOM

Introducing BorisJS 3.0Initial Render

1.Call render() to build tree

2.Save as “Current Tree” 3.Create initial DOM

Updates

1.Call render() to build “Future Tree”

2.Compare each element to “Current Tree” 4.Change DOM when needed

5.Save “Future Tree” as “Current Tree”

6.Win!

Page 20: Render to DOM

NO READS?

Page 21: Render to DOM

Todos.setState({ todos: [’Uno’, ‘Two’] });

Todos• One • Two

Todos• Uno • Two

Page 22: Render to DOM

todos = document.getElementById('app').children[0].children[1]; todos.removeChild(todos.childNodes[0]);

Todos.setState({ todos: [‘Uno’, ‘Dos’] });

Todos• Dos

Todos• One • Two

Todos• Two

Page 23: Render to DOM
Page 24: Render to DOM

I LiedGet <input /> values?

Page 25: Render to DOM

In React• Initial Render

• Updates

Page 26: Render to DOM

FIRST RUN

Page 27: Render to DOM

React.createElement(App);

Starting

Page 28: Render to DOM

function Todos()

function Header()

“div”

“Welcome”

“h1”

“div”

function Todo()

“Two”

“li”

“ul

function Todo()

“One”

“li”

function App()

Mounting markup

Page 29: Render to DOM

function Todos()

function Header()

“div”

“Welcome”

“h1”

“div”

function Todo()

“Two”

“li”

“ul

function Todo()

“One”

“li”

function App()

Mounting markup

Page 30: Render to DOM

function Todos()

function Header()

“div”

“Welcome”

“h1”

“div”

function Todo()

“Two”

“li”

“ul

function Todo()

“One”

“li”

function App()

“Welcome”

“h1”

“div”

Mounting markup

Page 31: Render to DOM

function Todos()

function Header()

“div”

“Welcome”

“h1”

“div”

function Todo()

“Two”

“li”

“ul

function Todo()

“One”

“li”

function App()

“Welcome”

“h1”

“div”

Mounting markup

Page 32: Render to DOM

function Todos()

function Header()

“div”

“Welcome”

“h1”

“div”

function Todo()

“Two”

“li”

“ul

function Todo()

“One”

“li”

function App()

“Welcome”

“h1”

“div”

“One”

“li”

Mounting markup

Page 33: Render to DOM

function Todos()

function Header()

“div”

“Welcome”

“h1”

“div”

function Todo()

“Two”

“li”

“ul

function Todo()

“One”

“li”

function App()

“Welcome”

“h1”

“div”

“One”

“li”

Mounting markup

Page 34: Render to DOM

function Todos()

function Header()

“div”

“Welcome”

“h1”

“div”

function Todo()

“Two”

“li”

“ul

function Todo()

“One”

“li”

function App()

“Welcome”

“h1”

“div”

“Two”

“li”

“One”

“li”

Mounting markup

Page 35: Render to DOM

function Todos()

function Header()

“div”

“Welcome”

“h1”

“div”

function Todo()

“Two”

“li”

“ul

function Todo()

“One”

“li”

function App()

“Welcome”

“h1”

“div”

“Two”

“li”

“ul”

“One”

“li”

Mounting markup

Page 36: Render to DOM

function Todos()

function Header()

“div”

“Welcome”

“h1”

“div”

function Todo()

“Two”

“li”

“ul

function Todo()

“One”

“li”

function App()

“Welcome”

“h1”

“div”

“Two”

“li”

“ul”

“One”

“li”

Mounting markup

“div”

Page 37: Render to DOM

“div”

“Welcome”

“h1”

“div”

“Two”

“li”

“ul”

“One”

“li”

#app

markup

<body> <div id="app"></div></body>

render( React.createElement(App), document.getElementById('app') );

Page 38: Render to DOM

DOM IS READY!Or is it?

Page 39: Render to DOM

DOM and React

Page 40: Render to DOM

Event Handers

<Component onClick={} />

Page 41: Render to DOM

Connection

React

onClick

DOM

React DOM

Our Code

Page 42: Render to DOM

Different renderersDOM - onClick

Native - onPress

Page 43: Render to DOM

What does this mean?

<Header onClick={} />

<Header onPress={} />

Page 44: Render to DOM
Page 45: Render to DOM

What is “React”?

addons 1,334 isomorphic 3,428 shared 7,058

renderers/ art 641 dom 12,337 native 2,735 noop 192 shared 9,368

* lines of code in 15-stable

Page 46: Render to DOM

TREE UPDATE

Page 47: Render to DOM

What will cause React to render again?• setState()

• forceUpdate()

Page 48: Render to DOM

function Todos()

“div”

function Todo()

{ title }

“li”

“ul”

function Todo()

{ title }

“li”

function App()

“div”

“Two”

“li”

“ul”

“One”

“li”

“div”

“Two”

“li”

“ul”

“One”

“li”

DOMReact Tree prev Virtual DOM

Page 49: Render to DOM

Todos.setState({ todos: ['Uno', 'Dos'] });

Page 50: Render to DOM

function Todos()

“div”

function Todo()

{ title }

“li”

“ul”

function Todo()

{ title }

“li”

function App()

“div”

“Two”

“li”

“ul”

“One”

“li”

“div”

“Two”

“li”

“ul”

“One”

“li”

DOMReact Tree prev Virtual DOM

Page 51: Render to DOM

function Todos()

“div”

function Todo()

{ title }

“li”

“ul”

function Todo()

{ title }

“li”

function App()

“div”

“Two”

“li”

“ul”

“One”

“li”

“div”

“Two”

“li”

“ul”

“One”

“li”

DOMReact Tree prev Virtual DOM

Page 52: Render to DOM

function Todos()

“div”

function Todo()

{ title }

“li”

“ul”

function Todo()

{ title }

“li”

function App()

“div”

“Two”

“li”

“ul”

“One”

“li”

“div”

“Two”

“li”

“ul”

“One”

“li”

DOMReact Tree prev Virtual DOM

‘UNO’ ‘DOS’

Page 53: Render to DOM

function Todos()

“div”

function Todo()

{ title }

“li”

“ul”

function Todo()

{ title }

“li”

function App()

“div”

“Two”

“li”

“ul”

“One”

“li”

“div”

“Two”

“li”

“ul”

“One”

“li”

DOMReact Tree prev Virtual DOM

‘UNO’ ‘DOS’

Page 54: Render to DOM

function Todos()

“div”

function Todo()

{ title }

“li”

“ul”

function Todo()

{ title }

“li”

function App()

“div”

“Two”

“li”

“ul”

“One”

“li”

“div”

“Two”

“li”

“ul”

“One”

“li”

DOMReact Tree prev Virtual DOM

‘UNO’ ‘DOS’

Page 55: Render to DOM

function Todos()

“div”

function Todo()

{ title }

“li”

“ul”

function Todo()

{ title }

“li”

function App()

“div”

“Two”

“li”

“ul”

“One”

“li”

“div”

“Two”

“li”

“ul”

“Uno”

“li”

DOMReact Tree prev Virtual DOM

‘UNO’ ‘DOS’

Page 56: Render to DOM

function Todos()

“div”

function Todo()

{ title }

“li”

“ul”

function Todo()

{ title }

“li”

function App()

“div”

“Two”

“li”

“ul”

“Uno”

“li”

“div”

“Two”

“li”

“ul”

“Uno”

“li”

DOMReact Tree prev Virtual DOM

‘UNO’ ‘DOS’

Page 57: Render to DOM

function Todos()

“div”

function Todo()

{ title }

“li”

“ul”

function Todo()

{ title }

“li”

function App()

“div”

“Two”

“li”

“ul”

“Uno”

“li”

“div”

“Two”

“li”

“ul”

“Uno”

“li”

DOMReact Tree prev Virtual DOM

‘UNO’ ‘DOS’

Page 58: Render to DOM

function Todos()

“div”

function Todo()

{ title }

“li”

“ul”

function Todo()

{ title }

“li”

function App()

“div”

“Two”

“li”

“ul”

“Uno”

“li”

“div”

“Two”

“li”

“ul”

“Uno”

“li”

DOMReact Tree prev Virtual DOM

‘UNO’ ‘DOS’

Page 59: Render to DOM

function Todos()

“div”

function Todo()

{ title }

“li”

“ul”

function Todo()

{ title }

“li”

function App()

“div”

“Two”

“li”

“ul”

“Uno”

“li”

“div”

“Two”

“li”

“ul”

“Uno”

“li”

DOMReact Tree prev Virtual DOM

‘UNO’ ‘DOS’

Page 60: Render to DOM

function Todos()

“div”

function Todo()

{ title }

“li”

“ul”

function Todo()

{ title }

“li”

function App()

“div”

“Two”

“li”

“ul”

“Uno”

“li”

“div”

“Dos”

“li”

“ul”

“Uno”

“li”

DOMReact Tree prev Virtual DOM

‘UNO’ ‘DOS’

Page 61: Render to DOM

function Todos()

“div”

function Todo()

{ title }

“li”

“ul”

function Todo()

{ title }

“li”

function App()

“div”

“Dos”

“li”

“ul”

“Uno”

“li”

“div”

“Dos”

“li”

“ul”

“Uno”

“li”

DOMReact Tree prev Virtual DOM

‘UNO’ ‘DOS’

Page 62: Render to DOM

function Todos()

“div”

function Todo()

{ title }

“li”

“ul”

function Todo()

{ title }

“li”

function App()

“div”

“Dos”

“li”

“ul”

“Uno”

“li”

“div”

“Dos”

“li”

“ul”

“Uno”

“li”

DOMReact Tree prev Virtual DOM

‘UNO’ ‘DOS’

Page 63: Render to DOM

function Todos()

“div”

function Todo()

{ title }

“li”

“ul”

function Todo()

{ title }

“li”

function App()

“div”

“Dos”

“li”

“ul”

“Uno”

“li”

“div”

“Dos”

“li”

“ul”

“Uno”

“li”

DOMReact Tree prev Virtual DOM

‘UNO’ ‘DOS’

Page 64: Render to DOM

function Todos()

“div”

function Todo()

{ title }

“li”

“ul”

function Todo()

{ title }

“li”

function App()

“div”

“Dos”

“li”

“ul”

“Uno”

“li”

“div”

“Dos”

“li”

“ul”

“Uno”

“li”

DOMReact Tree prev Virtual DOM

‘UNO’ ‘DOS’

Page 65: Render to DOM

Flow1. setState({ todos: [‘Uno’, ‘Dos’] });

2. Todos updated and rendering starts

3. Todo1 needs update

4. DOM updated

5. Todo2 needs update

6. DOM updated

Page 66: Render to DOM

AGAIN?

Page 67: Render to DOM

Todos.setState({ todos: ['Uno', 'Dos'] });

Page 68: Render to DOM

function Todos()

“div”

function Todo()

{ title }

“li”

“ul”

function Todo()

{ title }

“li”

function App()

“div”

“Dos”

“li”

“ul”

“Uno”

“li”

“div”

“Dos”

“li”

“ul”

“Uno”

“li”

DOMReact Tree prev Virtual DOM

Page 69: Render to DOM

function Todos()

“div”

function Todo()

{ title }

“li”

“ul”

function Todo()

{ title }

“li”

function App()

“div”

“Dos”

“li”

“ul”

“Uno”

“li”

“div”

“Dos”

“li”

“ul”

“Uno”

“li”

DOMReact Tree prev Virtual DOM

Page 70: Render to DOM

function Todos()

“div”

function Todo()

{ title }

“li”

“ul”

function Todo()

{ title }

“li”

function App()

“div”

“Dos”

“li”

“ul”

“Uno”

“li”

“div”

“Dos”

“li”

“ul”

“Uno”

“li”

DOMReact Tree prev Virtual DOM

‘UNO’ ‘DOS’

Page 71: Render to DOM

function Todos()

“div”

function Todo()

{ title }

“li”

“ul”

function Todo()

{ title }

“li”

function App()

“div”

“Dos”

“li”

“ul”

“Uno”

“li”

“div”

“Dos”

“li”

“ul”

“Uno”

“li”

DOMReact Tree prev Virtual DOM

‘UNO’ ‘DOS’

Page 72: Render to DOM

function Todos()

“div”

function Todo()

{ title }

“li”

“ul”

function Todo()

{ title }

“li”

function App()

“div”

“Dos”

“li”

“ul”

“Uno”

“li”

“div”

“Dos”

“li”

“ul”

“Uno”

“li”

DOMReact Tree prev Virtual DOM

‘UNO’ ‘DOS’

Page 73: Render to DOM

function Todos()

“div”

function Todo()

{ title }

“li”

“ul”

function Todo()

{ title }

“li”

function App()

“div”

“Dos”

“li”

“ul”

“Uno”

“li”

“div”

“Dos”

“li”

“ul”

“Uno”

“li”

DOMReact Tree prev Virtual DOM

‘UNO’ ‘DOS’

Page 74: Render to DOM

LIFE CYCLE

Page 75: Render to DOM

function Todos()

“div”

function Todo()

{ title }

“li”

“ul”

function Todo()

{ title }

“li”

function App()

React Tree

componentWillMount componentDidMount componentWillUpdate componentDidUpdate componentWillUnmount …

Page 76: Render to DOM

MULTIPLE UPDATES

Page 77: Render to DOM

Multiple setState calls

Todos.setState({ todos: [‘Uno’, ‘Dos’] }); App.setState({ title: ‘Bye’ }); Todos.setState({ todos: [‘Raz’, ‘Dva’] });

Page 78: Render to DOM

How many render() ?

App()

Todos()

Todos()

Todos()

Todo()

App()

Page 79: Render to DOM

How many render() ?

App()

Todos()

Todos()

Todos()

Todo()

App()

Page 80: Render to DOM

How many render() ?

App()

Todos()

Todos()

Todos()

Todo()

App()

Page 81: Render to DOM

How many render() ?

App()

Todos()

Todos()

Todos()

Todo()

App() 0

1

1

Page 82: Render to DOM

How many render() ?

App()

Todos()

Todos()

Todos()

Todo()

App() 0

1

1

Page 83: Render to DOM

How many render() ?

App()

Todos()

Todos()

Todos()

Todo()

App() 1

1

1

Page 84: Render to DOM

How many render() ?

App()

Todos()

Todos()

Todos()

Todo()

App() 1

2

1

Page 85: Render to DOM

How many render() ?

App()

Todos()

Todos()

Todos()

Todo()

App() 1

2

2

Page 86: Render to DOM

How many render() ?

App()

Todos()

Todos()

Todos()

Todo()

App() 1

2

2

Page 87: Render to DOM

How many render() ?

App()

Todos()

Todos()

Todos()

Todo()

App() 1

3

2

Page 88: Render to DOM

How many render() ?

App()

Todos()

Todos()

Todos()

Todo()

App() 1

3

3

Page 89: Render to DOM

How many render() ?

App()

Todos()

Todos()

Todos()

Todo()

App() 1

3

3

Page 90: Render to DOM

transactions

Page 91: Render to DOM

How do we group?

Todos.setState({ todos: [‘Uno’, ‘Dos’] }); App.setState({ title: ‘Bye’ }); Todos.setState({ todos: [‘Raz’, ‘Dva’] });

Page 92: Render to DOM

Callback

Before

After

Transaction

Page 93: Render to DOM

Callback

Before

After

• Prepare

• Calculate final state • Update DOM • Run Callbacks

Transaction

• multiple setState() • Build list of changes

Page 94: Render to DOM

Todos

dirtyComponents

Todos.setState({ todos: [‘Uno’, ‘Dos’] });

{ todos: [‘Uno’, ‘Dos’] }

Page 95: Render to DOM

App

dirtyComponents

Todos.setState({ todos: [‘Uno’, ‘Dos’] }); App.setState({ title: ‘Bye’ });

{ todos: [‘Uno’, ‘Dos’] }

Todos

{ title: ‘Bye’ }

Page 96: Render to DOM

dirtyComponents

Todos.setState({ todos: [‘Uno’, ‘Dos’] }); App.setState({ title: ‘Bye’ }); Todos.setState({ todos: [‘Raz’, ‘Dva’] });

{ todos: [‘Uno’, ‘Dos’] } { todos: [‘Raz’, ‘Dva’] }

Todos

{ title: ‘Bye’ }

App

Page 97: Render to DOM

Finalize Transaction

Page 98: Render to DOM

How many render() ?

App()

Todos()

Todos()

Todo()

App() 0

0

0

Page 99: Render to DOM

How many render() ?

App()

Todos()

Todos()

Todo()

App() 0

0

0

Page 100: Render to DOM

How many render() ?

App()

Todos()

Todos()

Todo()

App() 0

0

0

Update the state to it’s latest version

Page 101: Render to DOM

How many render() ?

App()

Todos()

Todos()

Todo()

App() 0

1

0

Page 102: Render to DOM

How many render() ?

App()

Todos()

Todos()

Todo()

App() 0

1

1

Page 103: Render to DOM

How many render() ?

App()

Todos()

Todos()

Todo()

App() 0

1

1

Page 104: Render to DOM

How many render() ?

App()

Todos()

Todos()

Todo()

App() 0

1

1

Page 105: Render to DOM

How many render() ?

App()

Todos()

Todos()

Todo()

App() 0

1

1

Update the state

Page 106: Render to DOM

How many render() ?

App()

Todos()

Todos()

Todo()

App() 1

1

1

Page 107: Render to DOM

How many render() ?

App()

Todos()

Todos()

Todo()

App() 1

1

1

New props from App?

Page 108: Render to DOM

How many render() ?

App()

Todos()

Todos()

Todo()

App() 1

2

1

Page 109: Render to DOM

How many render() ?

App()

Todos()

Todos()

Todo()

App() 1

2

2

Page 110: Render to DOM

WAIT A MINUTE…

Page 111: Render to DOM

SORT BY ORDERSet order as components are mounted

Page 112: Render to DOM

How many render() ?

App()

Todos()

Todos()

Todo()

App() 0

0

0

Page 113: Render to DOM

How many render() ?

App()

Todos()Todos()

Todo()

App() 0

0

0

Page 114: Render to DOM

How many render() ?

App()

Todos()Todos()

Todo()

App() 0

0

0

Page 115: Render to DOM

How many render() ?

App()

Todos()Todos()

Todo()

App() 0

0

0

Update the state

Page 116: Render to DOM

How many render() ?

App()

Todos()Todos()

Todo()

App() 1

0

0

Page 117: Render to DOM

How many render() ?

App()

Todos()Todos()

Todo()

App() 1

0

0

Update the state

Page 118: Render to DOM

How many render() ?

App()

Todos()Todos()

Todo()

App() 1

1

0

Page 119: Render to DOM

How many render() ?

App()

Todos()Todos()

Todo()

App() 1

1

1

Page 120: Render to DOM

How many render() ?

App()

Todos()Todos()

Todo()

App() 1

1

1

Page 121: Render to DOM

How many render() ?

App()

Todos()Todos()

Todo()

App() 1

1

1

Page 122: Render to DOM

Callback order in transaction

Todos.setState({ todos: [‘Uno’, ‘Dos’] }); App.setState({ title: ‘Bye’ }); Todos.setState({ todos: [‘Raz’, ‘Dva’] });

1. App setState 2. Todos setState 3. Todos setState

Callbacks order

Page 123: Render to DOM

Transactions In ReactPreserving input selection

Suppressing events during DOM work

Collecting “componentDidUpdate”

etc

Page 124: Render to DOM

FINAL WORDS

Page 125: Render to DOM

REACT IS COMPLICATED SO YOUR CODE DOES’T HAVE TO BE

Page 126: Render to DOM

http://redux-book.com

The Complete Redux Book

Page 127: Render to DOM

And read our blog:http://blog.500tech.com

Don’t <React />, Plan!