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ͷ̏ͭͷಛ௃ • JUST THE UI • VIRTUAL DOM • DATA

    FLOW VIRTUAL DOMʹΑΓ ඞཁ࠷௿ݶͷ ύϑΥʔϚϯε͸कΒΕ͍ͯΔ
  2. container setStateʹΑΓ ม਺VΛߋ৽ state͕ίϯϙʔωϯτʹ౉͍ͬͯΕ͹ɺ ྫ͑ະ࢖༻Ͱ΋࠶ϨϯμϦϯά͕૸Δ ίϯϙʔωϯτ܈ ίϯϙʔωϯτ $PNQPOFOU% $PNQPOFOU& $PNQPOFOU'

    $PNQPOFOU$ $PNQPOFOU# $PNQPOFOU" BNPVOUΛνΣοΫ BNPVOUΛʜ BNPVOUΛ νΣοΫ BN TFU4UBUF \BNPVOUWBMVF^ ࣮ࡍʹBNPVOUΛ࢖͏ ίϯϙʔωϯτ
  3. state͸ઙ͘อͪɺ֤ίϯϙʔωϯτͷ ߋ৽ʹඞཁͳ΋ͷ͚ͩ౉͢Α͏৺͕͚Δ this.state = { // ඞཁͳstateΛҰͭͷΦϒδΣΫτʹશͯ֨ೲ͍ͯ͠Δύλʔϯ masterObject: { date:

    ‘2017-5-15’, amount: 3000, name: ‘tawashi’, } }; this.state = { // stateΛ෼ׂͨ͠ date: ‘2017-5-15’, amount: 3000, name: ‘tawashi’, };
  4. Spread Attributes΍ChildrenͳͲͷ ͝ར༻͸ܭըతʹ render() { // Spread Attributes return <Meat

    {...props} />; } • όέπϦϨʔʹർΕͨਓͷٹੈओ • ͝ར༻͸ܭըతʹ
  5. ෆཁͳpropsͷड͚౉͠ΛࢭΊΔ class MeatMarker extends Component { render() { return <Meat

    A={this.props.A} B={this.props.B} V={this.props.V} />; } } • ԼҐίϯϙʔωϯτʹ౉͢஋͸ඞཁͳ΋ͷͩ ͚ʹ͠·͠ΐ͏ • ϨϏϡʔ΍ݟ௚͠͸͔ͬ͠Γͱ
  6. 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͕ฦΓ·͢)
  7. 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); }
  8. 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ͳൺֱΛ࣮ࢪ
  9. ೦ͷͨΊͷ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͕ؼΓ·͢
  10. Կ΋ߟ࣮͑ͣ૷͢Δͷ͸·͍ͣ 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Ͱܧ ঝͯ͠ൺֱॲཧΛ࣮૷͢ΔͱɺٯʹύϑΥʔϚ ϯε͕௿Լ͢ΔՄೳੑ͕͋Δʢͱݴ͏͔͢Δʣ
  11. 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ιʔείʔυ
  12. PerfͰͷݪҼಛఆͱରॲํ๏ʢผղʣ import React from ‘react'; import Perf from 'react-addons-perf'; class

    MeatMaker extends React.Component { componentDidMount() { window.Perf = Perf; } render (){ return ( <div> {Perf.start()} <MeatMaker /> {Perf.stop()} <ChikenMaker /> </div> ); } } ίϯϙʔωϯτͷಡΈࠐΈલޙͰstartɺstopΛ࣮ ࢪɺ֬ೝ͸ͦͷޙϒϥ΢β͔Βߦͬͯ΋OK
  13. ݪҼͱରॲฤʢ͓·͚ʣ getSubContainer() { switch (this.state.selectedKey) { case 'meat': return (<Meat

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

    {const chicken = this.state.selectedKey === ‘chicken’ } return ( <div> <Meat visible={meat} /> <Chicken visible={chicken} />); </div> ); } ঢ়گʹԠͯ͡ίϯϙʔωϯτΛඇදࣔʹ͠ɺ ࠶࡞੒͸ࣙΊͯΈͨ
  15. ͕