frontend at scale
play

FRONTEND AT SCALE Designing abstractions for big teams @joshduck - PowerPoint PPT Presentation

FRONTEND AT SCALE Designing abstractions for big teams @joshduck What front-end abstractions have we built? And how did we do it? Server rendered desktop site Less memory, bandwidth, and latency Device constraints More products Multiple


  1. FRONTEND AT SCALE Designing abstractions for big teams @joshduck

  2. What front-end abstractions have we built? And how did we do it?

  3. Server rendered desktop site

  4. Less memory, bandwidth, and latency

  5. Device constraints × More products × Multiple platforms × Product depth Lots of complexity

  6. Product UI Product code Business logic UI rendering Web framework Common Runtimes infrastructure Data storage Hardware

  7. Common infrastructure Products teams can focus on products We can chase long tail of optimizations Knowledge is transferable Shared tooling and processes

  8. The right solution changes over time

  9. Specialize

  10. Specialize Simplify

  11. Specialize Simplify Replace

  12. Server rendering Goal: Turn data into markup Medium: Strings and concatenation

  13. String escaping HTML syntax echo "<div class=\"dashboard-box\"> 
 Hello, $name. 
 </div>"; 
 Cross-site scripting HTML tags

  14. Object composition is better than string concatenation $welcome = new UIDashboard(); 
 $welcome->setTitle('Hello, ' . $name); 
 $welcome->setIcon('event'); 
 $welcome->setContent($body); 
 echo $welcome->render();

  15. XHP is a DSL for components $welcome = 
 <dashboard title={"Hello, $name"}> 
 {$body} 
 <button use="primary" /> 
 </dashboard>; 
 


  16. XHP is a DSL for components $welcome = 
 <dashboard title={"Hello, $name"}> 
 {$body} 
 <button use="primary" /> 
 </dashboard>; 
 


  17. It's XHP all the way down 🐣 class :dashboard { 
 function render() { 
 return 
 <card> 
 <icon type={$this->icon} /> 
 <div>{$this->:title}</div> 
 </card>; 
 } 
 }

  18. Components are a massive win for code quality They encourage engineers to create decoupled, reusable units of code

  19. The pit of success

  20. Retrofitting async rendering class :dashboard implements AsyncXHP { 
 async function render() { 
 $text = await getDashboard($this->:id); 
 return <card>{$data->text}</card>; 
 } 
 }

  21. A declarative interface leaves the door open for future changes

  22. Client rendering Goal: Synchronizing state with a UI Medium: DOM nodes and APIs

  23. {liked: } false

  24. {liked: } true

  25. {liked: } false

  26. Bookkeeping DOM APIs var liked = false; 
 var like = container.children[0]; 
 var unlike = container.children[1]; 
 
 container.addEventListener('click', (e) => { liked = !liked; 
 like.style.display = liked ? 'none' : 'block'; 
 unlike.style.display = liked ? 'block' : 'none'; 
 }); Browser compatibility

  27. jQuery simplifies the DOM APIs $('.like-button').click(function() { 
 $(container).find('.like').toggle(); 
 $(container).find('.unlike').toggle(); 
 });

  28. Initial render and updates share an API class LikeButton extends React.Component { 
 render() { 
 return this.state.liked ? 
 <Button label ="Like" onClick ={...} /> 
 <Button label ="Unlike" onClick ={...} /> 
 } 
 }

  29. Good infra doesn't come from building in isolation

  30. Work directly with product teams to understand their needs

  31. Iterating on a core library is really, really hard Minimize public interfaces Update call sites alongside infra changes Use tooling to automate changes Deprecate, log, and monitor

  32. React has gone places we never expected

  33. State management Goal: Handling application state changes in a predictable way Medium: Object mutation and events

  34. Stores Views Dispatcher

  35. Alt Delorean Fluxy Material Flux Flummox Reflux Fluxible McFly OmniscientJS MartyJS Lux Flux This Fluxxor

  36. Flux and Redux are still imperative Simplified mutations and events, but didn't replace them We couldn't iterate on implementation

  37. Relay is a new approach to data management function Product(props) { return <li>{props.name} (AUD {props.price}) </li>; 
 } 
 
 Relay.createContainer(Product, { 
 product: ` 
 fragment { 
 name, 
 price, 
 } 
 `, 
 }); 


  38. Declarative Immutable Automated data fetching No manual object mutations Static analysis

  39. Declarative code and static analysis play well together Extract data requirements as a build step Fetch data without running JavaScript Not possible with imperative code

  40. Strings XHP DOM APIs jQuery React Ad hoc Flux Relay

  41. Clearly define the problem space

  42. Understand products' needs Start by working directly with a team You should be writing product code

  43. Plan to iterate Build an escape hatch Support incremental adoption Iterate on the abstraction

  44. Steal ideas that work One way data flow Declarative interfaces Immutability Functional programming Static analysis

  45. Thank you @joshduck

Recommend


More recommend