how - wordpress.com ·...

82
JACK TOLD US “WHY” SINGLE-PAGE APPS HOW

Upload: others

Post on 03-Jun-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

J A C K T O L D U S “ W H Y ”S I N G L E - PA G E A P P S

H O W

Page 2: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

N I K O L A Y B A C H I Y S K I , A U T O M A T T I C , W O R D C A M P V I E N N A , A P R I L 1 1 , 2 0 1 5

Page 3: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

A U T O M A T T I CE X T R A P O L A T E . M E@ N I K O L A Y B

Page 4: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

F A S T E R

Page 5: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

M O R E E N G A G I N G

Page 6: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})
Page 7: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

C H A N G EL E T ' S TA L K A B O U T

Page 8: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})
Page 9: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

S T A T EL E T ' S TA L K A B O U T

Page 10: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})
Page 11: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})
Page 12: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

O L D - S C H O O L V S .

S I N G L E - P A G E A P P S

Page 13: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

O L D S C H O O L

Page 14: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

C H A N G E ⇒ R E F R E S H

O L D - S C H O O L

Page 15: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

C H A N G E ⇒

S I N G L E - P A G E

Page 16: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})
Page 17: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})
Page 18: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

U I L I B R A R Y

Page 19: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

N O T A F R A M E W O R K

Page 20: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

var  Post  =  React.createClass(  {      function  render()  {          return  (              <div  className="post">                  <p  className="content">                      {  this.props.post.content  }                  </p>                  <PostMeta  post={  this.props.post  }  />              </div>          );      }  }  );  

Page 21: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

var  Post  =  React.createClass(  {      function  render()  {          return  (              <div  className="post">                  <p  className="content">                      {  this.props.post.content  }                  </p>                  <PostMeta  post={  this.props.post  }  />              </div>          );      }  }  );   J S X

Page 22: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

var  Post  =  React.createClass(  {      function  render()  {          return  (              React.DOM.div(                  {className:  'post'},                  [  React.DOM.p(                          null,                          this.props.post.content                      ),                      PostMeta(  {post:  this.props.post}  )              );        );      }  }  );  

Page 23: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

var  Post  =  React.createClass(  {      function  render()  {          return  (              <div  className="post">                  <p  className="content">                      {  this.props.post.content  }                  </p>                  <PostMeta  post={  this.props.post  }  />              </div>          );      }  }  );

Page 24: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

var  PostMeta  =  React.createClass(  {      function  getInitialState()  {          return  {  hidden:  true  };      },      function  onToggle()  {          this.setState(  {  hidden:  !  this.state.hidden  }  );      },      function  render()  {          return  (              <div  className="meta">                  {  this.props.post.author  }                  <button  onClick={  this.onToggle  }>                      {  this.state.hidden  ?  'More'  :  'Hide'  }                  </button>                  (  this.state.hidden  ?                          <p>…extra  meta…</p>  :                          null                  )              </div>          );      }  }  );

Page 25: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

var  PostMeta  =  React.createClass(  {      function  getInitialState()  {          return  {  hidden:  true  };      },      function  onToggle()  {          this.setState(  {  hidden:  !  this.state.hidden  }  );      },      function  render()  {          return  (              <div  className="meta">                  {  this.props.post.author  }                  <button  onClick={  this.onToggle  }>                      {  this.state.hidden  ?  'More'  :  'Hide'  }                  </button>                  (  this.state.hidden  ?                          <p>…extra  meta…</p>  :                          null                  )              </div>          );      }  }  );

Page 26: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

var  PostMeta  =  React.createClass(  {      function  getInitialState()  {          return  {  hidden:  true  };      },      function  onToggle()  {          this.setState(  {  hidden:  !  this.state.hidden  }  );      },      function  render()  {          return  (              <div  className="meta">                  {  this.props.post.author  }                  <button  onClick={  this.onToggle  }>                      {  this.state.hidden  ?  'More'  :  'Hide'  }                  </button>                  (  this.state.hidden  ?                          <p>…extra  meta…</p>  :                          null                  )              </div>          );      }  }  );

Page 27: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

var  PostMeta  =  React.createClass(  {      function  getInitialState()  {          return  {  hidden:  true  };      },      function  onToggle()  {          this.setState(  {  hidden:  !  this.state.hidden  }  );      },      function  render()  {          return  (              <div  className="meta">                  {  this.props.post.author  }                  <button  onClick={  this.onToggle  }>                      {  this.state.hidden  ?  'More'  :  'Hide'  }                  </button>                  (  this.state.hidden  ?                          <p>…extra  meta…</p>  :                          null                  )              </div>          );      }  }  );

R E - R E N D E R S

Page 28: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

C O M P O N E N T SL E T ' S TA L K A B I T M O R E A B O U T

Page 29: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

C O M P O S A B L E

Page 30: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

<MasterBar>      <UserGreeting  user="…">          <Avatar  login={  this.props.user.login  }  />          Howdy,  {  this.props.user.nickname  }          <LogOutLink  id={  this.props.user.id  }  />      </UserGreeting>  </MasterBar>

Page 31: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

B U I L D I N G B L O C K S O F O U R A P P L I C A T I O N

Page 32: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

<MasterBar  />  <MastHead  />  <Navigation  active="archive"  />  <Posts  date="2015-­‐04-­‐01"  author="crumb">      <Post>          …      </Post>      <Post>          …      </Post>      …  </Posts>

Page 33: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

<MasterBar  />  <MastHead  />  <Posts  date="2015-­‐04-­‐01"  author="crumb">      <Post  post="…">          <p  class="content">              {  this.props.post.content}          </p>          <PostMeta  post="…"  />      </Post>      <Post>      …      </Post>      …  </Posts>

Page 34: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})
Page 35: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

