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

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

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

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

E16c5bf274115740284b9493d5250b18?s=128

teamspirit_minato

May 26, 2017
Tweet

Transcript

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

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

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

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

  5. Reactͷ̏ͭͷಛ௃ • JUST THE UI • VIRTUAL DOM • DATA

    FLOW VIRTUAL DOMʹΑΓ ඞཁ࠷௿ݶͷ ύϑΥʔϚϯε͸कΒΕ͍ͯΔ
  6. ͋Γ͕ͱ͏ ͓ΘΓ

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

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

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

  10. Stateͷߋ৽

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

    TFU4UBUF \BNPVOUWBMVF^ ࣮ࡍʹBNPVOUΛ࢖͏ ίϯϙʔωϯτ
  12. ٯΛݴ͏ͱɾɾɾ

  13. container setStateʹΑΓ ม਺VΛߋ৽ state͕ίϯϙʔωϯτʹ౉͍ͬͯΕ͹ɺ ྫ͑ະ࢖༻Ͱ΋࠶ϨϯμϦϯά͕૸Δ ίϯϙʔωϯτ܈ ίϯϙʔωϯτ $PNQPOFOU% $PNQPOFOU& $PNQPOFOU'

    $PNQPOFOU$ $PNQPOFOU# $PNQPOFOU" BNPVOUΛνΣοΫ BNPVOUΛʜ BNPVOUΛ νΣοΫ BN TFU4UBUF \BNPVOUWBMVF^ ࣮ࡍʹBNPVOUΛ࢖͏ ίϯϙʔωϯτ
  14. ࠶ϨϯμϦϯάͷ ճ਺ΛݮΒ͢ʹ͸ʁ

  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’, };
  16. Spread Attributes΍ChildrenͳͲͷ ͝ར༻͸ܭըతʹ render() { // Spread Attributes return <Meat

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

    A={this.props.A} B={this.props.B} V={this.props.V} />; } } • ԼҐίϯϙʔωϯτʹ౉͢஋͸ඞཁͳ΋ͷͩ ͚ʹ͠·͠ΐ͏ • ϨϏϡʔ΍ݟ௚͠͸͔ͬ͠Γͱ
  18. ReactϙϦεʢϨϏϡʔΞʣͱͯ͠ ͔ͬ͠Γ࢓ࣄ͍͖ͯ͠·͠ΐ͏

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

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

  21. componentWillUpdate(nextProps) { console.log(this.state.amount); console.log(nextProps.amount); } // લճͱඳը݁Ռ͕Ұॹ͕ͩ࠶౓ϨϯμϦϯά͸࣮ࢪ͞ΕΔ render(){ ɹˡɹ return

    (<p>{amount}</p>); } ߋ৽ͷલޙͰState͕ಉҰͷ৔߹Ͱ΋ ࠶ϨϯμϦϯά͕૸Δ
  22. ࠶ϨϯμϦϯάͷ ճ਺ΛݮΒ͢ʹ͸ʁ

  23. shouldComponentUpdate

  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͕ฦΓ·͢)
  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); }
  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ͳൺֱΛ࣮ࢪ
  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͕ؼΓ·͢
  28. WARNING!

  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Ͱܧ ঝͯ͠ൺֱॲཧΛ࣮૷͢ΔͱɺٯʹύϑΥʔϚ ϯε͕௿Լ͢ΔՄೳੑ͕͋Δʢͱݴ͏͔͢Δʣ
  30. Ͳ͜ʹ࣮૷͢΂͖͔͸ ͪΌΜͱݕ౼͔ͯ͠Βʹ ͠·͠ΐ͏

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

    • shouldComponentUpdateͰߋ৽લޙͷ஋͕ ಉҰͷ৔߹ʹߋ৽ॲཧΛߦΘͳ͍Α͏ʹ͢Δ
  32. ͜͜·Ͱ͸༧๷

  33. ͔͜͜Β͸ର঱ྍ๏

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

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

  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ιʔείʔυ
  37. PerfͰͷݪҼಛఆͱରॲํ๏ 2. Perf.start()Λ࣮ߦɻ 3. ޷͖ͳ͚ͩΞΫγϣϯΛى͜͢ɻ 4. Perf.stop()Λ࣮ߦɻ 5. getLastMeasurementsͰ಺༰Λ֬ೝ͠ɺ࣌ؒ ͕͔͔͍ͬͯΔՕॴΛ֬ೝɻ

    ϒϥ΢βίϯιʔϧ ͜͜ΒลͳΜ͔΍͹ͦ͏
  38. 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
  39. ݪҼ΍৔ॴΛಛఆͨ͠ޙͷରॲํ๏͸ʁ جຊ͸લ߲·ͰͷLTͷ಺༰Λ ࢥ͍ฦ͍͚ͯͨͩ͠Ε͹ େৎ෉ʢͷ͸ͣʣʂ

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

  41. ݪҼͱରॲฤʢ͓·͚ʣ getSubContainer() { switch (this.state.selectedKey) { case 'meat': return (<Meat

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

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

  44. ͕

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

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

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

    ʹߋ৽ॲཧΛߦΘͳ͍Α͏ʹ͢Δɻ • ϨϯμϦϯά͕஗͍৔߹͸PerfΛ࢖ͬͯݪҼΛಛఆ͠ɺ ରॲྍ๏Λ࣮૷͢Δɻ࣮૷͸ܭըతʹ
  48. ࠷ޙʹࠓߋͰ͕͢ λΠτϧͷ݅ʹ͍ͭͯ

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

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

    ϚδͰࠔͬͨΒPerfͰͳΜͱ͔͢Δ
  51. ྑ͍ReactϥΠϑΛ

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