angularjsとfluxとriotjsと

42
AngularJSとFluxと RiotJSと 2015/10/28 GotandaJS # @mizuki_r

Upload: ryo-iinuma

Post on 22-Jan-2018

4.054 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: AngularJSとFluxとRiotJSと

AngularJSとFluxとRiotJSと

2015/10/28 GotandaJS # @mizuki_r

Page 2: AngularJSとFluxとRiotJSと

Profileaccount.

twitter: @mizuki_r github: ry_mizuki role.

フロントエンドエンジニア

tags.

AngularJS, RiotJS, Backbone,

hariko, angular-period, etc

Page 3: AngularJSとFluxとRiotJSと

Theme

• AngularJSで書いたアプリをFlux化した話

• Flux化したAngularJSアプリにRiotJS入れた話

Page 4: AngularJSとFluxとRiotJSと

AngularJSで書いたアプリをFlux化した話

Page 5: AngularJSとFluxとRiotJSと

What is Flux?

Page 6: AngularJSとFluxとRiotJSと

Flux’s architecture

https://facebook.github.io/flux/docs/overview.html

Page 7: AngularJSとFluxとRiotJSと

Flux’s architecture

• Facebookが提唱したアーキテクチャ

• データの流れを一方向に限定する

• Store, View, Dispatcherの責務がActionという単位で処理を回す

Page 8: AngularJSとFluxとRiotJSと

Flux’s architecture

https://github.com/facebook/flux/tree/master/examples/flux-todomvc/#structure-and-data-flow

Page 9: AngularJSとFluxとRiotJSと

Why Flux

Page 10: AngularJSとFluxとRiotJSと

Why Flux?• modelの管理に疲れた

• データ構造と責務分担の分類の考察

• 急なデータの変更、Viewの変更

• controllerでmodelを管理しがち

• modelとmodelの連携

• controllerの抽象化が雑に…

Page 11: AngularJSとFluxとRiotJSと

所謂MVCの運用には 高度な訓練と

高い意識が必要なのでは?

Page 12: AngularJSとFluxとRiotJSと

もっと低意識で運用したい!

Page 13: AngularJSとFluxとRiotJSと

I thought…

Page 14: AngularJSとFluxとRiotJSと

ぼくのかんがえたさいきょうの…• Dispatcherは自前でObserver定義 • ViewとActionCreator, Storeは一対

• ドメインの定義はViewにすべて移譲 • ActionCreatorは外部との連絡用

• API通信はngResourceをwrapしてrepositoryとして分離

• actionにする前にデータ整形を行うメソッドをかます

Page 15: AngularJSとFluxとRiotJSと

ぼくさいFlux arch

Page 16: AngularJSとFluxとRiotJSと

ぼくさいFlux arch

Page 17: AngularJSとFluxとRiotJSと

import * as action_creator from '../action-creators/example' import store from '../stores/example'

class ExampleCtrl { constructor ($scope) { this.onReceiveData = this.onReceiveData.bind(this) this.onDestroy = this.onDestroy.bind(this) store.addReceiveDataListener(this.onReceiveData) $scope.$on('$destroy', this.onDestroy) action_creator.init() } select () { action_creator.select() } onReceiveData () { this.data = store.getData() } onDestroy () { store.removeReceiveDataListener(this.onReceiveData) } }

angular.module('example').controller('ExampleCtrl', ExampleCtrl)

Page 18: AngularJSとFluxとRiotJSと

import dispatcher from '../dispatcher' import action_types from '../action-types' import injector from '../injector'

export function init () { dispatcher.handleViewAction({ type: action_types.INIT_EXAMPLE_VIEW, }) var Repository = injector.get('ExampleRepository') Repository.fetch().then((data) => { dispatcher.handleApiAction({ type: action_types.RECEIVE_EXAMPLE_DATA, data }) }) }

export function select () { dispatcher.handleViewAction({ type: action_types.SELECT_EXAMPLE_VIEW, }) var Repository = injector.get('ExampleRepository') Repository.post().then((data) => { dispatcher.handleApiAction({ type: action_types.POST_SELECT_EXAMPLE_DATA, data }) }) }

Page 19: AngularJSとFluxとRiotJSと

conclusion

• ViewをActionCreatorとStoreに抽象化できた

• コードが冗長になり、量が増えた

• 初期開発コストは高いが更新の手間などは減った

Page 20: AngularJSとFluxとRiotJSと

ViewをActionCreatorとStoreに抽象化できた

Page 21: AngularJSとFluxとRiotJSと

…あれ?

Page 22: AngularJSとFluxとRiotJSと

