ウェブアプリケーション高速化
ユーザーのアクションに対するレスポンスは即座に!
高速化を考える時、細かなテクニックに惑わされてはいけない
実際の速さ以上に、
ユーザーが速いと感じることが大事
もちろん、実際に速くなっているか検証することは必要
ただ、数msレベルの速さを語るとき、ユーザーのことを忘れているかも?
以上を踏まえて…
概ね、バッドノウハウの集まり(gzip自体はバッドノウハウじゃないけど、IE6で問題があったりしてバッドノウハウがつきまとう)
<!DOCTYPE HTML> <html manifest="/cache.manifest">
htmlタグでマニフェストファイルを指定し、
# ver.1 # #はコメントアウト CACHE MANIFEST index.html stylesheet.css images/image.png scripts/javascript.js NETWORK: search.php login.php /api FALLBACK: images/dynamic.php static_image.png
マニフェストファイルでキャッシュの定義を決める
静的なページでは効果絶大
動的なページでは扱い難い
マニフェストファイルを指定したページ自体もキャッシュの対象だったり、静的ファイルの更新に手間がかかるようになる…
シンプルなキーバリュー型のデータストアで非常に扱いやすい
ちょっとしたコードで動的なキャッシュが可能
function ajax(url, callback) {
var xhr = new XMLHttpRequest();
var responseTimer = setTimeout(function() {
//タイムアウト時の処理
xhr.abort();
if (!!localStorage[url]) {
// localStorageから取り出す
callback(localStorage[url]);
}
}, ajax.MaxWaitTime || 5000);
xhr.onload = function() {
//リクエスト成功時
clearTimeout(responseTimer);
//localStorageに保存
localStorage[url] = xhr.responseText;
callback(xhr.responseText);
};
xhr.onerror = function() {
//リクエスト失敗時
clearTimeout(responseTimer);
if (!!localStorage[url]) {
// localStorageから取り出す
callback(localStorage[url]);
}
};
xhr.open("GET", url);
xhr.send();
};
urlをキーに、Ajaxの結果をキャッシュ
ループを展開するとかなんとか?
数msの差ではユーザーは気が付かない
地道な高速化はコードの可読性、保守性を下げてしまい、画期的な高速化を妨げる要因に成り得る
明らかなボトルネックではない限り、うかつに手を出すべきではない
例えば、Gmailのスター
3が良さそう?
押した瞬間に星が付く
リクエストの成功を待たずに画面に反映してしまう
ローディングも出さない
結果はわかっているので、わざわざローディングの表示を出さなくてもよい
中途半端なローディング表示はユーザー体験を損ねる
リクエスト自体が失敗する可能性はあるので、その例外処理だけ考える
シンプルさを下げる要因かもしれない
CSSスプライトを簡単に作れるツール、ApplicationCacheのマニフェストを自動で生成するツールなど、システム的に解決はできないことはない
ただ、そのコストに対して十分な見返りが得られるのか考えなくてはいけない
「いいね」は「すごい!」の敵
FacebookのBigPipe
世界最大のSNS
SNSということは、ユーザーごとに異なるデータを表示しなければいけない
ほぼすべてのページが動的でキャッシュが効かない(Twitterなども同様)
入れ物となる空のdiv要素を先に表示しておき
その中身をJavaScriptから差し込む
用意できたコンテンツからFlushして書きこむことができるので、遅いコンテンツがあってもそれ以外の部分は先に表示できる
「読み込み開始からレンダリングが完了までの時間」ではなく、「読み込み開始から、主要なコンテンツが表示され、利用できるようになるまでの時間」
通常のウェブアプリの作り方とは大きく異なるので、動いているサービスに導入するのは困難な手法
ただ、BigPipeはシンプルに反するので、Facebook以外には適用しにくい
JavaScriptの利用シーンは増え、様々なライブラリを利用することが増えている
ライブラリが増えると読み込み時間がボトルネック(JavaScriptの読み込み中は他の処理をブロックするので)になってくる
全部読み込むと多すぎるし、必要な部分だけ分割読み込み(require.js、yepnope.jsなど)すると次のように直列読み込みになってしまうことが…
(require.js利用時)
SIMPLE is BEST
Good is the Enemy of Great