中規模Angularアプリケーションの
再設計
Suguru Inatomi
bitbank LT Night #5
© bitbank inc.
2
Suguru Inatomi
@laco2net
今日のアジェンダ
3
© bitbank inc.
アジェンダ 4
● アーキテクチャ導入の話
● パフォーマンス改善の話
● 品質改善の話
アーキテクチャの話
5
課題なきアーキテクチャは
ただのアート
6
© bitbank inc.
bitbankアプリの大きな課題 7
● 状態管理の分散
○ Serviceごとに管理の仕方がバラバラ
● ビジネスロジックの点在
○ コンポーネントがロジックを持っている
© bitbank inc.
願望 8
● 状態管理の分散
○ 状態管理を一元化したい
● ビジネスロジックの点在
○ コンポーネントから切り出してまとめたい
○ 適切にモジュール分割したい
願望を叶えるための
構造を考える
9
© bitbank inc.
中規模Angularアーキテクチャ v1.1 10
© bitbank inc.
ベースになる原理原則 11
● Presentation Domain Separation (PDS)
○ プレゼンテーションとドメインの分離
● Single Responsibility Principle (SRP)
○ 単一責任の原則
● Stable Dependencies Principle (SDP)
○ 安定依存の原則
● Command Query Responsibility Segregation (CQRS)
○ コマンド・クエリ責務分離
● Single source of truth (SSOT)
○ 唯一の情報源
© bitbank inc.
つまりどういうこと? 12
● Presentation Domain Separation (PDS)
○ コンポーネントからビジネスロジックを切り出す
● Single Responsibility Principle (SRP)
○ サービスの役割を明確にして境界づける
● Stable Dependencies Principle (SDP)
○ ユースケース依存のモジュールとそうでないものを境界づける
● Command Query Responsibility Segregation
○ 状態を変更する経路を限定する
● Single source of truth
○ アプリケーションの状態を一元管理する
© bitbank inc.
Presentation Domain Separation 13
Presentation系とDomain系を分離
© bitbank inc.
Single Responsibility Principle 14
役割ごとにモジュールを分類
© bitbank inc.
Stable Dependencies Principle 15
より安定しているモジュールに依存する
© bitbank inc.
Command Query Responsibility Segregation 16
WriteOnlyのUsecaseと
ReadOnlyのQueryを
Componentが利用する
© bitbank inc.
Single source of truth 17
アプリケーションの状態は
Storeで管理する
© bitbank inc.
Usecase-Store-Query 18
● Storeの実装として @ngrx/store を採用
© bitbank inc.
NgRxと学習曲線の設計 19
● NgRxへの関心をStore層に閉じる
○ NgRxから別のライブラリに変えやすくする
○ NgRxを知らなくても開発に参加できるようにする
● 参考: システムの学習曲線とAngularアプリケーションの設計
© bitbank inc.
Work in Progress 20
● Presentationのモジュール化はがんばりすぎない
○ 効果が薄い
● PDSができたら60点(可)
○ PDSさえ出来ていればどうとでもなる
● Webのことだけ考える(bitbankの場合)
○ locationやwindowの抽象化に固執しない
● TypeScriptとして簡潔であることを重視する
○ AngularやRxJSを使いこなそうとしない
小休止
questions$
.pipe( takeUntil( timer(3分) ) )
.subscribe()
21
パフォーマンス改善の話
22
© bitbank inc.
やったこと 23
● バンドルサイズの削減
○ main.bundle.js: 1.96MB -> 1.29MB (gzip前)
● 一部CSSのインライン化
○ 起動前のローディング用のCSS
© bitbank inc.
バンドルサイズの削減内訳 24
● 脱lodash ( => lodash.XXX )
● 脱moment ( => dayjs )
● 脱SharedModule
● Angular v8.0 (Differential Loading)
○ 参考
© bitbank inc.
バンドルサイズ推移 25
© bitbank inc.
初期CSSのインライン化 26
● ローディングアニメーション用のCSS
● CSSのロードが終わるまでローディングが出なかった
● index.htmlにハードコード
○ ほぼ変わることのない部分
○ HTMLのサイズはそれほど問題ではない
© bitbank inc.
留意点 27
● bitbankのアプリの特殊性
○ ほぼ検索流入しない
○ リアルタイムデータ依存(SSRしない)
● 初期ロードパフォーマンスの重要度: 低
● アーキテクチャを犠牲にしてまで高速化するモチベーションはない
○ あるべき形でそれ相応のパフォーマンスであればOK
品質改善の話
28
© bitbank inc.
品質とは? 29
● バグが少ないアプリケーションを目指す
● アプリケーションの入口と出口で品質を担保する
○ 入口: デプロイ前にバグを除去する = テスト
○ 出口: デプロイ後にバグを検知する = 監視
© bitbank inc.
アプリケーションの監視 30
● エラーの発生を検知する
○ ツール: Sentry
● 検知できた例
○ リリース後に特定のブラウザでエラーが起きていた
■ Polyfill不足
○ `Cannot read property *** of undefined`
■ TypeScriptの型定義漏れ (Null Check)
© bitbank inc.
ノイズが多い問題 31
● どんなエラーも全部流れてくる
○ アプリケーション側でハンドルすべき例外
○ サードパーティJSがグローバルに投げるエラー
● 監視を運用するにはノイズを除去する必要がある
○ Slack通知が多すぎる
● 取り組み
○ 例外処理の見直し
○ HTTPリクエストにリトライを導入
○ 通知すべきエラーのフィルター設定
まとめ
32
© bitbank inc.
Takeaway 33
● アーキテクチャは割り切りとコスパが大事
○ 例:「PDSさえできてれば合格」
● 守破離。まずは歴史に学び、原理原則を知る
● moment.jsやlodashの利用は計画的に
● SharedModuleが許されるのは小規模アプリまで
● アプリケーションの監視は重要
○ 実行時エラーに気づける仕組みを作る