T E S T A B L E

Page 36: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

P R E V E N T S X S S

Page 37: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

<p>{  this.props.content  }</p>

<img  src="javascript:alert('XSS');">

&lt;img  src=&quot;javascript:alert(&#39;XSS&#39;);&quot;&gt;

Page 38: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

<p  dangerouslySetInnerHTML={{  __html:  this.props.content  }}  />

Page 39: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})
Page 40: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

N O T T E M P L A T E S

Page 41: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

<div  class="posts">      {{#each  posts}}          <div  class="post">              {{#if  author}}          </div>      {{/each}}  </div>

Page 42: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

R E U S A B L E

Page 43: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

<Comment>      <Avatar  email={  this.props.comment.author.email}  />      …  </Comment>

Page 44: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

<PostMeta>      <Avatar  email={  this.props.comment.author.email}  />      …  </PostMeta>

Page 45: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

W A I T !

Page 46: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

K E E P L O G I C A N D M A R K U P…A P O P U L A R B E S T P R A C T I C E S A Y S …

Page 47: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

… S E P A R A T E !

Page 48: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

S E P A R A T I O N O F C O N C E R N S I S G O O D , R I G H T ?

Page 49: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

W H E N D O W E N E E D A N E V E N T H A N D L E R W I T H O U T T H E D O M E L E M E N T I T I S B O U N D T O ?

onClick()

<button>

Page 50: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

W H E N D O W E N E E D A D O M E L E M E N T W I T H O U T T H E E V E N T H A N D L E R S F O R I T S A C T I O N S ?

onClick()

<button>

Page 51: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

H T M L

Page 52: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

D I S P L A Y L O G I C

Page 53: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

T H E S A M E C O N C E R N

Page 54: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

H T M LJ S

Page 55: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

T H E S A M E C O N C E R N

Page 56: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})
Page 57: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})
Page 58: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})
Page 59: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

R E - R E N D E R I N G

Page 60: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})
Page 61: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})
Page 62: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

V I R T U A L D O M

Page 63: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

0 . R U N render()

O N E V E R Y U P D A T E

Page 64: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

1 . D I F F W I T H P R E V I O U S T R E E

O N E V E R Y U P D A T E

Page 65: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

http://calendar.perfplanet.com/2013/diff/

Page 66: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

2 . C O M P U T E M I N I M U M S E T O F D O M C H A N G E S

O N E V E R Y U P D A T E

Page 67: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

3 . B A T C H - E X E C U T E A L L D O M U P D A T E S

O N E V E R Y U P D A T E

Page 68: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

V I R T U A L D O M : N O T O N L Y S P E E D !

Page 69: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

S E R V E R - S I D E R E N D E R I N G

Page 70: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

S V G , V M L , C A N V A S

Page 71: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

R U N N I N G I N A W E B W O R K E R

Page 72: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})
Page 73: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})
Page 74: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

F L U Xhttps://facebook.github.io/flux/

http://blog.andrewray.me/flux-for-stupid-people/

https://scotch.io/tutorials/getting-to-know-flux-the-react-js-architecture

Page 75: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

N O T A F R A M E W O R K

Page 76: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

A R C H I T E C T U R E B L U E P R I N T

Page 77: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

L E T ' S C H A T

Page 78: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

S U M M A R Y

Page 79: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

C O M P O N E N T S , N O T T E M P L A T E S

Page 80: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

R E - R E N D E R , D O N ' T T O U C H

T H E D O M

Page 81: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

V I R T U A L D O M I S S I M P L E , F A S T , F U N

L E T ' S TA L K A B O U T

Page 82: HOW - WordPress.com · varPost=React.createClass({functionrender(){return(React.DOM.div({className:'post'}, [React.DOM.p(null, this.props.post.content), PostMeta({post:this.props.post})

Q U E S T I O N S ? @ N I K O L A Y B