Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Reactのパフォーマンスを改善する必要がなかった話
Search
teamspirit_minato
May 26, 2017
Technology
3.7k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Reactのパフォーマンスを改善する必要がなかった話
現在開発中の自社製品に対し、パフォーマンスを初めて意識した際にまだ特に大きく改善する点が見当たらなかったというだけの話
teamspirit_minato
May 26, 2017
Other Decks in Technology
See All in Technology
AIに賢く動いてもらうためのコンテキスト〜Snowflake女子会 vol.8
snowwmn0824
0
180
AI感のないAWS構成図をAIエージェントに描かせたい!
sagochiko
2
380
AgentCore Runtime上にAgentic Coding基盤を構築・展開する際の設計ポイントと限界点 / Design considerations and limitations when building an agentic coding platform on AgentCore Runtime
har1101
6
770
今話題のAI「Jev」って何? 宇宙最速で学ぶ会
minorun365
PRO
34
22k
技術的負債から考える、AI時代のエンジニアリング投資 — ビズリーチの技術的負債と向き合った経験から、変更し続けられるソフトウェアを考える/ technical-debt-con2026
visional_engineering_and_design
4
3.8k
AWS DevOps Agent スキルをつかいこなそう / Master AWS DevOps Agent Skills
kinunori
2
510
GoのInterface内部構造から学ぶ!最高パフォーマンスを出すコード設計
yappli_developers
1
300
LLMに渡さなかった仕事
nanaism
0
12k
フルカイテン株式会社 エンジニア向け採用資料
fullkaiten
0
12k
AIに書かせて、プラットフォームで縛る ― EKSプラットフォームで実践した責任境界と権限設計
elmodev09
0
590
作って終わりじゃないサーバーレス 〜9年運用する大規模EC物流API基盤の設計・運用のリアル〜
zozotech
PRO
0
540
Claude Codeを「使うほど育つ」AI秘書にするノウハウ
minorun365
PRO
32
32k
Featured
See All Featured
Raft: Consensus for Rubyists
vanstee
142
7.7k
Exploring anti-patterns in Rails
aemeredith
4
510
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
2k
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
68
58k
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
2
450
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2.1k
Rails Girls Zürich Keynote
gr2m
96
14k
Designing for humans not robots
tammielis
254
26k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
250
1.3M
KATA
mclloyd
PRO
35
16k
Large-scale JavaScript Application Architecture
addyosmani
515
110k
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
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ϥΠϑΛ
͝੩ௌ ͋Γ͕ͱ͏͍͟͝·ͨ͠