操作方法
- l キー: 次のページへ
- h キー: 前のページへ
- j キー: 目次ページへ
- k キー: 目次ページから戻る
- 目次ページでは j k キーで一覧を移動し、クリックで選択します
モダン WebUI の章
Yappo: yappo あっと shibuya.pl
Shibuya Perl Mongers
自己紹介
- 大沢和宏
- Perl Hacker
- CPAN Author
- Farmer
最近は
- OSDC.tw 2010
- Yokohama.PM #6
- YAPC::Asia 2010
- Fukuoka.PM
- BPStudy #39で発表なう
- Shibuya.PM #15で発表予定
現在Web+DB PRESSにて
WebUIの連載をやっています
そのほか会社で
Ficiaというフォトストレージ
サービスをやっています
今回のテーマ
LDRやPhotoshop Express等のように、デスクトップアプリケーションをWeb上で提供するサービスが増えていますが、それらのアプリケーションはどう作ったら良いかという話をします。
今回のテーマ
具体的にはFiciaをどんな感じで作っているのかと言うのを話します。
目次
- 目指す方向と問題点
- データ量の増大にどう対応するか
- どうするイベント通知
目指す方向
- 全てのデータはWebへ
- 操作感はキビキビ早く
- ユーザを待たせない
解決すべき問題を見つける
- どのようなデータを取り扱うWebアプリを作るのか明確に
- そのデータをWebにアップロードする方法は、何が一番楽かを考える
回線やサーバ処理速度につい
ては基本すぎなので触れない
Ficiaでは...
- 撮影した写真を全部保存するストレージサービス
- PCにデジカメのカードが繋がった時に、カードの中の写真を全部アップロード
- 一度あげたデータは二度とアップロードしない
専用クライアントを
PCにインストールして
意識せずデータを
Webにあげられる
Webサービスだからといって全部ブラウザの中だけで完結せずに、必要ならば専用クライアントを作るくらいの柔軟さも重要
これが達成できれば何でもいい
- 全てのデータはWebへ
- 操作感はキビキビ早く
- ユーザを待たせない
ここまでは、全てのデータを
Webに上げる良い方法の話
ふつうのWeb
- MVCは全てserver side
- 画面遷移のたびにhtmlをサーバから取ってくる
例えば写真サイト
- ユーザが見たいのは画像のみ
- 普通は次の写真をどんどん見たい
- 極端に言うと画像だけ変われば良い
- 次の写真を見る時にHTMLまで作るのは無駄
例えばこうする
- 次の写真を見るリンクを踏んだら、Ajax等を使って次の写真の画像URLだけを受け取る
- 画像URLを受け取ったら、その時見ていた写真のIMGタグのsrc要素を新しい画像URLに差し替える
サーバ側にModelとController
を置いて、ブラウザ側で
Viewを実装するイメージ
予め次の写真を先読みする
事で、さらに早く表示できる
Pros :)
- サーバ側でHTMLの動的生成をしないので負荷が減る
- データ転送量も大幅に減る
- ブラウザのレンダリング変更する場所も限定的
- 結果的に高速に次の写真が表示される
Cons ;(
- permalinkが無くなる(詳細は次ページ)
- サーチエンジンなどのbotがリンク辿れなくなる
- そもそもJavaScriptが動く環境じゃないと使えない
permalink問題は、googleなどが"#! が含まれる URL を hash を含まないものに読み替える仕組みを提唱している"(参考:kazuhoのメモ置き場)
目次
- 目指す方向と問題点
- データ量の増大にどう対応するか
- どうするイベント通知
サムネイル一覧
一般的な写真サイトでは、上がっている写真を一覧で見る機能がついています。
Ficiaの物を見てみましょう。
画面遷移の無い一覧表示
Ficiaでも、Ajaxを駆使して画面遷移無く写真の閲覧が出来るようになっていますが、1万件も写真があると普通に実装してしまうと困った事になる
ハマりどころ
- 1万件全部が増を表示したらブラウザ重い
- 1万件分のデータをAjaxで取ったら遅い
必要な所だけを表示すべき
- 多量に表示すべきデータがあっても、画面の大きさは有限
- 画面に見えない部分を一生懸命レンダリングしてもリソースの無駄
Ficiaでは...
- どのサムネイルが画面で表示されるかを常に計算して、表示される部分だけのDOMを作っている
- スクロールした瞬間に不要なDOMを消している
- とても縦長な空白のDOMを伸び縮みさせる事で違和感無くしている
Ajaxリクエストにページングを
- 必要な所だけ描画しても、1万件分のJSONを一気にダウンロードしたら遅くなる
- 表示に必要な部分だけの小さなJSONをダウンロードさせるようにすると速い
さらに。。。
- サムネイルリストの場合だと、画面の真ん中に位置する部分から描画してあげたほうが体感速度が上がる
Pros :)
- 必要な部分のサムネイルだけダウンロードされるのでネットワークに優しい
- 描画するDOMの量が圧倒的に少ないのでクライアントにも優しい
Cons ;(
- ページングしたJSONを読み込むタイミングで回線が遅くなったら、ちょっと詰まる
- 激しいスクロールをさせると描画が追いつかない事がある
キャッシュを忘れずに
- JSONや画像データ等は、適切なキャッシュをかけないとスクロールされるたびにダウンロードする事になるので注意が必要
目次
- 目指す方向と問題点
- データ量の増大にどう対応するか
- どうするイベント通知
ここまでのまとめ
ここまでの流れで基本的に画面遷移が発生しないようなアプリケーションの話ですね
画面遷移ないと
- 「あなたの写真にコメントされました」見たいなお知らせをmixiのお知らせみたく出せない
画面遷移ないと
- 「あなたの写真にコメントされました」見たいなお知らせをmixiのお知らせみたく出せない
- なぜならHTMLをサーバからダウンロード出来るのが一回だけ
画面遷移ないと
- 「あなたの写真にコメントされました」見たいなお知らせをmixiのお知らせみたく出せない
- なぜならHTMLをサーバからダウンロード出来るのが一回だけ
- JavaScriptで動的に取ってくるしかない
なぜ通知するのか
- 自分の上げた写真にコメントが付くと嬉しい
- ユーザが嬉しいと思う事は、サービサーとしても早く教えてあげたい
- サービサーとしてはユーザに喜んで欲しいから通知する。それもいち早く
実現手段
- 定期的にserverを叩く
- long pollする
定期的にserverを叩く
- setTimeout等を使って定期的にイベントが読めるAPIを叩いて、新規イベントがあるか無いかをチェックする
定期的にserverを叩く Pros/Cons
- 良い所: 実装が簡単、proxyが間に挟まっていても普通は問題起きない
- 悪い所: apiへのアクセスが増える、イベントが発生してからユーザに通知するまでのタイムラグがある
long pollする
- Ajaxリクエストを受け取ったら、サーバ側は新規イベントが発生するまで何も返さずに接続を繋げたままにして、新規イベントが発生したら即座に結果を返す
long pollする Pros/Cons
- 良い所: イベントが発生したと同時にユーザに通知できる
- 悪い所: 実装が複雑、途中にProxyが挟んでるとうまくいかない時がある
イベントが来たら
- 目立つ形でアピールする
- keireki.jpだと右下がビガビガする
- Ficiaだと右上がビガビガする
まとめ
- どんなサービスを提供するかのポリシーを定める
- データが多くなりがちになるときは、必要なデータだけを処理するようにする
- ユーザの操作の邪魔にならないように作る