エキスパートが手がけたプロダクトを題材に技術的な解説を行っていくシリーズ連載、今回は wri.peです。 難しい機能の実装や、先進的なAPIの利用を通じて、執筆者が得たノウハウを余すところなく紹介していきます。
HTML5を活用したメモ帳アプリ [wri.pe]
最近、仕事で作っているミイルが忙しかったり、趣味で作っているMobiRubyがなかなか進まなかったりして、個人でWebサービス的なモノを作っていない事が自分としてちょっと気になっていました。
そこで息抜きとして、ゴールデンウイークに集中してWebサービスを一つ作ろう!と思い立ち、wri.peというWebサービスの開発に着手しました。
wri.peは自分が使いたいと思えるメモ帳を作ったので、下記の様な特徴を持っています。
- Markdownフォーマットをサポート
- Gmailの様なアーカイブ機能
- 全文検索
- カレンダーへのマッピング
- iPhone / iPadをサポート
- キーボードで操作ができる
ゴールデンウイーク期間中に一通り作った後、一カ月ほど自分で使いながらブラッシュアップし、6月3日に正式にリリースしました。
初めて個人でプレスリリースを打ってみたところ、個人でリリースしたWebサービスとしては多くの国内外のメディアやブログに取り上げていただきました。
wri.peが目指すモノ
wri.peは息抜きで作ったモノですが、せっかく作るのだからといくつかの目標を立てました。詳しくはブログをご覧頂きたいのですが、その中の一つに、新しい技術で製品レベルのサイトを作った場合に起こる問題点などを把握したいという目標がありました。
HTML5の機能やBackboneJSなど耳にすることはあっても、実際に製品レベルのサイトで使って大丈夫なのか自分の肌感覚として把握できていないと仕事などで使うことができません。
HTML5というと、CSS3を用いたアニメーションや3D表現、ビデオやオーディオの標準化など、ブラウザ上の表現力向上が多く取り上げられます。 またHTML5の仕様には入りませんでしたが、WebSocketを用いたリアルタイム通信やGeolocation APIを使った位置情報の取得なども、広義のHTML5として話題になっています。
そこでwri.peでは、HTML5の中でも速度の向上にターゲットを絞って、新しい機能を使ってみることにしました。
サイトの高速化のためにHTML5を使用する
ほとんどのブラウザでは、通信をキャッシュする機能を有していて、同じページや画像の表示を高速化しています。 このキャッシュの制御はWebサーバで設定を行い、HTTPヘッダに特別な値を設定する事で有効期限などを設定することができます。 HTML5では、そうした既存のキャッシュ機構に加えて、Application Cacheというキャッシュ機構を持っています。
Application Cacheで通信を減らそう
このApplication Cacheは本来、Webアプリをオフラインでも動かすために、通信状況に関係なくHTMLや画像を読み込むことのできるキャッシュとして設計されました。 しかし通常のWebサイトでもこのApplication Cacheを使うことで、画像などを読み込むためのネットワークアクセスを抑制し、ページの読み込み速度を上げることができます。
Application Cacheは、マニフェストファイルと呼ばれるファイルにキャッシュしたいファイル名を書くだけでキャッシュが行われます。そのため、HTMLやJavaScriptファイルに変更の必要がなく、手軽に導入できるというメリットがあります。
変更頻度の低いロゴなどの画像やCSSなどをこのマニフェストファイルに記述し、HTMLの中でマニフェストファイルのパスを指定するだけです。
なお、wri.peではrack-offlineというライブラリを使い、マニフェストファイルを生成しています。
例) http://wri.pe/application.appcache
CACHE MANIFEST
# 91ccff4f438451ad735c534b974c29e2ff1b08a9da4e71f928b5fc2f4ba6bd02
/assets/app-437607bb972a49c7922a504cfe02226a.css
/assets/app-7c794995cb685c8412ee2f1facea67e3.js
/fonts/fontawesome-webfont-311.ttf
/fonts/fontawesome-webfont-311.woff
/images/wripe114s.png
/images/dropbox_icon128.png
/images/wripe400s.png
/images/wripe-top880.png
/images/masuidrive64.jpg
NETWORK:
*
HTML部
:html:
<!DOCTYPE html>
<html lang="en" manifest="application.manifest" xmlns:og="http://ogp.me/ns#" xmlns:fb="http://www.facebook.com/2008/fbml">
<head>
....
Application Cacheでは、コメントも含めマニフェストファイルが1文字でも変更されるとキャッシュが破棄され、ネットワークから最新のデータが読み込まれます。 このキャッシュの制御はJavaScriptから行う事が可能なのですが、iOS 6ではバグがあるようでJavaScriptからキャッシュの更新などが正しく行えないようです。
またリソースの変更後にマニフェストファイルを更新しても、その変更が反映されるのは次回の読み込み時になります。そのため、更新頻度の高いファイルをキャッシュする用途にはあまり向きません。
wri.peでは、RailsのAssets Pipelineという機能を使い、JavaScriptとCSSをそれぞれ一つのファイルにまとめることで、ファイルの読み込み回数を減らし、表示を高速化しています。
実際に読み込み時間を比較してみます。赤い縦の線が、大体画面に表示される時間だと思ってください。
キャッシュのない状態では1,150ms、キャッシュありでは200msほどになります。
テストでは、回線が高速なため、思ったよりも差が出なくなっていますが、スマホなどでキャッシュなしの場合には、これより数倍遅くなる事が多いと思われます。キャッシュありの場合では回線速度に依存せず、安定して高速な読み込みが可能です。
また、Application Cacheにキャッシュされているファイルは、ネットに繋がっていない状態でも読み出すことができます。 試しにPCをネットから切り離すか、iPhone/Androidをフライトモードにして、https://wri.pe/app にアクセスしてみてください。全てのファイルがキャッシュから読み込まれるため、ネットに繋がっていない状態でも同じように表示されるでしょう。
ただしメモ帳のデータはApplication Cacheには入っていないので、本来であればオフライン時に読み込むことはできません。しかしそれらの情報はまた別の方法でキャッシュしているため、オフライン状態でもメモ一覧が表示されるのです。
次回予告
今回はApplication Cacheを使い、各種ファイルの読み込みを高速化する手法を取り上げました。
wri.peでは、メモ帳データのようにAjax通信で取り出すためキャッシュしにくいデータも、localStorageを使いキャッシュしています。
次回はlocalStorageを用いたデータのキャッシュや、PC向けブラウザ、iPhone/Android、iPadなどのタブレットを一つのHTMLで対応する手法について解説します。