Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Scaling React.js Applications

Scaling React.js Applications

Max Stoiber

July 04, 2016
Tweet

More Decks by Max Stoiber

Other Decks in Technology

Transcript

  1. Scaling React.js Applications
    Max Stoiber, @mxstbr
    Open Source Developer, Thinkmill

    View Slide

  2. @mxstbr

    View Slide

  3. KeystoneJS

    View Slide

  4. ElementalUI

    View Slide

  5. @mxstbr

    View Slide

  6. @mxstbr

    View Slide

  7. @mxstbr
    2. State Management
    3. Architecture
    1. What is Scalability?
    4. Performance

    View Slide

  8. @mxstbr
    2. State Management
    3. Architecture
    1. What is Scalability?
    4. Performance

    View Slide

  9. @mxstbr
    2. State Management
    3. Architecture
    1. What is Scalability?
    4. Performance

    View Slide

  10. @mxstbr

    View Slide

  11. @mxstbr

    View Slide

  12. @mxstbr

    View Slide

  13. @mxstbr
    Unidirectional Data Flow

    View Slide

  14. @mxstbr
    Store

    View Slide

  15. @mxstbr

    View Slide

  16. @mxstbr
    2. State Management
    3. Architecture
    1. What is Scalability?
    4. Performance

    View Slide

  17. @mxstbr
    Containers and Components

    View Slide

  18. @mxstbr
    Structure

    View Slide

  19. @mxstbr
    Traditionally grouped by type

    View Slide

  20. @mxstbr
    react-app-by-type
    !"" css
    !"" actions
    # $"" NavBarActions.js
    !"" containers
    # $"" NavBar.js
    !"" constants
    # $"" NavBarConstants.js
    !"" components
    # $"" App.js
    $"" reducers
    $"" NavBarReducer.js

    View Slide

  21. @mxstbr
    Group by feature instead

    View Slide

  22. @mxstbr
    react-app-by-feature
    !"" css
    !"" containers
    # $"" NavBar
    # !"" NavBar.js
    # !"" actions.js
    # !"" constants.js
    # $"" reducer.js
    $"" components
    $"" App.js

    View Slide

  23. @mxstbr
    Easy renaming and moving

    View Slide

  24. @mxstbr
    import { toggleNav } from ‘containers/NavBar/actions.js’;

    View Slide

  25. @mxstbr
    import { toggleNav } from ‘containers/PrimaryNav/actions.js’;

    View Slide

  26. @mxstbr
    Work in a single folder

    View Slide

  27. @mxstbr
    Reusable components

    View Slide

  28. @mxstbr
    Styling??

    View Slide

  29. @mxstbr
    .header {
    /* … */
    }
    .title {
    background-color: yellow;
    }
    .footer {
    /* … */
    }
    .title {
    border-color: blue;
    }
    Conflict!
    Naming

    View Slide

  30. @mxstbr
    CSS Modules

    View Slide

  31. @mxstbr
    import styles from ‘styles.css’;
    render() {
    return (
    className={styles.footer}
    />
    );
    }

    View Slide

  32. @mxstbr
    .footer { /* … */ }
    .title { /* … */ }
    .MyApp__footer__1co1k { /* … */ }
    .MyApp__title__2fgr5s { /* … */ }

    View Slide

  33. @mxstbr
    .header { line-height: 1.5em; }
    a { line-height: 1.5em; }
    .title { line-height: 1.5em; }
    Inheritance

    View Slide

  34. @mxstbr
    .header {
    line-height: 1.5em;
    }
    .title {
    line-height: 1.5em;
    }
    Inheritance
    .footer {
    line-height: 1em;
    }
    .title {
    line-height: 1em;
    }
    Conflict!

    View Slide

  35. @mxstbr
    Reset
    Header
    Title
    Global Reset
    Reset
    Header
    Local Reset
    Reset
    Title

    View Slide

  36. @mxstbr
    PostCSS

    View Slide

  37. @mxstbr
    PostCSS
    +
    postcss-autoreset

    View Slide

  38. @mxstbr
    .header { line-height: 1.5em; }
    a { line-height: default; }
    .title { line-height: default; }

    View Slide

  39. @mxstbr
    react-app-by-feature
    !"" containers
    # $"" NavBar
    # !"" NavBar.js
    # !"" actions.js
    # !"" constants.js
    # !"" styles.css
    # $"" reducer.js
    $"" components
    $"" App.js

    View Slide

  40. @mxstbr
    Component Isolation!

    View Slide

  41. @mxstbr
    Data Fetching??

    View Slide

  42. @mxstbr

    View Slide

  43. @mxstbr
    onStartClick={
    dipatch(startTimer())
    }
    />
    onStopClick={
    dispatch(showTime())
    }
    />

    View Slide

  44. @mxstbr
    redux-saga

    View Slide

  45. @mxstbr
    onStartClick={
    dipatch(startClicked())
    }
    />
    onStopClick={
    dispatch(stopClicked())
    }
    />

    View Slide

  46. @mxstbr
    function* connectClockToTimer() {
    while (true) {
    yield take(START_BUTTON_CLICKED);
    put(startTimer());
    yield take(STOP_BUTTON_CLICKED);
    put(stopTimer());
    put(showTimeOnClock());
    }
    }

    View Slide

  47. @mxstbr
    function* connectClockToTimer() {
    while (true) {
    yield take(START_BUTTON_CLICKED);
    put(startTimer());
    yield take(STOP_BUTTON_CLICKED);
    put(stopTimer());
    put(showTimeOnClock());
    }
    }

    View Slide

  48. @mxstbr
    function* connectClockToTimer() {
    while (true) {
    yield take(START_BUTTON_CLICKED);
    put(startTimer());
    yield take(STOP_BUTTON_CLICKED);
    put(stopTimer());
    put(showTimeOnClock());
    }
    }

    View Slide

  49. @mxstbr
    function* connectClockToTimer() {
    while (true) {
    yield take(START_BUTTON_CLICKED);
    put(startTimer());
    yield take(STOP_BUTTON_CLICKED);
    put(stopTimer());
    put(showTimeOnClock());
    }
    }

    View Slide

  50. @mxstbr
    function* connectClockToTimer() {
    while (true) {
    yield take(START_BUTTON_CLICKED);
    put(startTimer());
    yield take(STOP_BUTTON_CLICKED);
    put(stopTimer());
    put(showTimeOnClock());
    }
    }

    View Slide

  51. @mxstbr
    Decoupled Components

    View Slide

  52. @mxstbr
    2. Group files by feature
    3. Isolate Styling
    1. Containers and Components
    4. Use redux-saga

    View Slide

  53. @mxstbr
    2. State Management
    3. Architecture
    1. What is Scalability?
    4. Performance

    View Slide

  54. @mxstbr
    Webpack
    Code Splitting

    View Slide

  55. @mxstbr

    View Slide

  56. @mxstbr

    View Slide

  57. @mxstbr

    View Slide

  58. @mxstbr

    View Slide

  59. @mxstbr

    View Slide

  60. @mxstbr
    shouldComponentUpdate

    View Slide

  61. @mxstbr

    View Slide

  62. @mxstbr
    class NavBar extends React.Component {
    shouldComponentUpdate(nextProps) {
    ?????
    }
    }

    View Slide

  63. @mxstbr
    class NavBar extends React.Component {
    shouldComponentUpdate(nextProps) {
    return nextProps !== this.props;
    }
    }

    View Slide

  64. @mxstbr
    { “username”: “@mxstbr” } { “username”: “@mxstbr” }
    !==

    View Slide

  65. @mxstbr
    Deeply comparing objects
    is expensive

    View Slide

  66. @mxstbr
    ImmutableJS

    View Slide

  67. @mxstbr
    import { fromJS } from ‘immutable’;
    const state = fromJS({
    “username”: “@mxstbr”
    });

    View Slide

  68. @mxstbr
    .equals
    fromJS({ “username”: “@mxstbr” })
    fromJS({ “username”: “@mxstbr” })

    View Slide

  69. @mxstbr
    Deeply comparing objects
    is cheap!

    View Slide

  70. @mxstbr

    View Slide

  71. @mxstbr

    View Slide

  72. @mxstbr
    2. State Management
    3. Architecture
    1. What is Scalability?
    4. Performance

    View Slide

  73. Thanks for having me!
    Tweet comments/feedback to @mxstbr
    Come talk to me!

    View Slide