Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
1 SPAアプリの パフォーマンス改善入門 with Angular HRMOS事業部 プロダクト開発 フロントエンドエンジニア 黒田学人
Slide 2
Slide 2 text
2 自己紹介
Slide 3
Slide 3 text
3 黒田学人... ● Web系の受託会社 ○ LAMP ○ Backbone.js ● Vancouver / Canada ○ Art School ■ デザイン学んだり ■ 仕事したり ● BizReach ○ HRMOS事業部 フロントエンドエ ンジニア ○ Angular
Slide 4
Slide 4 text
4 フロントエンドの パフォーマンス改善とは
Slide 5
Slide 5 text
5 パフォーマンスはUXの重要な要素
Slide 6
Slide 6 text
6 ユーザー第一に考える
Slide 7
Slide 7 text
7
Slide 8
Slide 8 text
8 RAILパフォーマンスモデル
Slide 9
Slide 9 text
9 ● R : Responseは100ms未満になるように ● A : Animationは16ms毎になるように ● I : Idleは100ms未満で起きるように ● L : Loadは1000ms未満に終わるように
Slide 10
Slide 10 text
10 ● ページのロードから表示されるまで ○ データダウンロード ○ レンダリングツリーのレイアウト ● ページが表示されてからの動き ○ レンダリングツリーのレイアウト、ペイント ○ ユーザーのアクション ○ JavaSriptの実行コスト
Slide 11
Slide 11 text
11 ● ページのロードから表示されるまで ○ データダウンロード ○ レンダリングツリーのレイアウト ● ページが表示されてからの動き ○ レンダリングツリーのレイアウト、ペイント ○ ユーザーのアクション ○ JavaSriptの実行コスト
Slide 12
Slide 12 text
12 ユーザーの使い心地にフォーカス
Slide 13
Slide 13 text
13 ブラウザはなぜ遅くなるのか?
Slide 14
Slide 14 text
14 Scriptに負荷がかかると遅い
Slide 15
Slide 15 text
15
Slide 16
Slide 16 text
16 JavaScriptのメモリリーク
Slide 17
Slide 17 text
17 ● 不要になったオブジェクトがメモリ領域に存在するこ と ● メモリ領域が圧迫されることで、ブラウザの実行速 度が著しく低下する ● メモリの回収はGCが動いた時 ● リロードしたからって全てが回収されるわけではない
Slide 18
Slide 18 text
18 オブジェクトのライフサイクル
Slide 19
Slide 19 text
19 Root Node
Slide 20
Slide 20 text
20 どのタイミングで開放されるの?
Slide 21
Slide 21 text
21 Root Node
Slide 22
Slide 22 text
22 Root Node
Slide 23
Slide 23 text
23 Root Node
Slide 24
Slide 24 text
24 メモリリークのパターン
Slide 25
Slide 25 text
25 コンソール タイマー クロージャ 循環参照 (DOM)
Slide 26
Slide 26 text
26 コンソール タイマー クロージャ 循環参照 (DOM)
Slide 27
Slide 27 text
27
Slide 28
Slide 28 text
28 コンソール タイマー クロージャ 循環参照 (DOM)
Slide 29
Slide 29 text
29
Slide 30
Slide 30 text
30
Slide 31
Slide 31 text
31
Slide 32
Slide 32 text
32 コンソール タイマー クロージャ 循環参照 (DOM)
Slide 33
Slide 33 text
33 JavaScriptの関数は、その関数が定義されたコンテキ ストとは異なるコンテキスト上にある変数に格納される 時、その関数自身および関数の定義時のコンテキストが 一体になった「クロージャ」という特殊なオブジェクトにな る。
Slide 34
Slide 34 text
34 わかりづらっ!!
Slide 35
Slide 35 text
35
Slide 36
Slide 36 text
36
Slide 37
Slide 37 text
37
Slide 38
Slide 38 text
38
Slide 39
Slide 39 text
39
Slide 40
Slide 40 text
40 アクティベーションオブジェクト
Slide 41
Slide 41 text
41 アクティベーションオブジェクトとは関数のコールが発生 した際に、自動的に生成されるオブジェクト。アクティベー ションオブジェクトには、引数、ローカル変数だけでなく、 argumentsオブジェクト、thisが格納される。
Slide 42
Slide 42 text
42
Slide 43
Slide 43 text
43 生成される アクティベーションオブジェクト { arguments:, this:, foo:, bar:, baz:, qux: }
Slide 44
Slide 44 text
44 スコープチェーン
Slide 45
Slide 45 text
45 スコープチェーンとは、変数の参照を解決する際にアク ティベーションオブジェクトを辿る仕組み
Slide 46
Slide 46 text
46 アクティベーションオブジェクト argument this アクティベーションオブジェクト argument this localBar グローバル変数 globalBar
Slide 47
Slide 47 text
47 アクティベーションオブジェクト argument this アクティベーションオブジェクト argument this localBar グローバル変数 globalBar
Slide 48
Slide 48 text
48 変数fに対し、明示的にnullをセットしない限り、hoge()内 部のアクティベーションオブジェクトは保持され続ける。
Slide 49
Slide 49 text
49 コンソール タイマー クロージャ 循環参照 (DOM)
Slide 50
Slide 50 text
50
Slide 51
Slide 51 text
51
Slide 52
Slide 52 text
52 element(DOM) -> onclick(DOM) -> function(script) -> element(DOM)
Slide 53
Slide 53 text
53
Slide 54
Slide 54 text
54
Slide 55
Slide 55 text
55 WeakMap()
Slide 56
Slide 56 text
56 WeakMapは、キーに弱参照を保持できる。 弱参照はGCによって利用されているとみなされないの で、自動的に解放される。
Slide 57
Slide 57 text
57 DOM要素に何か値を持たせたいけども、 DOM要素のプロパティを汚したくないときにWeakMapを 利用できる。
Slide 58
Slide 58 text
58
Slide 59
Slide 59 text
59 メモリリークを見つけるには
Slide 60
Slide 60 text
60
Slide 61
Slide 61 text
61 ● タスクマネージャー ○ ページで現在使用されているメモリ量を調べる ● Performance (Timeline) ○ メモリの使用量を時系列に表示 ● Profiles ○ デタッチされた DOM ツリー(メモリリークの一般的な原因)を特定
Slide 62
Slide 62 text
62 ● タスクマネージャー ○ ページで現在使用されているメモリ量を調べる ● Performance (Timeline) ○ メモリの使用量を時系列に表示 ● Profiles ○ デタッチされた DOM ツリー(メモリリークの一般的な原因)を特定
Slide 63
Slide 63 text
63
Slide 64
Slide 64 text
64
Slide 65
Slide 65 text
65 ● Memory ○ ネイティブメモリを表す。DOM のノードはネイティブメモリに格納され、この 値が増えている場合は、DOM のノードが作成されている。 ● JavaScript Memory ○ JS ヒープを表す。基本的に見るのはライブ数値(かっこ内のやつ)。 ライブ 数値は、ページ上のアクセス可能なオブジェクトが使用中のメモリ量を表し ている。 この数値が増えている場合は、新しいオブジェクトが作成されてい るか、既存のオブジェクトが拡大している。
Slide 66
Slide 66 text
66 ● タスクマネージャー ○ ページで現在使用されているメモリ量を調べる ● Performance (Timeline) ○ メモリの使用量を時系列に表示 ● Profiles ○ デタッチされた DOM ツリー(メモリリークの一般的な原因)を特定
Slide 67
Slide 67 text
67
Slide 68
Slide 68 text
68
Slide 69
Slide 69 text
69 1. FPS 1 秒あたりのフレーム数。緑色の棒グラフが高いほど、FPS も高くなる。グラフ上部の赤いブロックは時間がかかって いるフレームを示し、問題を含んでいる可能性がある。 2. CPU CPU リソース 3. NET ネットワークリソース。棒グラフが長いほどダウンロードに時間がかかっている。
Slide 70
Slide 70 text
70 ● Keep 60 FPS ○ ブラウザは1秒間に60回リフレッシュする ○ 60FPSのためには、1フレームあたり16.67msに抑える必要がある ○ 一般的には30FPS出てればいい感じらしい
Slide 71
Slide 71 text
71
Slide 72
Slide 72 text
72
Slide 73
Slide 73 text
73 ● JS Heap ● Documents ● Nodes ● Listeners ● GPU
Slide 74
Slide 74 text
74
Slide 75
Slide 75 text
75
Slide 76
Slide 76 text
76
Slide 77
Slide 77 text
77
Slide 78
Slide 78 text
78
Slide 79
Slide 79 text
79
Slide 80
Slide 80 text
80 ● タスクマネージャー ○ ページで現在使用されているメモリ量を調べる ● Performance (Timeline) ○ メモリの使用量を時系列に表示 ● Profiles ○ デタッチされた DOM ツリー(メモリリークの一般的な原因)を特定
Slide 81
Slide 81 text
81
Slide 82
Slide 82 text
82
Slide 83
Slide 83 text
83
Slide 84
Slide 84 text
84 ● Distance ○ GC rootからの距離。Windowオブジェクトからの距離 ● Object Counts ○ オブジェクト数 ● Shallow Size ○ 直接参照されているオブジェクトのデータサイズ ● Retained Size ○ 参照されている全てのオブジェクトの総データサイズ
Slide 85
Slide 85 text
85
Slide 86
Slide 86 text
86
Slide 87
Slide 87 text
87 AngularJSの メモリリーク対策
Slide 88
Slide 88 text
88 ● Event Handlerを解放してあげる ● Watcherを解放してあげる ● Serviceのコールバック内で$scopeを使わない
Slide 89
Slide 89 text
89 ● Event Handlerを解放してあげる ● Watcherを解放してあげる ● Serviceのコールバック内で$scopeを使わない
Slide 90
Slide 90 text
90
Slide 91
Slide 91 text
91
Slide 92
Slide 92 text
92 ● Event Handlerを解放してあげる ● Watcherを解放してあげる ● Serviceのコールバック内で$scopeを使わない
Slide 93
Slide 93 text
93
Slide 94
Slide 94 text
94
Slide 95
Slide 95 text
95 ● Event Handlerを解放してあげる ● Watcherを解放してあげる ● Serviceのコールバック内で$scopeを使わない
Slide 96
Slide 96 text
96
Slide 97
Slide 97 text
97
Slide 98
Slide 98 text
98 ● Third Parties
Slide 99
Slide 99 text
99
Slide 100
Slide 100 text
100
Slide 101
Slide 101 text
101 Angular2の メモリリーク対策
Slide 102
Slide 102 text
102
Slide 103
Slide 103 text
103
Slide 104
Slide 104 text
104
Slide 105
Slide 105 text
105
Slide 106
Slide 106 text
106 Change Detectionをスキップして高速化
Slide 107
Slide 107 text
107
Slide 108
Slide 108 text
108
Slide 109
Slide 109 text
109
Slide 110
Slide 110 text
110 イベントが起こると毎回すべてのコンポーネントで Chande Detectionを走らせなければならない
Slide 111
Slide 111 text
111
Slide 112
Slide 112 text
112 チェックの回数を減らしたい
Slide 113
Slide 113 text
113 Immutable オブジェクト
Slide 114
Slide 114 text
114
Slide 115
Slide 115 text
115
Slide 116
Slide 116 text
116
Slide 117
Slide 117 text
117 Observable オブジェクト
Slide 118
Slide 118 text
118 ImmutableのようにObservableは変更があっても 新しい参照は与えられない。その代わりに変更に反応 するためにsubscribeが使用できる。
Slide 119
Slide 119 text
119
Slide 120
Slide 120 text
120
Slide 121
Slide 121 text
121 どうすればAngularに変更を知らせることができる?
Slide 122
Slide 122 text
122
Slide 123
Slide 123 text
123
Slide 124
Slide 124 text
124 NgZoneでChande Detectionが走っているか確認
Slide 125
Slide 125 text
125
Slide 126
Slide 126 text
126 angular-performance-checklist https://github.com/mgechev/angular-performance-checklist#runtime-optimizations
Slide 127
Slide 127 text
127 UI / UXのチューニング
Slide 128
Slide 128 text
128 振る舞いやUIを変更することで ユーザーの体感速度を上げること
Slide 129
Slide 129 text
129 ● RAILパフォーマンスモデルでは、ユーザーのアクショ ンに対するレスポンスの指標は100ミリ秒以内 ● ロードが始まってからユーザーが操作可能になるまで の時間は1000ミリ秒以内にすべき
Slide 130
Slide 130 text
130 1秒を超えるような処理や読み込みを行う場合には、待 ち時間であることを表すインジケータやアニメーションな どを返してあげること。 そして、ユーザーに待たされている感覚を与えないこと。
Slide 131
Slide 131 text
131 ● インターフェイスプレビュー ○ ローディング中に仮のコンテンツを表示しておく ● ローディングアニメーション ○ マイクロインタラクション
Slide 132
Slide 132 text
132
Slide 133
Slide 133 text
133
Slide 134
Slide 134 text
134
Slide 135
Slide 135 text
135 New Relic Browserで SPA監視
Slide 136
Slide 136 text
136
Slide 137
Slide 137 text
137 定期的に観測することで、問題のあるページ、処理を洗 い出したい
Slide 138
Slide 138 text
138 ● Ajaxのレスポンスタイムパフォーマンス ● ページレンダリングの時間がわかる ○ 遅いページが大体わかる ● ブラウザ毎のパフォーマンスがわかる ● エラー監視
Slide 139
Slide 139 text
139