Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Reactのパフォーマンスを改善する必要がなかった話
Search
teamspirit_minato
May 26, 2017
Technology
2
3.4k
Reactのパフォーマンスを改善する必要がなかった話
現在開発中の自社製品に対し、パフォーマンスを初めて意識した際にまだ特に大きく改善する点が見当たらなかったというだけの話
teamspirit_minato
May 26, 2017
Tweet
Share
Other Decks in Technology
See All in Technology
人はなぜISUCONに夢中になるのか
kakehashi
PRO
6
1.6k
開発組織のための セキュアコーディング研修の始め方
flatt_security
3
2k
The Future of SEO: The Impact of AI on Search
badams
0
180
ビジネスモデリング道場 目的と背景
masuda220
PRO
9
490
「海外登壇」という 選択肢を与えるために 〜Gophers EX
logica0419
0
700
飲食店予約台帳を支えるインタラクティブ UI 設計と実装
siropaca
7
1.7k
Data-centric AI入門第6章:Data-centric AIの実践例
x_ttyszk
1
400
10分で紹介するAmazon Bedrock利用時のセキュリティ対策 / 10-minutes introduction to security measures when using Amazon Bedrock
hideakiaoyagi
0
180
Tech Blogを書きやすい環境づくり
lycorptech_jp
PRO
1
240
エンジニアのためのドキュメント力基礎講座〜構造化思考から始めよう〜(2025/02/15jbug広島#15発表資料)
yasuoyasuo
16
6.5k
君も受託系GISエンジニアにならないか
sudataka
2
420
ハッキングの世界に迫る~攻撃者の思考で考えるセキュリティ~
nomizone
13
5.1k
Featured
See All Featured
The Pragmatic Product Professional
lauravandoore
32
6.4k
Fashionably flexible responsive web design (full day workshop)
malarkey
406
66k
Making Projects Easy
brettharned
116
6k
Adopting Sorbet at Scale
ufuk
74
9.2k
Why You Should Never Use an ORM
jnunemaker
PRO
55
9.2k
Scaling GitHub
holman
459
140k
For a Future-Friendly Web
brad_frost
176
9.5k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
29
1k
How to Think Like a Performance Engineer
csswizardry
22
1.3k
Typedesign – Prime Four
hannesfritz
40
2.5k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
A Philosophy of Restraint
colly
203
16k
Transcript
ReactͷύϑΥʔϚϯεΛ վળ͢Δඞཁ͕ͳ͔ͬͨ
ࣗݾհɿືɹٛ໌ • ϑϩϯτΤϯυΤϯδχΞ • νʔϜεϐϦοτʹೖࣾ • ήʔϜେ͖ • ࣾͷےτϨڭʹೖ৴ͭͭ͋͠Δ
ຊͷ͓ ωοτͰ࠷ۙReactͷ ύϑΥʔϚϯεΛվળͨ͠Λ Α͘ݟΔͷͰ ࣗͰͬͯΈͨΒ ಛʹඞཁͳ͔ͬͨͱ͍͏
લఏͱͯ͠ ReactͷಛΛৼΓฦΔ
Reactͷ̏ͭͷಛ • JUST THE UI • VIRTUAL DOM • DATA
FLOW VIRTUAL DOMʹΑΓ ඞཁ࠷ݶͷ ύϑΥʔϚϯεकΒΕ͍ͯΔ
͋Γ͕ͱ͏ ͓ΘΓ
͏গ͠ଓ͚·͢ɾɾɾ
·ͱΊ • ReactVirtul DomͰͷࠩߋ৽Λߦ͏ͨΊɹ ࠷ॳ͔Β͋ΔఔͷύϑΥʔϚϯε͕อͯΔ Α͏ʹग़དྷ͍ͯΔɻ
վΊͯ DOM͍ͭߋ৽͞ΕΔͷ͔ʁ
Stateͷߋ৽
container amountΛߋ৽ State͕ߋ৽࣌ɺ࠶ϨϯμϦϯά͕ൃੜ ίϯϙʔωϯτ܈ $PNQPOFOU% $PNQPOFOU& $PNQPOFOU' $PNQPOFOU$ $PNQPOFOU# $PNQPOFOU"
TFU4UBUF \BNPVOUWBMVF^ ࣮ࡍʹBNPVOUΛ͏ ίϯϙʔωϯτ
ٯΛݴ͏ͱɾɾɾ
container setStateʹΑΓ มVΛߋ৽ state͕ίϯϙʔωϯτʹ͍ͬͯΕɺ ྫ͑ະ༻Ͱ࠶ϨϯμϦϯά͕Δ ίϯϙʔωϯτ܈ ίϯϙʔωϯτ $PNQPOFOU% $PNQPOFOU& $PNQPOFOU'
$PNQPOFOU$ $PNQPOFOU# $PNQPOFOU" BNPVOUΛνΣοΫ BNPVOUΛʜ BNPVOUΛ νΣοΫ BN TFU4UBUF \BNPVOUWBMVF^ ࣮ࡍʹBNPVOUΛ͏ ίϯϙʔωϯτ
࠶ϨϯμϦϯάͷ ճΛݮΒ͢ʹʁ
stateઙ͘อͪɺ֤ίϯϙʔωϯτͷ ߋ৽ʹඞཁͳͷ͚ͩ͢Α͏৺͕͚Δ this.state = { // ඞཁͳstateΛҰͭͷΦϒδΣΫτʹશͯ֨ೲ͍ͯ͠Δύλʔϯ masterObject: { date:
‘2017-5-15’, amount: 3000, name: ‘tawashi’, } }; this.state = { // stateΛׂͨ͠ date: ‘2017-5-15’, amount: 3000, name: ‘tawashi’, };
Spread AttributesChildrenͳͲͷ ͝ར༻ܭըతʹ render() { // Spread Attributes return <Meat
{...props} />; } • όέπϦϨʔʹർΕͨਓͷٹੈओ • ͝ར༻ܭըతʹ
ෆཁͳpropsͷड͚͠ΛࢭΊΔ class MeatMarker extends Component { render() { return <Meat
A={this.props.A} B={this.props.B} V={this.props.V} />; } } • ԼҐίϯϙʔωϯτʹ͢ඞཁͳͷͩ ͚ʹ͠·͠ΐ͏ • ϨϏϡʔݟ͔ͬ͠͠Γͱ
ReactϙϦεʢϨϏϡʔΞʣͱͯ͠ ͔ͬ͠Γࣄ͍͖ͯ͠·͠ΐ͏
·ͱΊ • ReactVirtul DomͰͷࠩߋ৽Λߦ͏ͨΊɹ ɹ ࠷ॳ͔Β͋ΔఔͷύϑΥʔϚϯε͕อͯΔ Α͏ʹग़དྷ͍ͯΔɻ • React͕ύϑΥʔϚϯεΛൃشͰ͖ΔΑ͏ʹߏ ͞Ε͍ͯΔ͔ৗʹ֬ೝ͢Δɻ
͏ҰؤுͬͯΈΔ
componentWillUpdate(nextProps) { console.log(this.state.amount); console.log(nextProps.amount); } // લճͱඳը݁Ռ͕Ұॹ͕ͩ࠶ϨϯμϦϯά࣮ࢪ͞ΕΔ render(){ ɹˡɹ return
(<p>{amount}</p>); } ߋ৽ͷલޙͰState͕ಉҰͷ߹Ͱ ࠶ϨϯμϦϯά͕Δ
࠶ϨϯμϦϯάͷ ճΛݮΒ͢ʹʁ
shouldComponentUpdate
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͕ฦΓ·͢)
shouldComponentUpdateΑ͋͘Δ࣮ shouldComponentUpdate: function(nextProps, nextState) { // user໊͕ߋ৽લޙͰಉҰͳΒߋ৽ॲཧ࣮ࢪ͠ͳ͍ return this.props.userName !==
nextProps.userName; } ̍.݅Λઃܭ࣮ͯ͠ 2.lodashimmutable.jsΛར༻࣮ͨ͠ shouldComponentUpdate: function(nextProps, nextState) { // ߋ৽લޙͰ͕มΘ͍ͬͯͳ͚Εɺupdate࣮ࢪ͠ͳ͍ const propsDiff = _.isEqual(nextProps, this.props); const stateDiff = _.isEqual(nextState, this.state); return !(propsDiff && stateDiff); }
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ͳൺֱΛ࣮ࢪ
೦ͷͨΊͷ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͕ؼΓ·͢
WARNING!
Կߟ࣮͑ͣ͢Δͷ·͍ͣ 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Ͱܧ ঝͯ͠ൺֱॲཧΛ࣮͢ΔͱɺٯʹύϑΥʔϚ ϯε͕Լ͢ΔՄೳੑ͕͋Δʢͱݴ͏͔͢Δʣ
Ͳ͜ʹ࣮͖͔͢ ͪΌΜͱݕ౼͔ͯ͠Βʹ ͠·͠ΐ͏
·ͱΊ • ReactVirtul DomͰͷࠩߋ৽Λߦ͏ͨΊɹ ɹ ࠷ॳ͔Β͋ΔఔͷύϑΥʔϚϯε͕อͯΔ Α͏ʹग़དྷ͍ͯΔɻ • React͕ύϑΥʔϚϯεΛൃشͰ͖ΔΑ͏ʹߏ ͞Ε͍ͯΔ͔ৗʹ֬ೝ͢Δɻ
• shouldComponentUpdateͰߋ৽લޙͷ͕ ಉҰͷ߹ʹߋ৽ॲཧΛߦΘͳ͍Α͏ʹ͢Δ
͜͜·Ͱ༧
͔͜͜Βରྍ๏
ύϑΥʔϚϯεͷ ϘτϧωοΫΛ୳͢
PerfͷಋೖɻPerfͱԿ͔ʁ • ίϯϙʔωϯτͷඳըʹ͔͔Δ࣌ؒΛௐΔ ͜ͱ͕Ͱ͖Δπʔϧ • ϒϥβͷίϯιʔϧ্Ͱಈ࡞͢Δ ↓͜Μͳײ͡ͷ݁Ռ͕ग़ͯͲ͜ʹ͕͔͔͍࣌ؒͬͯΔ֬ೝͰ͖Δ
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ιʔείʔυ
PerfͰͷݪҼಛఆͱରॲํ๏ 2. Perf.start()Λ࣮ߦɻ 3. ͖ͳ͚ͩΞΫγϣϯΛى͜͢ɻ 4. Perf.stop()Λ࣮ߦɻ 5. getLastMeasurementsͰ༰Λ֬ೝ͠ɺ࣌ؒ ͕͔͔͍ͬͯΔՕॴΛ֬ೝɻ
ϒϥβίϯιʔϧ ͜͜ΒลͳΜ͔ͦ͏
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
ݪҼॴΛಛఆͨ͠ޙͷରॲํ๏ʁ جຊલ߲·ͰͷLTͷ༰Λ ࢥ͍ฦ͍͚ͯͨͩ͠Ε େৎʢͷͣʣʂ
۩ମతʹʁʢ͓͞Β͍ʣ • ߏΛݟ͠ • ෆཁͳpropsͷআ • shouldComponentUpdate(PureComponent) ͷ࣮
ݪҼͱରॲฤʢ͓·͚ʣ getSubContainer() { switch (this.state.selectedKey) { case 'meat': return (<Meat
/>); case 'chicken': return (<chicken />); default : return null; } }Window.Perf.start()Λ࣮ߦ ↓ຖճίϯϙʔωϯτΛ࠶࡞͍ͯ͠ΔͷͰॏ͍
ݪҼͱରॲฤʢ͓·͚ʣ renderSubContainer() { {const meat = this.state.selectedKey === ‘meat’ }
{const chicken = this.state.selectedKey === ‘chicken’ } return ( <div> <Meat visible={meat} /> <Chicken visible={chicken} />); </div> ); } ঢ়گʹԠͯ͡ίϯϙʔωϯτΛඇදࣔʹ͠ɺ ࠶࡞ࣙΊͯΈͨ
࠶ϨϯμϦϯάૣ͘ͳͬͨʂ
͕
ॳظදࣔ͘ͳΓ ϝϞϦͷৗ࣌ͷ༻ྔ૿͑ͨ
ଥͳτϨʔυΦϑ͔ ݕূඞཁ ΫϫΨλ खฤΈͷϚϑϥʔ
·ͱΊ • ReactVirtul DomͰͷࠩߋ৽Λߦ͏ͨΊɺ࠷ॳ͔Β ͋ΔఔͷύϑΥʔϚϯε͕อͯΔΑ͏ʹग़དྷ͍ͯΔɻ • React͕ύϑΥʔϚϯεΛൃشͰ͖ΔΑ͏ʹߏ͞Εͯ ͍Δ͔ৗʹ֬ೝ͢Δɻ • shouldComponentUpdateͰߋ৽લޙͷ͕ಉҰͷ߹
ʹߋ৽ॲཧΛߦΘͳ͍Α͏ʹ͢Δɻ • ϨϯμϦϯά͕͍߹PerfΛͬͯݪҼΛಛఆ͠ɺ ରॲྍ๏Λ࣮͢Δɻ࣮ܭըతʹ
࠷ޙʹࠓߋͰ͕͢ λΠτϧͷ݅ʹ͍ͭͯ
ॳΊͯฐࣾͷͷύϑΥʔϚϯεΛҙࣝͨ࣌͠ • ฐࣾͷϓϩμΫτࠒͷϨϏϡʔΛ͋Δఔ ͔ͬ͠Γ͍ͬͯͨ͜ͱ͋Γɺɹɹɹɹ ผʹࠓ͙͢ύϑΥʔϚϯεΛҙࣝͨ͠मਖ਼Λ ࣮ࢪ͠ͳ͍͍͔ͯ͘ͳɻͱ͍͏ͷ͕࠷ॳͷ ײͰͨ͠ɻ • ࣮ͯ͠ମײͰ͖Δఔͷ͕ࠩ͋·Γແ͘ɺ ଞͷݕ౼ࣄ߲͕ग़ͦ͏ͩͬͨ
• ϚδͰࠔͬͨΒPerfͰͳΜͱ͔͢Δ
·ͱΊͷ·ͱΊ • ReactVirtual Domͷࢥ͋Γɺҙࣝͤͣ ͱύϑΥʔϚϯε͋Δఔग़Δɻ • ઃܭͱࠒͷϨϏϡʔ͕େࣄɻઃܭࠒͷ ϨϏϡʔ͕ສશͳΒɺͦͦύϑΥʔϚ ϯεͷվળࣗମ͕ෆཁͳ͜ͱଟ͍ɻ •
ϚδͰࠔͬͨΒPerfͰͳΜͱ͔͢Δ
ྑ͍ReactϥΠϑΛ
͝੩ௌ ͋Γ͕ͱ͏͍͟͝·ͨ͠