Angularじゃなくてもよくね?

Page 23: AngularJSとFluxとRiotJSと

Flux化したAngularJSアプリにRiotJS入れた話

Page 24: AngularJSとFluxとRiotJSと

What is RiotJS?

Page 25: AngularJSとFluxとRiotJSと

RiotJS

• Reactライクのユーザインタフェースライブラリ

• とっても小さい

• Virtual-DOM

• JavaScript in HTML

Page 26: AngularJSとFluxとRiotJSと

<todo>

<!-- layout --> <h3>{ opts.title }</h3>

<ul> <li each={ item, i in items }>{ item }</li> </ul>

<form onsubmit={ add }> <input> <button>Add #{ items.length + 1 }</button> </form>

<!-- logic --> <script> this.items = []

add(e) { var input = e.target[0] this.items.push(input.value) input.value = '' } </script>

</todo>

http://riotjs.com/ja/

Page 27: AngularJSとFluxとRiotJSと

ファイルサイズ

Reactの約1/19!

Page 28: AngularJSとFluxとRiotJSと

つまり…• 小さいし必要最小限の機能

• 細かいViewの制御なら十分なAPI

• 明示的な更新が可能なI/F

• Component系なので最小限の変更範囲

• 書きやすそうなJSX

Page 29: AngularJSとFluxとRiotJSと

Why is RiotJS?

Page 30: AngularJSとFluxとRiotJSと

AngularJSへの不満…

• $applyが重い

• 暗黙的な$digestの管理が辛い

Page 31: AngularJSとFluxとRiotJSと

$applyが遅い• 式を受け取りViewを更新するかを判定

• 更新する場合は`$scope.$digest()` を実行

• $http, $timeoutなどのAPIが内部的に利用

• 登録されているすべてのリスナを評価する

• 遅い評価式を登録してしまうと更新のたびに…

Page 32: AngularJSとFluxとRiotJSと

暗黙的な$digestが辛い• $http, $timeoutなどAPIが暗黙的に発行する

• 発行しないAPIもある

• 自前で作った機能は$scope.$apply等が必要

• たまたまうまく更新がされるケース

• digest中にdigestを発行すると死ぬ

Page 33: AngularJSとFluxとRiotJSと

つまり…• 特定のView以下で更新したい

• 短いサイクルでの更新

• 毎秒すべてのViewを評価してどうする

• 明示的に更新したい

• 必要ないところで評価されても

• 更新したいタイミングは僕らが決めたい

Page 34: AngularJSとFluxとRiotJSと

Angular with Riot

Page 35: AngularJSとFluxとRiotJSと

RiotJSの役割• 末端のViewの更新サイクルの管理

• 毎秒更新が発生するもの

• ホバーなどサイクルが短いもの

• ユーザアクションのハンドルと他のViewとの連携はFluxベースのアーキテクチャで吸収

• RiotからAngularのViewは参照しない

Page 36: AngularJSとFluxとRiotJSと

directive

angular.module('example', []).directive('todo', function () { return function () { riot.mount('todo') } })

directive化することで、templateから参照できる。

Page 37: AngularJSとFluxとRiotJSと

outside injector

exports.get = function (name) { return angular.element(document).injector().get(name) }

injectorをAngularの管理外から参照できるように

Page 38: AngularJSとFluxとRiotJSと

入れてみた結果• 「遅い」と言われてた部分が解消(体感的に)

• ぶっちゃけRiotJSが早いわけじゃない

• むしろ状況次第ではAngularより遅い

• $digest漏れや$applyの遅延による「遅く見える」が減少した

• RiotJS、以外と書きやすい

Page 39: AngularJSとFluxとRiotJSと

Conclusion

Page 40: AngularJSとFluxとRiotJSと

Conclusion• FluxによるViewの抽象化事例を紹介

• Viewの単位でコードを管理できるので、追加・更新・削除が思いの外簡単になった

• でもコード量は増えた

• AngularJSとRiotJSの共存事例を紹介

• 目に見えて反応が違った

• RiotJSは必要最小限で使う分にはかなり使い勝手良い

• 個人的にはRiotJSXはもっと使って行きたい

Page 41: AngularJSとFluxとRiotJSと

Next Generation• Fluxでの責務分担のあり方をもうちょっと考えたい

• いずれこれは二層式に集約されていくのだろうなと

• ServiceWorker上で扱えるレベルのロジックの抽象化

• メインスレッドを綺麗にしてUIのパフォーマンスあげたい

Page 42: AngularJSとFluxとRiotJSと

ご清聴ありがとうございました