SlideShare a Scribd company logo
Browser Computing
Structure
Frontrend in Fukuoka
@1000ch
@1000ch
Frontend Developer
目次
変化するWebとJavaScriptの役割
ブラウザが何をしているかを知る
ブラウザが遅くなる原因を知る
最適化アプローチ
変化するWebと
JavaScriptの役割
• テキストベースのWebサイト
• コンテンツの更新は遷移が中心
• 装飾は<marquee>とか<blink>とか…
静的なWeb
• 非同期通信によるコンテンツの更新

(Googleマップ・Googleサジェスト等)
• JavaScriptがダイナミックなWebサイトの

可能性をHTMLにもたらした
動的なWeb
• HTML5やCSS3といった、

技術の標準化と飛躍的な進化
• ブラウザで出来ることが増えた

(WebGL・WebAudio・WebSocket…)
リッチなWeb
JavaScriptなしに
HTML5を語れない
対応の難しさ
ベンダーの数×OSのバージョン
に比例して増加する実装リスク
確か存在するコスト
マシンスペックに左右される上に

モバイル端末だとなおさら差が顕著
パフォーマンスが
犠牲になりがち
Amazon
100msの高速化
売上1%増加
Mozilla
Google
2200msの高速化
ダウンロード15.4%増加
400msの高速化
検索回数0.59%増加
パフォーマンスは

最も重要なUX指標
パフォーマンスはWebサイトの品質である
かっこよくても遅いサイトにユーザーは満足しない
ブラウザが

何をしているかを知る
データの要求とダウンロード
URLの入力やページ遷移等
HTML
レンダーツリーのレイアウトとペイント
ユーザーアクションの応答
クリックやスクロールのインタラクション
ユーザーアクションの応答
クリックやスクロールのインタラクション
データの要求とダウンロード
URL
HTMLやCSSの解析と描画
レンダーツリーのレイアウトとペイント
ユーザーアクションの応答
クリックやスクロールのインタラクション
データの要求とダウンロード
URL
HTML
レンダーツリーのレイアウトとペイント
ユーザーアクションの応答
クリックやスクロールのインタラクション
データの要求とダウンロード
URLの入力やページ遷移等
HTMLやCSSの解析と描画
レンダーツリーのレイアウトとペイント
データの要求とダウンロード
URL
HTML
レンダーツリーのレイアウトとペイント
ユーザーアクションの応答
クリックやスクロールのインタラクション
ページのロード開始から
表示されるまで
データの要求とダウンロード
URL
HTML
レンダーツリーのレイアウトとペイント
ユーザーアクションの応答
クリックやスクロールのインタラクション
ページが表示されてから
次の遷移までずっと
Render ComputeNetwork
パフォーマンスの3大要素
Render ComputeNetwork
ページ表示までのイニシャルコスト
→ファーストインプレッション
Render ComputeNetwork
スクロールの滑らかさやページ応答
→ユーザーの使い心地
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 Paintder Paint Load Sc
ブラウザの処理
16.67ms
Paint Paint
特に処理がないとき
16.67ms
20FPSのサンプル
http://codepen.io/paulirish/full/nkwKs
Browser Computing Structure
60FPSのサンプル
http://codepen.io/1000ch/full/KbLHh
Browser Computing Structure
ブラウザが

遅くなる原因を知る
Case#1 重い処理
時間がかかるとペイントも遅れる
Scriptが忙しいと…
Load Script Render Paintder Paint Load
16.67msに収まらない
Browser Computing Structure
Browser Computing Structure
Browser Computing Structure
Case#2 GC
Scriptの実行を止めてしまう
Garbage Collection?
• JavaScriptでは、メモリの割当と解放がJavaScriptのエ
ンジンによって自動で行われる。その仕組みがGarbage
Collectionである
• 最近の高水準言語にほとんど備わっている
• いわばルンバのような存在 by @ahomu
GC発生のタイミング
• ブラウザによって一定の周期で実行される他、メモリが少
なくなってきたり、不要なメモリが出現すると実行される
• JavaScriptでは実行のタイミングを直接コントロールす
る術はない
Window
A
B
D
CE
Window
A
B
D
CEGCの対象になる
GCの間はScriptが止まる
Load Render Paintder Paint GC Load
16.67msに収まらない
Script
Browser Computing Structure
Browser Computing Structure
Browser Computing Structure
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);
雪だるま式に増えるメモリ
A
C B
A
C B
参照が残ってしまい

GCで回収されない
A
C B
参照がなくなったので
メモリが開放される
参照関係の整理を!
一般的なフレームワークはこのような

