React製 SPA における パフォーマンスチューニング

E8dde3bdd21542507a606a60a2101e66?s=47 Kento TSUJI
November 23, 2018

React製 SPA における パフォーマンスチューニング

E8dde3bdd21542507a606a60a2101e66?s=128

Kento TSUJI

November 23, 2018
Tweet

Transcript

  1. 2.

    ࣗݾ঺հ • Github: @maxmellon • Twitter: @maxmellon_9039 • ϦΫϧʔτςΫϊϩδʔζ 18೥

    ৽ଔೖࣾ
 ࣾձਓྺ ൒೥ʂʂʂ (Vim ྺ 5೥) • ޷෺: ͏ͲΜ, Vim, pipeline-operator
  2. 7.
  3. 21.

    ϦΫϧʔτʹ͓͚ΔSPA • AirSHIFTͱ͍͏αʔϏε͕͋Δ • γϑτද͕௚ײతʹ࡞ΕΔ • React / Redux +

    BFF (redux-pluto) • Component ਺ ໿600 ݸͱ͍͏େن໛ͳSPA • ௚ײతʹγϑτΛ࡞੒͢ΔͨΊʹ
 υϥοάΞϯυυϩοϓΛ࠾༻
  4. 23.
  5. 24.
  6. 25.
  7. 27.

    BFF Client API Isomorphic Session Data Notification
 Server Redis FCM

    wrapper React/Redux Fetchr CSR SSR DB Push
 Notification WebSocket OAuth γϑτ
 Ϙʔυ
 ʢ࿈ܞΞϓϦʣ ΞʔΩςΫνϟ
  8. 39.

    connect 3PPU $PNQPOFOU" DPOOFDU $PNQPOFOU" 3FEVDFS͕
 \
 TUBUF 
 BOZ0CKFDU

    
 ^
 ͯ͠Δ ͜ͷઌ͔ΒมߋΛ఻ୡ ͠ͳ͍Α͏ʹ͢Ε͹͍͍ͷͰ͸ʂ ͕͜͜ࢠʹ఻ୡ͍ͯ͠Δ͔Β
 ࠶ϨϯμϦϯά͕ൃੜͯ͠ΔͷͰ͸
  9. 56.

    performance.mark(‘A’) doSomeThing() performance.mark(‘B’) preformance.mesure(‘A-B’, ‘A’, ‘B’) ࢖͍ํ • doSomeThing ͷ࣮ߦ࣌ؒΛܭଌ͍ͨ͠৔߹

    • ܭଌ͍ͨ͠લޙͰ mark() • measure(<label>, <start>, <end>) Ͱܭଌ ͜ͷίʔυΛ௥هͯ͠ %FW5PPMTͰ ύϑΥʔϚϯεΛܭଌ͢Δ
  10. 57.
  11. 58.

    React 16 ͔Β User Timing API͕ఏڙ • React 16 ͔ΒUser

    Timing API ͕ར༻͞Εͨ • ։ൃ؀ڥͰ͸ DevTools ͰݟΔ͚ͩͰ OK • React ͕ ΠΠΧϯδʹ
 `performance.mark, measure` ͯ͘͠Ε͍ͯΔ
  12. 59.
  13. 91.

    Tree Reconciliation 4$6USVF OFX1SPQTˠ OFX1SPQTˠ 4$6GBMTF 4$6USVF TFU4UBUF OFX1SPQTˠ OFX1SPQTˠ

    SFOEFS SFOEFS 4$6USVF 4$6GBMTF ྘ͷՕॴ͸
 3FDPODJMJBUJPO͕
 ൃੜ͢Δ /P/FFE3FDPODJMJBUJPO /FFE3FDPODJMJBUJPO 4$6TIPVME$PNQPOFOU6QEBUF
  14. 93.

    Tree Reconciliation 4$6USVF OFX1SPQTˠ OFX1SPQTˠ 4$6GBMTF 4$6USVF TFU4UBUF OFX1SPQTˠ OFX1SPQTˠ

    SFOEFS SFOEFS 4$6USVF 4$6GBMTF ྘ͷՕॴ͸
 3FDPODJMJBUJPO͕
 ൃੜ͢Δ /P/FFE3FDPODJMJBUJPO /FFE3FDPODJMJBUJPO 4$6TIPVME$PNQPOFOU6QEBUF
  15. 95.

    React ʹ ͓͚Δ LifeCycle • ͦ΋ͦ΋ React ʹ͸ϥΠϑαΠΫϧ͕͋Δ • shouldComponentUpdate

    ͱ͍͏ͷ͸
 ϥΠϑαΠΫϧͷ1ͭ • ੹຿͸ɺࠩ෼ϨϯμϦϯά͕ඞཁ͔Ͳ͏͔ͷ
 ൑ఆΛߦ͏͜ͱ
  16. 96.

    LifeCycle // version 16 DPOTUSVDUPS SFOEFS DPNQPOFOU%JE.PVOU DPNQPOFOU%JE6QEBUF DPNQPOFOU8JMM
 6ONPVOU

    6QEBUF3FBDU%0.BOESFGT Mount TIPVME$PNQPOFOU6QEBUF Update Unmount 3FOEFS
 1IBTF $PNNJU
 1IBTF HFU%SJWFE4UBUF'SPN1SPQT HFU4OBQTIPU#FGPSF6QEBUF
  17. 97.

    LifeCycle // version 16 DPOTUSVDUPS SFOEFS DPNQPOFOU%JE.PVOU DPNQPOFOU%JE6QEBUF DPNQPOFOU8JMM
 6ONPVOU

    6QEBUF3FBDU%0.BOESFGT Mount TIPVME$PNQPOFOU6QEBUF Update Unmount 3FOEFS
 1IBTF $PNNJU
 1IBTF ͍͕ͭ͜USVFΛ
 ฦͨ͠ͱ͖ͷΈ
 ࠶ϨϯμϦϯά HFU%SJWFE4UBUF'SPN1SPQT HFU4OBQTIPU#FGPSF6QEBUF
  18. 98.

    LifeCycle // version 16 DPOTUSVDUPS SFOEFS DPNQPOFOU%JE.PVOU DPNQPOFOU%JE6QEBUF DPNQPOFOU8JMM
 6ONPVOU

    6QEBUF3FBDU%0.BOESFGT Mount TIPVME$PNQPOFOU6QEBUF Update Unmount 3FOEFS
 1IBTF $PNNJU
 1IBTF ͍͕ͭ͜USVFΛ
 ฦͨ͠ͱ͖ͷΈ
 ࠶ϨϯμϦϯά HFU%SJWFE4UBUF'SPN1SPQT HFU4OBQTIPU#FGPSF6QEBUF σϑΥϧτ͸
 ৗʹ5SVFΛฦ٫
  19. 101.

    Tree Reconciliation 4$6USVF OFX1SPQTˠ OFX1SPQTˠ 4$6GBMTF 4$6USVF TFU4UBUF OFX1SPQTˠ OFX1SPQTˠ

    SFOEFS SFOEFS 4$6USVF 4$6GBMTF ͦ΋ͦ΋໦ߏ଄ খ͘͢͞Ε͹͍͍͡ΌΜ
  20. 113.
  21. 114.
  22. 115.
  23. 118.
  24. 123.
  25. 128.
  26. 131.

    ͜ͷΞϓϩʔνͷڧΈ • ٕज़తʹ೉͍͠ཁૉ͕͘͢ͳ͍
 ˠ ΊΜͲ͍͚ͩ͘͞ • shouldComponentUpdate ͸࠷ॳ͔Β
 ॻ͔ͳͯ͘΋ྑ͍
 →

    ॏ͘ͳΕ͹ॻ͚͹͍͍ • ίϯϙʔωϯτ͕খ͍͞ͱ props ͕গͳ͍
 → SCU Λॻ͔ͳͯ͘΋ React.memo ͳͲ͕࢖͑Δ
  27. 138.
  28. 151.
  29. 155.

    ԿΛͯ͘͠ΕΔ͔ • جຊతʹ͢΂ͯ fbjs/shallowEqual ͯ͘͠ΕΔ • React.memo ͸ $$type Λॻ͖׵͑ͯ


    ಺෦ͷ updater ͷϩδοΫΛࠩ͠ସ͑ͯΔ
 㱺 SCU ʹ shallowEqual ͕ೖΔͱࢥͬͯྑ͍
  30. 158.
  31. 160.
  32. 161.
  33. 162.

    ·ͱΊ • recompose/pure ͸ class Ͱ΋ ؔ਺ Ͱ΋
 ࢖͑Δ •

    React.memo ͸ؔ਺༻ • PureComponent ͸ Ϋϥε༻ • React.memo ͸ ΦϓγϣϯͰνϡʔχϯάͰ͖Δ
  34. 165.

    Options { pure = ture, areStatesEqual = (a, b) =>

    a === b, areOwnPropsEqual = shallowEqual, areStatePropsEqual = shallowEqual, areMergedPropsEqual = shallowEqual, storeKey = ‘store’, } HoC ࣗମͷ࠶ϨϯμϦϯάͷ੍ޚ͕Ͱ͖Δ
  35. 166.

    connect() // version5 Component Store connect areStateEqual(prev, next) next =

    mapStateToProps(prev, next) prev = next // memoized once Update Childe Component // return true 
 in shouldComponentUpdate of HoC
  36. 167.

    connect() // version5 Component Store connect areStateEqual(prev, next) next =

    mapStateToProps(prev, next) prev = next // memoized once 7FSTJPO͸)P$ϕʔε Update Childe Component // return true 
 in shouldComponentUpdate of HoC
  37. 168.

    connect() // version5 connect areStateEqual(prev, next) next = mapStateToProps(prev, next)

    prev = next // memoized once PQUJPOQVSF  4IBMMPX&RVBM 4USJDU&RVBM Update Childe Component // return true 
 in shouldComponentUpdate of HoC Store Component
  38. 169.

    connect() // version5 connect areStateEqual(prev, next) next = mapStateToProps(prev, next)

    prev = next // memoized once ୈ̐Ҿ਺ͰΦʔόϥΠυͰ͖Δ  QSFW4UBUF OFYU4UBUF CPPMFBO Update Childe Component // return true 
 in shouldComponentUpdate of HoC Store Component
  39. 170.

    connect() // version5 connect areStateEqual(prev, next) next = mapStateToProps(prev, next)

    prev = next // memoized once Update Childe Component // return true 
 in shouldComponentUpdate of HoC Store Component લճͷ݁ՌΛอ͓࣋ͯ͘͠
  40. 171.

    connect ·ͱΊ • HoCͰ࣮૷͞Ε͍ͯΔ • Connect ͷ areStateEqual ͕ false

    Λฦͤ͹
 ࢠίϯϙʔωϯτͷ࠶ϨϯμϦϯάͳ͠ • ୈ4Ҿ਺ͰΦϓγϣϯΛ஫ೖՄೳ