new takyam();

Qiitaぽい話はQiitaに書いていくことにする気がする http://qiita.com/takyam

2013年はSPAの年・・・になるといいなぁ

自分は去年から小さく言い続けてるんですが、SPA(Single Page Application)が主流の時代が間違いなくくると思ってます。

Single-page application [en.wikipedia.org]
http://en.wikipedia.org/wiki/Single-page_application

細かい定義までは理解していませんが、基本的にはWEBアプリケーションにおいて、URL遷移なくすべて(or ほとんど)の機能を利用できるアプリケーションのことだと思ってます。

もう少し具体的にいうと、機能(ページ)遷移時のHTMLレンダリングはJavaScriptによって必要な分だけのDOMの再構築を行い、データの取得などクライアントサイドで完結しない部分については、サーバとAjaxなどを用いてJSONデータのやり取りなどで必要なデータを都度取得するような構成でもって作られたアプリケーションです。

URL遷移なく・・・と言いましたが、URL末尾のハッシュ(#hoge)が機能(=ページ)毎に変わる事が多いでしょうし、history backやSEO的な事を考えるならそうすべきです。

SPAの代表例は一時期のtwitterでしょうか。URL遷移なしで、「http://twitter.com/#!/takyam」の#!以降が変化してましたよね

で、このSPAですが、通常のWEBアプリケーションと比較した際の大きなメリットは、その高速な動作です。少なくとも理屈のうえでは高速です。

SPAが高速な理由を説明するまえに、まず、通常のWEBアプリケーションの動作をおさらいしておきましょう。

通常のWEBアプリケーションの動作の流れ

まず、通常のWEBアプリケーションの場合、画面遷移時に都度HTTPリクエストで、HTMLを要求します。

この時HTMLを要求されたサーバーサイドのアプリケーションは、ControllerがリクエストパラメータをもとにModelなどを使ってデータを処理したり取得したりします。
それらのデータをもとに、Viewの中でループ処理を行ったりしてHTMLを生成し、テンプレート(レイアウト)と合成してそれを返します。

HTMLを取得したクライアント(ブラウザ)は、HTML上に記載のある必要な外部リソース(JS/CSS/画像等)を、HTTPリクエストします。

リソース単位でHTTPリクエストが発生し、そのリソースの取得が終わるまで、サーバーと接続された状態になります。

その後、CSS、JSなどの処理が行われ、ページのレンダリングが終了します。

これらの処理が主流であり、枯れた技術であるともいえます。

HTTPリクエストは意外とハイコストなので、1つのページ(HMTL)内から100を超えるような外部リソースを読み込む場合、HTTPコネクションだけで無駄に重くなっているような状態になります。

それらの問題を解決するための技術も多数あり、

  • KeepAlived
  • CSS Sprite
  • JSのmin化
  • mod pagespeed
  • SPEEDY
  • 画像圧縮
  • gzip

などなど、本当にたくさんのプラクティスが存在します。

これらのある種、涙ぐましい努力による改善でなく、もう少し根本的に処理を変えてしまおうというアプローチのひとつがSPAです。たぶん。

SPAの場合の動作

まず、最初のページを表示するまでの動作は、通常のWEBアプリケーションとほぼ同じです。

サーバーサイドにHTMLをリクエストし、必要な外部リソースを取得、処理します。

2ページ目以降の表示時が、通常のWEBアプリケーションとは異なります。

検索にしろ、何かの新規追加などにしろ、ユーザ側のリクエストはAjax等でサーバへリクエストし、サーバーサイドのアプリケーションはリクエストを処理した結果をJSONで返します。

その後のDOMのレンダリングはJS側で行います。つまりサーバーサイドでのViewの生成が省略されたわけですね。

さらに、ページ遷移はしていませんから、追加での外部リソースの取得は最低限(新たに表示する事になった画像とか)でよく、いわゆるテンプレートやレイアウトと呼ばれる部分のDOMレンダリングは終わっているわけですから、必要最低限のDOMの更新ですむわけです。

さらに、SPAはHTTPリクエストの問題も解決するかもしれません。

SPA+Websocketで不要になるHTTPリクエスト

実際はSPAで、というわけではないのですが、Websocketを利用するSPAであれば初回ページ表示時と画像取得時以外はWebsocketでのやり取りで完結できるようになります。

最初のページを表示時にWebsocketでサーバと接続されている状態になれば、HTTPリクエストレスで、少なくともテキストデータをやり取りする事ができ、JSONのやり取りがHTTPリクエストレスになるという事です。”やり取り”というのが重要で、サーバーからでも、クライアントからでも、好きなタイミングでHTTPリクエストのコストを気にせずにJSONデータを贈り合う事ができます。素敵。

というわけで、少なくとも理屈の上では通常のWEBアプリケーションと比較してとても高速な事はわかっているのですが、なかなか流行る兆しを見せません。

理由は、開発の難しさのひとつに尽きると思います。

SPAが難しい理由

理由を挙げれば数限りないと思うのですが、パッと以下の4つが思いつきます。

  • Websocketを扱える言語が限られている
  • フレームワーク不足
  • スケールのし辛さ
  • Javascriptエンジニア不足

Websocketを扱える言語が限られてる

各言語、Websocketを扱うためのライブラリは用意されていますが、C10K問題を解決する必要がどうしても出てくるので、ノンブロッキングなイベント駆動でやんないとキッツイので、現実的にはNodeJSが最有力候補にあがってきます。

イベント駆動な開発というのは、Nodeだろうがそれ以外の言語のライブラリだろうが、慣れないときっついです。何も考えずにやっちゃうとネストが深くなっちゃうし、処理はわかりづらくなっちゃうし。同期処理も書けるけど書いちゃった瞬間にC10Kに対応できなくなっちゃうし。

後述するJavascriptエンジニア不足とあわせて、このへんもエンジニア不足というのは結構大きい問題かもしれませんね。

フレームワーク不足

RailsやCatalystといったような、キラーフレームワークが存在しないのは大きな問題だと思います。

SocketStream - GitHub
https://github.com/socketstream/socketstream

上記SocketStreamはかなりいい線いってるんですが、RailsというよりはSinatraのようなライトウェイトなSPAフレームワークという印象が強く、一人で開発するような場合には強力ですが、業務上で利用するにはちょっときついと思います。

それと、WEB上に情報が少ないので、結果自分でソース読まなきゃいけなくて、それはそれで勉強になるからいいのですが、業務上でゴリゴリというにはまだ早いような気がします。

これは一昼夜でどうこうなる問題ではないので、来年に期待したいところです。

スケールのし辛さ

スケールできないわけではないです。が、難しいです。

Socket.IO or WebSocket を AmazonELB でバランスする検証
http://d.hatena.ne.jp/Jxck/20120228/1330444857

上記記事など読んでいただければ雰囲気つかめるかと思いますが、LBでバランシングさえすれば良い通常のWEBアプリケーションと違い、Websocketのバランシングは現状ではかなり面倒くさかったりします。

本格的に使おうとするとこのへんもネックになってくると思います。

Javascriptエンジニア不足

Javascriptが使えないWEBエンジニアはほぼいないと言ってもいいくらい、JS使いは多いです。
が、より効率的なJSを書けるエンジニアは意外と少ないのではないでしょうか?

特に通常のアプリケーションと違って、いわゆるViewのレンダリング部分がほぼすべてクライアントサイドJSに依ることになりますので、単純にコード量が増え、処理も重くなります。

そこでメモリなどにも気を配りながらチューンしていく技術が求められたりします。たぶん。

そもそも効率的にクライアントサイドJSの開発を行うためのフレームワークの理解であったり、prototypeの理解であったり、そういったところまできちんと理解できてる人は少ないと思っています。

かくいう私も、そこまで深く理解しきれてるわけではなく、作ってみて重かったらチューンする、といったプロセスが必要になっています。

まだPCであればメモリにも余裕があるので割とザックリ作っても良いですが、スマホとかなると超大変みたいですし・・・。

Facebookアプリを、HTML5でどうしてサクサクにできたのか。Sencha Touch開発チームが用いた3つのテクニック
http://www.publickey1.jp/blog/12/facebookhtml5sencha_touch3.html

マーク・ザッカーバーグがHTML5は失敗だーみたいな事に反論する目的もあってSenchaTouchのチームがFacebookアプリをHTML5で作ってみた記事です。

記事の中で、IFRAMEを使ってDOMツリーを分割したりと、結構涙ぐましい努力をしてるみたいです。

たぶんこのレベルで、DOMやJSを理解できてるエンジニアって限られてますよね?

でも、たぶんこのへんの知識がないと、ネットワークトラフィックは軽くなっても、レンダリングやJSの処理で遅くなってしまっては、高速化のためにSPAフレームワークを使った意味がないですので、注意していきたいポイントではあります。

まとめ

というわけで、机上の空論になるかもしれない危険性をはらみつつ、ちゃんと作れれば、超高速なアプリケーションを作る事ができるSPAに未来を感じ続けてるわけです。

前述したSPAフレームワークSocketStreamの開発者たちは「Crazy Fast!(狂ったように速い!)」といっています。

Websocket+SPAはすぐに業務に使えるレベルで実用的ではないかもしれませんが、きっと!2013年は!きっと!きっと!良い感じになってくると信じています!

なんだかまとまりない感じになりましたが、このSPAへの期待を込めて、今年は終わりにしたいと思います。正月何か作らなきゃなぁと思ってるので、SocketStreamで汝は人狼なりや?でも作ってみようかと思ってます。できたら公開しますね。

ではでは皆様良いお年を。