中規模Angularアプリケーションの再設計

  • 1.
  • 2.
    © bitbank inc. 2 SuguruInatomi @laco2net
  • 3.
  • 4.
    © bitbank inc. アジェンダ4 ● アーキテクチャ導入の話 ● パフォーマンス改善の話 ● 品質改善の話
  • 5.
  • 6.
  • 7.
    © bitbank inc. bitbankアプリの大きな課題7 ● 状態管理の分散 ○ Serviceごとに管理の仕方がバラバラ ● ビジネスロジックの点在 ○ コンポーネントがロジックを持っている
  • 8.
    © bitbank inc. 願望8 ● 状態管理の分散 ○ 状態管理を一元化したい ● ビジネスロジックの点在 ○ コンポーネントから切り出してまとめたい ○ 適切にモジュール分割したい
  • 9.
  • 10.
  • 11.
    © bitbank inc. ベースになる原理原則11 ● Presentation Domain Separation (PDS) ○ プレゼンテーションとドメインの分離 ● Single Responsibility Principle (SRP) ○ 単一責任の原則 ● Stable Dependencies Principle (SDP) ○ 安定依存の原則 ● Command Query Responsibility Segregation (CQRS) ○ コマンド・クエリ責務分離 ● Single source of truth (SSOT) ○ 唯一の情報源
  • 12.
    © bitbank inc. つまりどういうこと?12 ● Presentation Domain Separation (PDS) ○ コンポーネントからビジネスロジックを切り出す ● Single Responsibility Principle (SRP) ○ サービスの役割を明確にして境界づける ● Stable Dependencies Principle (SDP) ○ ユースケース依存のモジュールとそうでないものを境界づける ● Command Query Responsibility Segregation ○ 状態を変更する経路を限定する ● Single source of truth ○ アプリケーションの状態を一元管理する
  • 13.
    © bitbank inc. PresentationDomain Separation 13 Presentation系とDomain系を分離
  • 14.
    © bitbank inc. SingleResponsibility Principle 14 役割ごとにモジュールを分類
  • 15.
    © bitbank inc. StableDependencies Principle 15 より安定しているモジュールに依存する
  • 16.
    © bitbank inc. CommandQuery Responsibility Segregation 16 WriteOnlyのUsecaseと ReadOnlyのQueryを Componentが利用する
  • 17.
    © bitbank inc. Singlesource of truth 17 アプリケーションの状態は Storeで管理する
  • 18.
    © bitbank inc. Usecase-Store-Query18 ● Storeの実装として @ngrx/store を採用
  • 19.
    © bitbank inc. NgRxと学習曲線の設計19 ● NgRxへの関心をStore層に閉じる ○ NgRxから別のライブラリに変えやすくする ○ NgRxを知らなくても開発に参加できるようにする ● 参考: システムの学習曲線とAngularアプリケーションの設計
  • 20.
    © bitbank inc. Workin Progress 20 ● Presentationのモジュール化はがんばりすぎない ○ 効果が薄い ● PDSができたら60点(可) ○ PDSさえ出来ていればどうとでもなる ● Webのことだけ考える(bitbankの場合) ○ locationやwindowの抽象化に固執しない ● TypeScriptとして簡潔であることを重視する ○ AngularやRxJSを使いこなそうとしない
  • 21.
  • 22.
  • 23.
    © bitbank inc. やったこと23 ● バンドルサイズの削減 ○ main.bundle.js: 1.96MB -> 1.29MB (gzip前) ● 一部CSSのインライン化 ○ 起動前のローディング用のCSS
  • 24.
    © bitbank inc. バンドルサイズの削減内訳24 ● 脱lodash ( => lodash.XXX ) ● 脱moment ( => dayjs ) ● 脱SharedModule ● Angular v8.0 (Differential Loading) ○ 参考
  • 25.
  • 26.
    © bitbank inc. 初期CSSのインライン化26 ● ローディングアニメーション用のCSS ● CSSのロードが終わるまでローディングが出なかった ● index.htmlにハードコード ○ ほぼ変わることのない部分 ○ HTMLのサイズはそれほど問題ではない
  • 27.
    © bitbank inc. 留意点27 ● bitbankのアプリの特殊性 ○ ほぼ検索流入しない ○ リアルタイムデータ依存(SSRしない) ● 初期ロードパフォーマンスの重要度: 低 ● アーキテクチャを犠牲にしてまで高速化するモチベーションはない ○ あるべき形でそれ相応のパフォーマンスであればOK
  • 28.
  • 29.
    © bitbank inc. 品質とは?29 ● バグが少ないアプリケーションを目指す ● アプリケーションの入口と出口で品質を担保する ○ 入口: デプロイ前にバグを除去する = テスト ○ 出口: デプロイ後にバグを検知する = 監視
  • 30.
    © bitbank inc. アプリケーションの監視30 ● エラーの発生を検知する ○ ツール: Sentry ● 検知できた例 ○ リリース後に特定のブラウザでエラーが起きていた ■ Polyfill不足 ○ `Cannot read property *** of undefined` ■ TypeScriptの型定義漏れ (Null Check)
  • 31.
    © bitbank inc. ノイズが多い問題31 ● どんなエラーも全部流れてくる ○ アプリケーション側でハンドルすべき例外 ○ サードパーティJSがグローバルに投げるエラー ● 監視を運用するにはノイズを除去する必要がある ○ Slack通知が多すぎる ● 取り組み ○ 例外処理の見直し ○ HTTPリクエストにリトライを導入 ○ 通知すべきエラーのフィルター設定
  • 32.
  • 33.
    © bitbank inc. Takeaway33 ● アーキテクチャは割り切りとコスパが大事 ○ 例:「PDSさえできてれば合格」 ● 守破離。まずは歴史に学び、原理原則を知る ● moment.jsやlodashの利用は計画的に ● SharedModuleが許されるのは小規模アプリまで ● アプリケーションの監視は重要 ○ 実行時エラーに気づける仕組みを作る