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
Browser Computing Structure
Search
Shogo Sensui
January 25, 2014
Programming
5
2.5k
Browser Computing Structure
2014/1/25に開催されたFrontrend in FukuokaのBrowser Computing Structureのセッションの資料です。
Shogo Sensui
January 25, 2014
Tweet
Share
More Decks by Shogo Sensui
See All by Shogo Sensui
EU のデジタル市場法と Apple / DMA and Apple
1000ch
0
75
Web Share API
1000ch
0
85
2023 年の Web 開発のベースライン / Web Development Baseline 2023
1000ch
0
28
開発生産性と組織 / Productivity and Organization
1000ch
0
1.1k
なぜ私達は働くのか / Why We Work?
1000ch
0
49
新しいメルカリ Web とそのパフォーマンス / The New Mercari Web and its performance
1000ch
0
43
Web Standards Interop 2022
1000ch
0
270
パフォーマンスを高める CSS / Performance Optimized CSS
1000ch
1
760
HTML Optimization for Web Performance
1000ch
0
680
Other Decks in Programming
See All in Programming
Vertical Architectures for Scalable Angular Applications
manfredsteyer
PRO
0
210
組織に自動テストを書く文化を根付かせる戦略(2024秋版) / Building Automated Test Culture 2024 Autumn Edition
twada
PRO
9
3.6k
ACES Meet におけるリリース作業改善の取り組み
fukucheee
0
150
本編では話さない Zig の話
andpad
2
120
Modern Angular with Lightweight Stores: New Rules and Options
manfredsteyer
PRO
0
190
Kubernetes上でOracle_Databaseの運用を楽にするOraOperatorの紹介
nnaka2992
0
170
今日で分かる!カスタムコップの作り方
krpk1900
2
270
CSC305 Lecture 09
javiergs
PRO
0
120
CSC509 Lecture 07
javiergs
PRO
0
140
Kotlin Multiplatform at Stable and Beyond (Kotlin Vienna, October 2024)
zsmb
2
410
Vaporモードを大規模サービスに最速導入して学びを共有する
kazukishimamoto
3
2.1k
飲食業界向けマルチプロダクトを実現させる開発体制とリアルな現状
hiroya0601
1
210
Featured
See All Featured
How STYLIGHT went responsive
nonsquared
95
5.1k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
26
4.1k
Building Applications with DynamoDB
mza
90
6k
10 Git Anti Patterns You Should be Aware of
lemiorhan
653
59k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
43
6.6k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
27
1.9k
Optimizing for Happiness
mojombo
376
69k
Mobile First: as difficult as doing things right
swwweet
222
8.9k
jQuery: Nuts, Bolts and Bling
dougneiner
61
7.5k
The Language of Interfaces
destraynor
154
24k
Raft: Consensus for Rubyists
vanstee
136
6.6k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
228
52k
Transcript
Browser Computing Structure Frontrend in Fukuoka @1000ch
@1000ch
Frontend Developer
࣍ มԽ͢ΔWebͱJavaScriptͷׂ ϒϥβ͕ԿΛ͍ͯ͠Δ͔ΛΔ ϒϥβ͕͘ͳΔݪҼΛΔ ࠷దԽΞϓϩʔν
มԽ͢ΔWebͱ JavaScriptͷׂ
None
• ςΩετϕʔεͷWebαΠτ • ίϯςϯπͷߋ৽ભҠ͕த৺ • ০<marquee>ͱ͔<blink>ͱ͔… ੩తͳWeb
None
• ඇಉظ௨৴ʹΑΔίϯςϯπͷߋ৽ ʢGoogleϚοϓɾGoogleαδΣετʣ • JavaScript͕μΠφϛοΫͳWebαΠτͷ ՄೳੑΛHTMLʹͨΒͨ͠ ಈతͳWeb
None
• HTML5CSS3ͱ͍ͬͨɺ ٕज़ͷඪ४Խͱඈ༂తͳਐԽ • ϒϥβͰग़དྷΔ͜ͱ͕૿͑ͨ (WebGLɾWebAudioɾWebSocket…) ϦονͳWeb
JavaScriptͳ͠ʹ HTML5ΛޠΕͳ͍
ରԠͷ͠͞ ϕϯμʔͷ×OSͷόʔδϣϯ ʹൺྫͯ͠૿Ճ͢Δ࣮ϦεΫ
͔֬ଘࡏ͢Δίετ ϚγϯεϖοΫʹࠨӈ͞ΕΔ্ʹ ϞόΠϧͩͱͳ͓͞Β͕ࠩݦஶ
ύϑΥʔϚϯε͕ ٘ਜ਼ʹͳΓ͕ͪ
Amazon 100msͷߴԽ ച্1%૿Ճ Mozilla Google 2200msͷߴԽ μϯϩʔυ15.4%૿Ճ 400msͷߴԽ ݕࡧճ0.59%૿Ճ
ύϑΥʔϚϯε ࠷ॏཁͳUXࢦඪ ύϑΥʔϚϯεWebαΠτͷ࣭Ͱ͋Δ ͔ͬ͜Α͍ͯ͘αΠτʹϢʔβʔຬ͠ͳ͍
ϒϥβ͕ ԿΛ͍ͯ͠Δ͔ΛΔ
σʔλͷཁٻͱμϯϩʔυ URLͷೖྗϖʔδભҠ HTML ϨϯμʔπϦʔͷϨΠΞτͱϖΠϯτ ϢʔβʔΞΫγϣϯͷԠ ΫϦοΫεΫϩʔϧͷΠϯλϥΫγϣϯ
ϢʔβʔΞΫγϣϯͷԠ ΫϦοΫεΫϩʔϧͷΠϯλϥΫγϣϯ σʔλͷཁٻͱμϯϩʔυ URL HTMLCSSͷղੳͱඳը ϨϯμʔπϦʔͷϨΠΞτͱϖΠϯτ
ϢʔβʔΞΫγϣϯͷԠ ΫϦοΫεΫϩʔϧͷΠϯλϥΫγϣϯ σʔλͷཁٻͱμϯϩʔυ URL HTML ϨϯμʔπϦʔͷϨΠΞτͱϖΠϯτ
ϢʔβʔΞΫγϣϯͷԠ ΫϦοΫεΫϩʔϧͷΠϯλϥΫγϣϯ σʔλͷཁٻͱμϯϩʔυ URLͷೖྗϖʔδભҠ HTMLCSSͷղੳͱඳը ϨϯμʔπϦʔͷϨΠΞτͱϖΠϯτ
ϢʔβʔΞΫγϣϯͷԠ ΫϦοΫεΫϩʔϧͷΠϯλϥΫγϣϯ σʔλͷཁٻͱμϯϩʔυ URLͷೖྗϖʔδભҠ HTMLCSSͷղੳͱඳը ϨϯμʔπϦʔͷϨΠΞτͱϖΠϯτ
σʔλͷཁٻͱμϯϩʔυ URL HTML ϨϯμʔπϦʔͷϨΠΞτͱϖΠϯτ ϢʔβʔΞΫγϣϯͷԠ ΫϦοΫεΫϩʔϧͷΠϯλϥΫγϣϯ ϖʔδͷϩʔυ։͔࢝Β දࣔ͞ΕΔ·Ͱ
σʔλͷཁٻͱμϯϩʔυ URL HTML ϨϯμʔπϦʔͷϨΠΞτͱϖΠϯτ ϢʔβʔΞΫγϣϯͷԠ ΫϦοΫεΫϩʔϧͷΠϯλϥΫγϣϯ ϖʔδ͕දࣔ͞Ε͔ͯΒ ࣍ͷભҠ·Ͱͣͬͱ
Render Compute Network ύϑΥʔϚϯεͷ3େཁૉ
Render Compute Network ϖʔδදࣔ·ͰͷΠχγϟϧίετ →ϑΝʔετΠϯϓϨογϣϯ
Render Compute Network εΫϩʔϧͷΒ͔͞ϖʔδԠ →Ϣʔβʔͷ͍৺
Chrome DevTools ϒϥβɺͦͯ͠࠷ڧͷ։ൃऀπʔϧ Firebug͍͍͚ͲͬͺChrome Command + option + i
Google Chrome Canary Chromeͷ։ൃऀ͚Ϗϧυ DevToolͷ৽ػೳΛ͍ͪૣ͘ࢼͤΔ ͨ·ʹෆ҆ఆ…
DevTools > Network Network HTTPϦΫΤετͷ ϦιʔεαΠζͷνΣοΫ όουϦΫΤετ͕ͳ͍͔Ͳ͏͔ ωοτϫʔΫपΓͷ࠷దԽ
DevTools > Timeline Render FPSͷͷνΣοΫ ϨΠΞτϖΠϯτͷλΠϛϯά ΠϕϯτͷൃՐGCͷ࣮ߦܗ ϒϥβ͕ͲͷΑ͏ͳॲཧ Λ͍ͯ͠Δ͔େମΘ͔Δ
DevTools > Profiles Compute JavaScriptͷ࣮ߦίετ ώʔϓྖҬʹஔ͔ΕΔΦϒδΣΫτ TimelineΑΓࡉ͔͍ϝϞϦͷঢ়ଶ εΫϦϓτपΓͷௐࠪ
Compute ࠓComputingͷ
Keep 60FPS • FPS = Frames Per Second • ϒϥβ1ඵؒʹ60ճϦϑϨογϡ͢Δ
• 60FPSΛҡ࣋͢Δʹ1ϑϨʔϜͷॲཧΛ16.67ms ʹऩΊΔ (16.67ms=1000ms / 60FPs) • Ұൠతʹ30FPSग़͍ͯΕΒ͔Ͱ͋Δ
ϒϥβͷॲཧ Load Script Render Paint Load Script Render
Load Script Render Paint der Paint Load Sc ϒϥβͷॲཧ 16.67ms
Paint Paint ಛʹॲཧ͕ͳ͍ͱ͖ 16.67ms
20FPSͷαϯϓϧ http://codepen.io/paulirish/full/nkwKs
None
60FPSͷαϯϓϧ http://codepen.io/1000ch/full/KbLHh
None
ϒϥβ͕ ͘ͳΔݪҼΛΔ
Case#1 ॏ͍ॲཧ ͕͔͔࣌ؒΔͱϖΠϯτΕΔ
Script͕͍͠ͱ… Load Script Render Paint der Paint Load 16.67msʹऩ·Βͳ͍
None
None
None
Case#2 GC Scriptͷ࣮ߦΛࢭΊͯ͠·͏
Garbage Collection? • JavaScriptͰɺϝϞϦͷׂͱղ์͕JavaScriptͷΤ ϯδϯʹΑͬͯࣗಈͰߦΘΕΔɻͦͷΈ͕Garbage CollectionͰ͋Δ • ࠷ۙͷߴਫ४ݴޠʹ΄ͱΜͲඋΘ͍ͬͯΔ • ͍ΘϧϯόͷΑ͏ͳଘࡏ
by @ahomu
GCൃੜͷλΠϛϯά • ϒϥβʹΑͬͯҰఆͷपظͰ࣮ߦ͞ΕΔଞɺϝϞϦ͕গ ͳ͘ͳ͖ͬͯͨΓɺෆཁͳϝϞϦ͕ग़ݱ͢Δͱ࣮ߦ͞ΕΔ • JavaScriptͰ࣮ߦͷλΠϛϯάΛίϯτϩʔϧ͢ Δज़ͳ͍
Window A B D C E
Window A B D C E
Window A B D C E GCͷରʹͳΔ
GCͷؒScript͕ࢭ·Δ Load Render Paint der Paint GC Load 16.67msʹऩ·Βͳ͍ Script
None
None
None
Case#3 ϝϞϦϦʔΫ Կ͔ͱѱӨڹΛٴ΅͢
ϝϞϦϦʔΫ • ϝϞϦྖҬ͕ѹഭ͞ΕΔͱඞવతʹϒϥβͷ࣮ߦ Լ͢Δ • ϝϞϦͷճऩϖʔδભҠ͔࣌ɺGarbage Collectionͷ ࣮ߦʹΑΓߦΘΕΔ • ϝϞϦϦʔΫͷදతͳݪҼ…?
Understand memory leaks http://www.ibm.com/developerworks/web/library/wa-jsmemory/
ίϯιʔϧ ॥ࢀর Ϋϩʔδϟ λΠϚʔ
ίϯιʔϧ ॥ࢀর Ϋϩʔδϟ λΠϚʔ
function Timer() { this.timerId = setInterval(function() { console.log('This is timer
log.'); }, 1000); } ! ! ! var timer = new Timer(); timer = null;
function Timer() { this.timerId = setInterval(function() { console.log('This is timer
log.'); }, 1000); } ! ! ! var timer = new Timer(); timer = null; ݺͼग़͠ݩΛഁغͯ͠ λΠϚʔ͕࣮ߦ͞Εଓ͚Δ
function Timer() { this.timerId = setInterval(function() { console.log('This is timer
log.'); }, 1000); this.stop = function() { clearInterval(this.timerId); }; } ! ! ! var timer = new Timer(); timer.stop(); timer = null;
function Timer() { this.timerId = setInterval(function() { console.log('This is timer
log.'); }, 1000); this.stop = function() { clearInterval(this.timerId); }; } ! ! ! var timer = new Timer(); timer.stop(); timer = null; λΠϚʔ ͪΌΜͱࢭΊΔ͜ͱʂ
Ϋϩʔδϟ λΠϚʔ ίϯιʔϧ ॥ࢀর
function Closure() { var value = 1000; return function() {
return value; }; }
function Closure() { var value = 1000; return function() {
return value; }; } value͔ؔΒ ࢀর͞Εଓ͚ͯ͠·͏
function Closure() { var value = 1000; return function() {
var another = 2000; return another; }; }
function Closure() { var value = 1000; return function() {
var another = 2000; return another; }; } valueࢀর͞Εͳ͘ͳΔ ͷͰGCʹճऩ͞ΕΔ
॥ࢀর ίϯιʔϧ λΠϚʔ Ϋϩʔδϟ
var family = []; ! var child = { age:
10 container: family }; ! var parent = { child: child, container: family }; ! family.push(child); family.push(parent);
var grandparent = { child: parent, container: family }; !
family.push(parent);
var grandparent = { child: parent, container: family }; !
family.push(parent); ઇͩΔ·ࣜʹ૿͑ΔϝϞϦ
A C B
A C B
A C
A C ࢀর͕ͬͯ͠·͍ GCͰճऩ͞Εͳ͍
A C B
A C
A C
A C ࢀর͕ͳ͘ͳͬͨͷͰ ϝϞϦ͕։์͞ΕΔ
ࢀরؔͷཧΛʂ ҰൠతͳϑϨʔϜϫʔΫ͜ͷΑ͏ͳ ΠϕϯτϦεφͷϞσϧʹै͍ͬͯΔ͜ͱ͕ଟ͍
ίϯιʔϧ ॥ࢀর λΠϚʔ Ϋϩʔδϟ
var object = { foo: 1, bar: 2 }; console.log(object);
object = null;
var object = { foo: 1, bar: 2 }; console.log(object);
object = null; ίϯιʔϧ͔Βࢀর͞Ε GC͔Βճऩ͞Εͳ͍
ϝϞϦͱͷਔٛͳ͖ઓ͍ • ͍͘Β࠷దԽͯ͠GCࣗಈͰ࣮ߦ͞Εͯ͠· ͏ɻͦͷΠϯύΫτΛԿʹখ͘͞ग़དྷΔ͔͕ॏཁ • ಛʹؾΛΘͳ͚Ε͍͚ͳ͍ͷϖʔδભҠΛ͠ ͳ͍ɺ͔ͭΒ͔͕͞ॏཁͳ߹(γϡʔςΟϯά ήʔϜͱ͔) • Script͔Βൃੜ͢ΔLoadRenderΕͳ͍
࠷దԽΞϓϩʔν
Profiles ະ։์ͷΦϒδΣΫτϝϞϦͷ༻ঢ়ଶ ͍৺ͷѱ͞Λݟಀ͞ͳ͍ εΫϩʔϧ͕Ҿ͔͔ͬΔ Timeline 60FPS
Profiles ະ։์ͷΦϒδΣΫτϝϞϦͷ༻ঢ়ଶ ͍৺ͷѱ͞Λݟಀ͞ͳ͍ εΫϩʔϧ͕Ҿ͔͔ͬΔ TimelineͰωοΫΛݟ͚ͭΔ 60FPSͱ30FPSͷϘʔμʔΛҹʹ
ProfilesͰৄ͘͠ղੳ͢Δ ະ։์ͷΦϒδΣΫτϝϞϦͷ༻ঢ়ଶ ͍৺ͷѱ͞Λݟಀ͞ͳ͍ εΫϩʔϧ͕Ҿ͔͔ͬΔ Timeline 60FPS
Collect JavaScript CPU Profile JavaScriptͷ࣮ߦʹ͔͔ͬͨ࣌ؒΛௐΔ͜ͱ͕ग़དྷΔ
Take Heap Snapshot ݱࡏͷϖʔδͰ࣮ߦ͞ΕɺώʔϓྖҬʹஔ͔Εͨ JavaScriptͷΦϒδΣΫτͷΛௐΔ͜ͱ͕ग़དྷΔ
Record Heap Allocations JavaScriptͷ࣮ߦͱͱʹ༻͞ΕΔϝϞϦͷ ׂͱղ์ͷঢ়ଶΛௐΔ͜ͱ͕ग़དྷΔ
JavaScriptͷ ߴԽηΦϦʔΛΔ
ArrayͷforEach()ΑΓforͰϧʔϓɹΞχϝʔγϣϯʹ requestAnimationFrame()ɹ“use strict”;Λ͏ɹ try/catchʢྫ֎ͷัଊʣॏ͍ɹparseInt()ΑΓՃݮԋ ࢉͰΩϟετ͢ΔɹDOMͷ୳ࡧૢ࡞࠷খݶʹɹ͍ؔͷ ΠϯϥΠϯԽɹeval()with()ΛΘͳ͍ɹnew Date()Α Γdate.now()ɹධՁॱͷɹਖ਼نදݱͷΩϟογϡɹॏ͍ ॲཧͷඇಉظԽ(WebWorker)ɹArrayͷforEach()ΑΓfor Ͱϧʔϓɹ
ΞχϝʔγϣϯʹrequestAnimationFrame()ɹ “use strict”;Λ͏ɹtry/catchʢྫ֎ͷัଊʣॏ͍ɹ parseInt()ΑΓՃݮԋࢉͰΩϟετ͢ΔɹDOMͷ୳ࡧૢ࡞ ࠷খݶʹɹ͍ؔͷΠϯϥΠϯԽɹeval()with()Λ Θͳ͍ɹnew Date()ΑΓdate.now()ɹධՁॱͷɹਖ਼ن දݱͷΩϟογϡɹॏ͍ॲཧͷඇಉظԽ(WebWorker)ɹetc…
JavaScript Garden http://bonsaiden.github.io/JavaScript-Garden/ja/
Don't Guess it, Test it! - Paul Lewis
jsPerf http://jsperf.com
GCΛආ͚Δ2ͭͷख๏
ΦϒδΣΫτϓʔϧ Θͳ͘ͳͬͨطఆͷܕͷΦϒδΣΫτΛϓʔϧ͠ ͦͷܕͷΦϒδΣΫτΛ࠶ར༻͢Δ
Object Pool
Object Pool Object
Object Pool Object
Object Pool Object Object
Object Pool Object Object
Object Pool Object Object ੜͨ͠ΦϒδΣΫτΛ ࠶ར༻͢Δ͜ͱͰ ϝϞϦͷ࠶ׂΛ͑Δ
Object Pools http://beej.us/blog/data/object-pool/
ελςΟοΫϝϞϦ ༻͢ΔશͯͷΦϒδΣΫτΛ͋Β͔͡ΊॳظԽͯ͠ ͏߹ʹͦͷΦϒδΣΫτ܈͔Βआ༻͢Δ
Object Pool
Object Pool Object Object Object Object
Object Pool Object Object Object Object ΦϒδΣΫτͷੜճΛ ݮΒ͢Ξϓϩʔν
ʲ൪֎ฤʳV8Τϯδϯͷ ࠷దԽΛ્͠ͳ͍
Design Elements https://developers.google.com/v8/design
Fast Property Access JITίϯύΠϧ࣌ʹ੩తͳΫϥεΛ࡞͠ JSͷίʔυΛಈతʹࢀর͢ΔͷͰͳ͘ ੜ͞ΕͨΫϥε(hidden class)Λߴʹࢀর͢Δ
Dynamic Machine Code Generation 1࣮ߦͨ͠ίʔυΛϚγϯίʔυʹίϯύΠϧ͠ ࣍ճҎ߱Ωϟογϡͨ͠ͷΛ࣮ߦ͢Δ (தؒόΠτίʔυΠϯλʔϓϦλΘͳ͍)
Ϋϥεͷఆ͕ٛ͋ͬͨΒ… function Point(x, y) { this.x = x; this.y =
y; }
Ϋϥεͷఆ͕ٛ͋ͬͨΒ… function Point(x, y) { this.x = x; this.y =
y; } JITίϯύΠϧ࣌ʹΫϥε ͷ੩తͳ࣮ଶΛੜ͢Δ function Point(x, y) { this.x = x; this.y = y; } Hidden Class
Ϋϥεͷఆ͕ٛ͋ͬͨΒ… function Point(x, y) { this.x = x; this.y =
y; } JITίϯύΠϧ࣌ʹΫϥε ͷ੩తͳ࣮ଶΛੜ͢Δ function Point(x, y) { this.x = x; this.y = y; } Hidden Class var point = new Point(); ͔࣍ΒίϯύΠϧࡁͷ ΫϥεΛࢀর͢ΔͷͰߴ
Ϋϥεͷఆ͕ٛ͋ͬͨΒ… function Point(x, y) { this.x = x; this.y =
y; } JITίϯύΠϧ࣌ʹΫϥε ͷ੩తͳ࣮ଶΛੜ͢Δ function Point(x, y) { this.x = x; this.y = y; } Hidden Class var point = new Point(); ͔࣍ΒίϯύΠϧࡁͷ ΫϥεΛࢀর͢ΔͷͰߴ
ఆٛΛ్தͰมߋ͢Δͱ… Point.name = 'Name';
function Point(x, y) { this.x = x; this.y = y;
} Point.name = 'Name'; Hidden ClassΛ ࠶ੜͯ͠͠·͏ Hidden Class ఆٛΛ్தͰมߋ͢Δͱ… Point.name = 'Name';
function Point(x, y) { this.x = x; this.y = y;
} Point.name = 'Name'; Hidden ClassΛ ࠶ੜͯ͠͠·͏ Hidden Class ఆٛΛ్தͰมߋ͢Δͱ… Point.name = 'Name'; ϒϥβ͕࣮ߦ࣌ʹ࠷దԽͨ͠ίʔυΛ ͳΔ͘มߋ͠ͳ͍Α͏ʹ͢Δʂ
·ͱΊ
ύϑΥʔϚϯεඞਢ ڥͷଟذԽߟྀ͢Δ
ϒϥβͷؾ࣋ͪΛΔ͜ͱ͕ ࠷దԽͷୈҰา
ۜͷؙଘࡏ͠ͳ͍ શͯ࠷దԽͷੵΈॏͶ
Thank you! @1000ch http://github.com/1000ch http://1000ch.net
Photo Credits • http://www.flickr.com/photos/66331098@N03/6041212579 • http://www.flickr.com/photos/danichro/7284517300 • http://www.flickr.com/photos/articnomad/16153058/ • http://www.flickr.com/photos/sfgirlbybay/2739327181/
• http://www.flickr.com/photos/30859306@N00/3331140550 • http://www.flickr.com/photos/45540741@N06/7365063522/ • http://www.flickr.com/photos/chrissinjo/5368405044 • http://www.flickr.com/photos/cloudy-day/5319042359 • http://www.flickr.com/photos/57490760@N04/7218896186