AngularJSとFluxとRiotJSと

3,013 views

Published on

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

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
3,013
On SlideShare
0
From Embeds
0
Number of Embeds
1,863
Actions
Shares
0
Downloads
2
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

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. ご清聴ありがとうございました

×