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

Reactのパフォーマンスを改善する必要がなかった話

 Reactのパフォーマンスを改善する必要がなかった話

現在開発中の自社製品に対し、パフォーマンスを初めて意識した際にまだ特に大きく改善する点が見当たらなかったというだけの話

teamspirit_minato

May 26, 2017
Tweet

Other Decks in Technology

Transcript

  1. ReactͷύϑΥʔϚϯεΛ
    վળ͢Δඞཁ͕ͳ͔ͬͨ࿩

    View Slide

  2. ࣗݾ঺հɿືɹٛ໌
    • ϑϩϯτΤϯυΤϯδχΞ
    • νʔϜεϐϦοτʹೖࣾ൒೥
    • ήʔϜେ޷͖
    • ࣾ಺ͷےτϨڭʹೖ৴ͭͭ͋͠Δ

    View Slide

  3. ຊ೔ͷ͓࿩
    ωοτͰ࠷ۙReactͷ
    ύϑΥʔϚϯεΛվળͨ͠࿩Λ
    Α͘ݟΔͷͰ
    ࣗ෼Ͱ΋΍ͬͯΈͨΒ
    ಛʹඞཁͳ͔ͬͨͱ͍͏࿩

    View Slide

  4. લఏͱͯ͠
    Reactͷಛ௃ΛৼΓฦΔ

    View Slide

  5. Reactͷ̏ͭͷಛ௃
    • JUST THE UI
    • VIRTUAL DOM
    • DATA FLOW
    VIRTUAL DOMʹΑΓ
    ඞཁ࠷௿ݶͷ
    ύϑΥʔϚϯε͸कΒΕ͍ͯΔ

    View Slide

  6. ͋Γ͕ͱ͏
    ͓ΘΓ

    View Slide

  7. ΋͏গ͠ଓ͚·͢ɾɾɾ

    View Slide

  8. ·ͱΊ
    • React͸Virtul DomͰͷࠩ෼ߋ৽Λߦ͏ͨΊɹ
    ࠷ॳ͔Β͋Δఔ౓ͷύϑΥʔϚϯε͕อͯΔ
    Α͏ʹग़དྷ͍ͯΔɻ

    View Slide

  9. վΊͯ
    DOM͸͍ͭߋ৽͞ΕΔͷ͔ʁ

    View Slide

  10. Stateͷߋ৽

    View Slide

  11. container
    amountΛߋ৽
    State͕ߋ৽࣌ɺ࠶ϨϯμϦϯά͕ൃੜ
    ίϯϙʔωϯτ܈
    $PNQPOFOU% $PNQPOFOU& $PNQPOFOU'
    $PNQPOFOU$
    $PNQPOFOU#
    $PNQPOFOU"
    TFU4UBUF \BNPVOUWBMVF^

    ࣮ࡍʹBNPVOUΛ࢖͏
    ίϯϙʔωϯτ

    View Slide

  12. ٯΛݴ͏ͱɾɾɾ

    View Slide

  13. container
    setStateʹΑΓ
    ม਺VΛߋ৽
    state͕ίϯϙʔωϯτʹ౉͍ͬͯΕ͹ɺ
    ྫ͑ະ࢖༻Ͱ΋࠶ϨϯμϦϯά͕૸Δ
    ίϯϙʔωϯτ܈
    ίϯϙʔωϯτ
    $PNQPOFOU% $PNQPOFOU& $PNQPOFOU'
    $PNQPOFOU$
    $PNQPOFOU#
    $PNQPOFOU"
    BNPVOUΛνΣοΫ
    BNPVOUΛʜ
    BNPVOUΛ
    νΣοΫ
    BN
    TFU4UBUF \BNPVOUWBMVF^

    ࣮ࡍʹBNPVOUΛ࢖͏
    ίϯϙʔωϯτ

    View Slide

  14. ࠶ϨϯμϦϯάͷ
    ճ਺ΛݮΒ͢ʹ͸ʁ

    View Slide

  15. state͸ઙ͘อͪɺ֤ίϯϙʔωϯτͷ
    ߋ৽ʹඞཁͳ΋ͷ͚ͩ౉͢Α͏৺͕͚Δ
    this.state = {
    // ඞཁͳstateΛҰͭͷΦϒδΣΫτʹશͯ֨ೲ͍ͯ͠Δύλʔϯ
    masterObject: {
    date: ‘2017-5-15’,
    amount: 3000,
    name: ‘tawashi’,
    }
    };
    this.state = {
    // stateΛ෼ׂͨ͠
    date: ‘2017-5-15’,
    amount: 3000,
    name: ‘tawashi’,
    };

    View Slide

  16. Spread Attributes΍ChildrenͳͲͷ
    ͝ར༻͸ܭըతʹ
    render() {
    // Spread Attributes
    return ;
    }
    • όέπϦϨʔʹർΕͨਓͷٹੈओ
    • ͝ར༻͸ܭըతʹ

    View Slide

  17. ෆཁͳpropsͷड͚౉͠ΛࢭΊΔ
    class MeatMarker extends Component {
    render() {
    return A={this.props.A}
    B={this.props.B}
    V={this.props.V} />;
    }
    }
    • ԼҐίϯϙʔωϯτʹ౉͢஋͸ඞཁͳ΋ͷͩ
    ͚ʹ͠·͠ΐ͏
    • ϨϏϡʔ΍ݟ௚͠͸͔ͬ͠Γͱ

    View Slide

  18. ReactϙϦεʢϨϏϡʔΞʣͱͯ͠
    ͔ͬ͠Γ࢓ࣄ͍͖ͯ͠·͠ΐ͏

    View Slide

  19. ·ͱΊ
    • React͸Virtul DomͰͷࠩ෼ߋ৽Λߦ͏ͨΊɹ
    ɹ
    ࠷ॳ͔Β͋Δఔ౓ͷύϑΥʔϚϯε͕อͯΔ
    Α͏ʹग़དྷ͍ͯΔɻ
    • React͕ύϑΥʔϚϯεΛൃشͰ͖ΔΑ͏ʹߏ
    ੒͞Ε͍ͯΔ͔ৗʹ֬ೝ͢Δɻ

    View Slide

  20. ΋͏Ұ੠ؤுͬͯΈΔ

    View Slide

  21. componentWillUpdate(nextProps) {
    console.log(this.state.amount);
    console.log(nextProps.amount);
    }
    // લճͱඳը݁Ռ͕Ұॹ͕ͩ࠶౓ϨϯμϦϯά͸࣮ࢪ͞ΕΔ
    render(){ ɹˡɹ
    return ({amount});
    }
    ߋ৽ͷલޙͰState͕ಉҰͷ৔߹Ͱ΋
    ࠶ϨϯμϦϯά͕૸Δ

    View Slide

  22. ࠶ϨϯμϦϯάͷ
    ճ਺ΛݮΒ͢ʹ͸ʁ

    View Slide

  23. shouldComponentUpdate

    View Slide

  24. shouldComponentUpdate
    class MeatMarker extends Component {
    shouldComponentUpdate: function(nextProps, nextState) {
    if (this.props.userName !== nextProps.userName) {
    return true;ɹˡ update࣮ࢪ
    } else {
    return false;ɹˡɹupdate͞Εͳ͍
    }
    }
    • ίϯϙʔωϯτΛ࠶ඳը͢Δ͔Ͳ͏͔Λܾఆ͢Δ
    • updateલʹ࣮ߦ͞ΕΔɻ
    • ໭Γ஋ͰfalseΛฦͤ͹update͸࣮ࢪ͞Εͳ͍ɹ
    (σϑΥϧτͰ͸ඞͣtrue͕ฦΓ·͢)

    View Slide

  25. shouldComponentUpdateΑ͋͘Δ࣮૷
    shouldComponentUpdate: function(nextProps, nextState) {
    // user໊͕ߋ৽લޙͰಉҰͳΒߋ৽ॲཧ͸࣮ࢪ͠ͳ͍
    return this.props.userName !== nextProps.userName;
    }
    ̍.৚݅Λઃܭ࣮ͯ͠૷
    2.lodash΍immutable.jsΛར༻࣮ͨ͠૷
    shouldComponentUpdate: function(nextProps, nextState) {
    // ߋ৽લޙͰ஋͕มΘ͍ͬͯͳ͚Ε͹ɺupdate͸࣮ࢪ͠ͳ͍
    const propsDiff = _.isEqual(nextProps, this.props);
    const stateDiff = _.isEqual(nextState, this.state);
    return !(propsDiff && stateDiff);
    }

    View Slide

  26. PureComponentͰ΋OK
    class MeatMarker extends Component {
    constructor(props) {
    super(props);
    ɹɹɹɹɹɹɹ!
    //extendsઌΛPureComponentʹมߋ͢Δʮ͚ͩʯͰར༻Ͱ͖Δ
    class MeatMarker extends PureComponent {
    constructor(props) {
    super(props);
    • React v15.3Ҏ߱Ͱ࣮૷͞Ε͍ͯΔ
    • shouldComponentUpdateΛཪͰ࣮૷
    • શͯͷstateͱpropsʹshallowͳൺֱΛ࣮ࢪ

    View Slide

  27. ೦ͷͨΊͷshallowͳൺֱͷ͓͞Β͍
    ̍ճ໨
    api.get("/api/user",(req, res) => { this.setState({user:res}) );
    console.log(this.state.user);
    ݁Ռ
    {user: ‘minato’ , company: ‘TeamSpirit’}
    ̎ճ໨
    api.get("/api/user",(req, res) => { this.setState({user:res}) );
    console.log(this.state.user);
    ݁Ռ
    {user: ‘minato’ , company: ‘TeamSpirit’}
    ̍ճ໨ͱ̎ճ໨ͰผͷΦϒδΣΫτΛ
    ੜ੒͍ͯ͠ΔͷͰtrue͕ؼΓ·͢

    View Slide

  28. WARNING!

    View Slide

  29. Կ΋ߟ࣮͑ͣ૷͢Δͷ͸·͍ͣ
    class BaseComponent extends React.Component {
    shouldComponentUpdate: function(nextProps, nextState) {
    const propsDiff = _.isEqual(nextProps, this.props);
    const stateDiff = _.isEqual(nextState, this.state);
    return !(propsDiff && stateDiff);
    }
    }
    ɹྫ͑͹ҎԼͷΑ͏ʹߋ৽લޙͷstateɺprops
    Λൺֱ͢ΔBaseClassΛ࣮૷͠ɺશͯͷclassͰܧ
    ঝͯ͠ൺֱॲཧΛ࣮૷͢ΔͱɺٯʹύϑΥʔϚ
    ϯε͕௿Լ͢ΔՄೳੑ͕͋Δʢͱݴ͏͔͢Δʣ

    View Slide

  30. Ͳ͜ʹ࣮૷͢΂͖͔͸
    ͪΌΜͱݕ౼͔ͯ͠Βʹ
    ͠·͠ΐ͏

    View Slide

  31. ·ͱΊ
    • React͸Virtul DomͰͷࠩ෼ߋ৽Λߦ͏ͨΊɹ
    ɹ
    ࠷ॳ͔Β͋Δఔ౓ͷύϑΥʔϚϯε͕อͯΔ
    Α͏ʹग़དྷ͍ͯΔɻ
    • React͕ύϑΥʔϚϯεΛൃشͰ͖ΔΑ͏ʹߏ
    ੒͞Ε͍ͯΔ͔ৗʹ֬ೝ͢Δɻ
    • shouldComponentUpdateͰߋ৽લޙͷ஋͕
    ಉҰͷ৔߹ʹߋ৽ॲཧΛߦΘͳ͍Α͏ʹ͢Δ

    View Slide

  32. ͜͜·Ͱ͸༧๷

    View Slide

  33. ͔͜͜Β͸ର঱ྍ๏

    View Slide

  34. ύϑΥʔϚϯεͷ
    ϘτϧωοΫΛ୳͢

    View Slide

  35. PerfͷಋೖɻPerfͱ͸Կ͔ʁ
    • ίϯϙʔωϯτͷඳըʹ͔͔Δ࣌ؒΛௐ΂Δ
    ͜ͱ͕Ͱ͖Δπʔϧ
    • ϒϥ΢βͷίϯιʔϧ্Ͱಈ࡞͢Δ
    ↓͜Μͳײ͡ͷ݁Ռ͕ग़ͯͲ͜ʹ͕͔͔͍࣌ؒͬͯΔ֬ೝͰ͖Δ

    View Slide

  36. PerfͰͷݪҼಛఆͱରॲํ๏
    import React from ‘react';
    import Perf from 'react-addons-perf';
    class MeatMaker extends React.Component {
    componentDidMount() {
    window.Perf = Perf;
    };
    }
    1. componentDidMountͰPerfΛWindowʹ
    ηοτ͢Δɻ
    Reactιʔείʔυ

    View Slide

  37. PerfͰͷݪҼಛఆͱରॲํ๏
    2. Perf.start()Λ࣮ߦɻ
    3. ޷͖ͳ͚ͩΞΫγϣϯΛى͜͢ɻ
    4. Perf.stop()Λ࣮ߦɻ
    5. getLastMeasurementsͰ಺༰Λ֬ೝ͠ɺ࣌ؒ
    ͕͔͔͍ͬͯΔՕॴΛ֬ೝɻ
    ϒϥ΢βίϯιʔϧ
    ͜͜ΒลͳΜ͔΍͹ͦ͏

    View Slide

  38. PerfͰͷݪҼಛఆͱରॲํ๏ʢผղʣ
    import React from ‘react';
    import Perf from 'react-addons-perf';
    class MeatMaker extends React.Component {
    componentDidMount() {
    window.Perf = Perf;
    }
    render (){
    return (
    {Perf.start()}

    {Perf.stop()}

    );
    }
    }
    ίϯϙʔωϯτͷಡΈࠐΈલޙͰstartɺstopΛ࣮
    ࢪɺ֬ೝ͸ͦͷޙϒϥ΢β͔Βߦͬͯ΋OK

    View Slide

  39. ݪҼ΍৔ॴΛಛఆͨ͠ޙͷରॲํ๏͸ʁ
    جຊ͸લ߲·ͰͷLTͷ಺༰Λ
    ࢥ͍ฦ͍͚ͯͨͩ͠Ε͹
    େৎ෉ʢͷ͸ͣʣʂ

    View Slide

  40. ۩ମతʹ͸ʁʢ͓͞Β͍ʣ
    • ߏ੒Λݟ௚͠
    • ෆཁͳpropsͷ࡟আ
    • shouldComponentUpdate(PureComponent)
    ͷ࣮૷

    View Slide

  41. ݪҼͱରॲฤʢ͓·͚ʣ
    getSubContainer() {
    switch (this.state.selectedKey) {
    case 'meat':
    return ();
    case 'chicken':
    return ();
    default :
    return null;
    }
    }Window.Perf.start()Λ࣮ߦ
    ↓ຖճίϯϙʔωϯτΛ࠶࡞੒͍ͯ͠ΔͷͰॏ͍

    View Slide

  42. ݪҼͱରॲฤʢ͓·͚ʣ
    renderSubContainer() {
    {const meat = this.state.selectedKey === ‘meat’ }
    {const chicken = this.state.selectedKey === ‘chicken’ }
    return (


    );

    );
    }
    ঢ়گʹԠͯ͡ίϯϙʔωϯτΛඇදࣔʹ͠ɺ
    ࠶࡞੒͸ࣙΊͯΈͨ

    View Slide

  43. ࠶ϨϯμϦϯά͸ૣ͘ͳͬͨʂ

    View Slide

  44. ͕

    View Slide

  45. ॳظදࣔ͸஗͘ͳΓ
    ϝϞϦͷৗ࣌ͷ࢖༻ྔ͸૿͑ͨ

    View Slide

  46. ଥ౰ͳτϨʔυΦϑ͔
    ݕূ͸ඞཁ
    ΫϫΨλ
    खฤΈͷϚϑϥʔ

    View Slide

  47. ·ͱΊ
    • React͸Virtul DomͰͷࠩ෼ߋ৽Λߦ͏ͨΊɺ࠷ॳ͔Β
    ͋Δఔ౓ͷύϑΥʔϚϯε͕อͯΔΑ͏ʹग़དྷ͍ͯΔɻ
    • React͕ύϑΥʔϚϯεΛൃشͰ͖ΔΑ͏ʹߏ੒͞Εͯ
    ͍Δ͔ৗʹ֬ೝ͢Δɻ
    • shouldComponentUpdateͰߋ৽લޙͷ஋͕ಉҰͷ৔߹
    ʹߋ৽ॲཧΛߦΘͳ͍Α͏ʹ͢Δɻ
    • ϨϯμϦϯά͕஗͍৔߹͸PerfΛ࢖ͬͯݪҼΛಛఆ͠ɺ
    ରॲྍ๏Λ࣮૷͢Δɻ࣮૷͸ܭըతʹ

    View Slide

  48. ࠷ޙʹࠓߋͰ͕͢
    λΠτϧͷ݅ʹ͍ͭͯ

    View Slide

  49. ॳΊͯฐࣾͷ੡඼ͷύϑΥʔϚϯεΛҙࣝͨ࣌͠
    • ฐࣾͷϓϩμΫτ͸೔ࠒͷϨϏϡʔΛ͋Δఔ
    ౓͔ͬ͠Γ΍͍ͬͯͨ͜ͱ΋͋Γɺɹɹɹɹ
    ผʹࠓ͙͢ύϑΥʔϚϯεΛҙࣝͨ͠मਖ਼Λ
    ࣮ࢪ͠ͳͯ͘΋͍͍͔ͳɻͱ͍͏ͷ͕࠷ॳͷ
    ײ૝Ͱͨ͠ɻ
    • ࣮૷ͯ͠΋ମײͰ͖Δఔͷ͕ࠩ͋·Γແ͘ɺ
    ଞͷݕ౼ࣄ߲͕ग़ͦ͏ͩͬͨ
    • ϚδͰࠔͬͨΒPerfͰͳΜͱ͔͢Δ

    View Slide

  50. ·ͱΊͷ·ͱΊ
    • React͸Virtual Domͷࢥ૝΋͋Γɺҙࣝͤͣ
    ͱ΋ύϑΥʔϚϯε͸͋Δఔ౓ग़Δɻ
    • ઃܭͱ೔ࠒͷϨϏϡʔ͕େࣄɻઃܭ΍೔ࠒͷ
    ϨϏϡʔ͕ສશͳΒ͹ɺͦ΋ͦ΋ύϑΥʔϚ
    ϯεͷվળࣗମ͕ෆཁͳ͜ͱ΋ଟ͍ɻ
    • ϚδͰࠔͬͨΒPerfͰͳΜͱ͔͢Δ

    View Slide

  51. ྑ͍ReactϥΠϑΛ

    View Slide

  52. ͝੩ௌ
    ͋Γ͕ͱ͏͍͟͝·ͨ͠

    View Slide