イベントリスナのモデルに従っていることが多い
コンソール循環参照
タイマー クロージャ
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から発生するLoadやRenderも忘れない
最適化アプローチ
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
メモリリークのサンプル
http://1000ch.net/memleak
GCを避ける2つの手法
オブジェクトプール
使わなくなった既定の型のオブジェクトをプールし
その型のオブジェクトを再利用する
Object Pool
Object
Object
生成したオブジェクトを
再利用することで
メモリの再割当を抑える
Object Pools
http://beej.us/blog/data/object-pool/
スタティックメモリ
使用する全てのオブジェクトをあらかじめ初期化して
使う場合にはそのオブジェクト群から借用する
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;
}
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;
}
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

More Related Content

PDF
AngularJSでの非同期処理の話
PDF
AngularJSの高速化
PDF
Scotty を利用した "ゆるふわ" Web サービス作成
PDF
レスポンシブWebデザイン【発展編】
PDF
200k/sec
PDF
インラインSVGをつかって地図っぽいものをつくってみる
PDF
RESTful APIとしてのRailsとクライアントとしてのJavaScript
PDF
なぜ人は必死でjQueryを捨てようとしているのか
AngularJSでの非同期処理の話
AngularJSの高速化
Scotty を利用した "ゆるふわ" Web サービス作成
レスポンシブWebデザイン【発展編】
200k/sec
インラインSVGをつかって地図っぽいものをつくってみる
RESTful APIとしてのRailsとクライアントとしてのJavaScript
なぜ人は必死でjQueryを捨てようとしているのか

Similar to Browser Computing Structure (20)

PDF
JavaScript.Next Returns
PDF
Chrome Developer Toolsを使いこなそう!
PDF
アプリ開発の
PDF
大規模なJavaScript開発の話
PPTX
HTML5&API総まくり
PDF
第3回企業Webシステム開発セミナー「業務システムにHTML5を上手に取り入れるためには?」
PDF
Dist 29 gcp_serverless_web_app_development
KEY
HTML5でスマートフォン開発の理想と現実
PPTX
HTML5最新動向
PDF
Chrome DevTools.next
PDF
我が家のフロントエンド開発事情
KEY
Web App Framework at SwapSkills vol28
PDF
Firefox OS - Blaze Your Own Path
PDF
JavaScript.Next
PDF
最近のWeb関連技術の動向あれこれ
PDF
[GrapeCity Web TECH FORUM 2018]グレープシティJavaScript製品のご紹介 活用のコツと開発のポイント
PDF
The forefront of html5 implementation
PDF
Concentrated HTML5 & Attractive HTML5
PPTX
HTML5 on ASP.NET
PDF
ゲームだけじゃないHTML5
JavaScript.Next Returns
Chrome Developer Toolsを使いこなそう!
アプリ開発の
大規模なJavaScript開発の話
HTML5&API総まくり
第3回企業Webシステム開発セミナー「業務システムにHTML5を上手に取り入れるためには?」
Dist 29 gcp_serverless_web_app_development
HTML5でスマートフォン開発の理想と現実
HTML5最新動向
Chrome DevTools.next
我が家のフロントエンド開発事情
Web App Framework at SwapSkills vol28
Firefox OS - Blaze Your Own Path
JavaScript.Next
最近のWeb関連技術の動向あれこれ
[GrapeCity Web TECH FORUM 2018]グレープシティJavaScript製品のご紹介 活用のコツと開発のポイント
The forefront of html5 implementation
Concentrated HTML5 & Attractive HTML5
HTML5 on ASP.NET
ゲームだけじゃないHTML5
Ad

More from Shogo Sensui (17)

PDF
Web Standards Interop 2022
PDF
Introduction to Performance APIs
PDF
Web Standards 2018
PDF
The State of Web Components
PDF
Component of Web Frontend
PDF
Web フロントエンドの変遷とこれから
PDF
Introduction to Resource Hints
PDF
Web Components 2016 & Polymer v2
PDF
これからのJavaScriptの話
PDF
初心者のためのWeb標準技術
PDF
Introduction to Service Worker
PDF
We should optimize images
PDF
Web Components changes Web Development
PDF
Re-think about Web Performance
PDF
Brush up your Coding! 2013 winter
PDF
Brush up your Coding!
PDF
Functional JavaScript with Lo-Dash.js
Web Standards Interop 2022
Introduction to Performance APIs
Web Standards 2018
The State of Web Components
Component of Web Frontend
Web フロントエンドの変遷とこれから
Introduction to Resource Hints
Web Components 2016 & Polymer v2
これからのJavaScriptの話
初心者のためのWeb標準技術
Introduction to Service Worker
We should optimize images
Web Components changes Web Development
Re-think about Web Performance
Brush up your Coding! 2013 winter
Brush up your Coding!
Functional JavaScript with Lo-Dash.js
Ad

Browser Computing Structure