Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

AngularJSとFluxとRiotJSと

4,597 views

Published on

http://gotandajs.connpass.com/event/20838/ で話した資料です

Published in: Technology
  • Be the first to comment

  • Be the first to like this

AngularJSとFluxとRiotJSと

  1. 1. AngularJSとFluxと RiotJSと 2015/10/28 GotandaJS # @mizuki_r
  2. 2. Profile account. twitter: @mizuki_r github: ry_mizuki role. フロントエンドエンジニア tags. AngularJS, RiotJS, Backbone, hariko, angular-period, etc
  3. 3. Theme • AngularJSで書いたアプリをFlux化した話 • Flux化したAngularJSアプリにRiotJS入れた話
  4. 4. AngularJSで書いたアプリ をFlux化した話
  5. 5. What is Flux?
  6. 6. Flux s architecture https://facebook.github.io/flux/docs/overview.html
  7. 7. Flux s architecture • Facebookが提唱したアーキテクチャ • データの流れを一方向に限定する • Store, View, Dispatcherの責務がActionという 単位で処理を回す
  8. 8. Flux s architecture https://github.com/facebook/flux/tree/master/examples/flux-todomvc/#structure-and-data-flow
  9. 9. Why Flux
  10. 10. Why Flux? • modelの管理に疲れた • データ構造と責務分担の分類の考察 • 急なデータの変更、Viewの変更 • controllerでmodelを管理しがち • modelとmodelの連携 • controllerの抽象化が雑に…
  11. 11. 所謂MVCの運用には 高度な訓練と 高い意識が必要なのでは?
  12. 12. もっと低意識で運用したい!
  13. 13. I thought…
  14. 14. ぼくのかんがえたさいきょうの… • Dispatcherは自前でObserver定義 • ViewとActionCreator, Storeは一対 • ドメインの定義はViewにすべて移譲 • ActionCreatorは外部との連絡用 • API通信はngResourceをwrapしてrepository として分離 • actionにする前にデータ整形を行うメソッドを かます
  15. 15. ぼくさいFlux arch
  16. 16. ぼくさいFlux arch
  17. 17. 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)
  18. 18. 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 }) }) }
  19. 19. conclusion • ViewをActionCreatorとStoreに抽象化できた • コードが冗長になり、量が増えた • 初期開発コストは高いが更新の手間などは減っ た
  20. 20. ViewをActionCreatorと Storeに抽象化できた
  21. 21. …あれ?
  22. 22. Angularじゃなくてもよくね?
  23. 23. Flux化したAngularJSアプ リにRiotJS入れた話
  24. 24. What is RiotJS?
  25. 25. RiotJS • Reactライクのユーザインタフェースライブラリ • とっても小さい • Virtual-DOM • JavaScript in HTML
  26. 26. <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/
  27. 27. ファイルサイズ Reactの約1/19!
  28. 28. つまり… • 小さいし必要最小限の機能 • 細かいViewの制御なら十分なAPI • 明示的な更新が可能なI/F • Component系なので最小限の変更範囲 • 書きやすそうなJSX
  29. 29. Why is RiotJS?
  30. 30. AngularJSへの不満… • $applyが重い • 暗黙的な$digestの管理が辛い
  31. 31. $applyが遅い • 式を受け取りViewを更新するかを判定 • 更新する場合は`$scope.$digest()` を実行 • $http, $timeoutなどのAPIが内部的に利用 • 登録されているすべてのリスナを評価する • 遅い評価式を登録してしまうと更新のたびに…
  32. 32. 暗黙的な$digestが辛い • $http, $timeoutなどAPIが暗黙的に発行する • 発行しないAPIもある • 自前で作った機能は$scope.$apply等が必要 • たまたまうまく更新がされるケース • digest中にdigestを発行すると死ぬ
  33. 33. つまり… • 特定のView以下で更新したい • 短いサイクルでの更新 • 毎秒すべてのViewを評価してどうする • 明示的に更新したい • 必要ないところで評価されても • 更新したいタイミングは僕らが決めたい
  34. 34. Angular with Riot
  35. 35. RiotJSの役割 • 末端のViewの更新サイクルの管理 • 毎秒更新が発生するもの • ホバーなどサイクルが短いもの • ユーザアクションのハンドルと他のViewとの連 携はFluxベースのアーキテクチャで吸収 • RiotからAngularのViewは参照しない
  36. 36. directive angular.module('example', []).directive('todo', function () { return function () { riot.mount('todo') } }) directive化することで、templateから参照できる。
  37. 37. outside injector exports.get = function (name) { return angular.element(document).injector().get(name) } injectorをAngularの管理外から参照できるように
  38. 38. 入れてみた結果 • 「遅い」と言われてた部分が解消(体感的に) • ぶっちゃけRiotJSが早いわけじゃない • むしろ状況次第ではAngularより遅い • $digest漏れや$applyの遅延による「遅く見え る」が減少した • RiotJS、以外と書きやすい
  39. 39. Conclusion
  40. 40. Conclusion • FluxによるViewの抽象化事例を紹介 • Viewの単位でコードを管理できるので、追加・更新・削 除が思いの外簡単になった • でもコード量は増えた • AngularJSとRiotJSの共存事例を紹介 • 目に見えて反応が違った • RiotJSは必要最小限で使う分にはかなり使い勝手良い • 個人的にはRiotJSXはもっと使って行きたい
  41. 41. Next Generation • Fluxでの責務分担のあり方をもうちょっと考え たい • いずれこれは二層式に集約されていくのだろう なと • ServiceWorker上で扱えるレベルのロジック の抽象化 • メインスレッドを綺麗にしてUIのパフォーマン スあげたい
  42. 42. ご清聴ありがとうございました

×