ネットワーク接続状況による処理の切り替え
スマホでは、移動しているのてネットワークがオフラインになることもよくある
ネットにつながっているなら
ローカルストレージにキャッシュして
ネットがつながったらデータ送信
というようにするなら
if(navigator.onLine){
//オンラインのときの処理
}else{
//オフラインのときの処理
}
というようにする
Just another WordPress site
ネットワーク接続状況による処理の切り替え
スマホでは、移動しているのてネットワークがオフラインになることもよくある
ネットにつながっているなら
ローカルストレージにキャッシュして
ネットがつながったらデータ送信
というようにするなら
if(navigator.onLine){
//オンラインのときの処理
}else{
//オフラインのときの処理
}
というようにする
Webアプリの更新について
動的に内容が変更されるWebアプリで
アプリケーションキャッシュを使うと
最初に読み込んだ画面を、
ずっとキャッシュし続けるため
更新されなくなってしまう
このため、動的にHTMLが変更かれる箇所では
アプリケーションキャッシュは使わない
また、アプリケーションキャッシュとして読み込んだファイルは
ブラウザーから明示的に更新をチェックしないと
キャッシュが更新されないことがある
このため、更新チェックのJavascriptなどを使わないと
更新できないWebアプリになる
このため、
キャッシュファイルの更新と
アプリケーションの更新をする必要がある
まず、キャッシュファイルの更新を検知してWebアプリを更新する方法
アプリケーションキャッシュを示す
applicationCacheでは
キャッシュファイルが更新されると発生する
updatereadyイベントが使える
この
updatereadyイベントを使うことで
更新チェックと
新しいバージョンへのアップデートができる
if(applicationCache){
applicationCache.addEventListener("updateready",function(){
if(confirm("新しいバージョンが利用できます。アップデートしますか?")){
//キャッシュのアップデートと画面の再読込
applicationCache.swapCache();
location.load();
}
},true);
}
これだけでも更新チェックとアップデートができるけど
コンテンツを更新しても
updatereadyイベントが発生しないこともある
そのため念のために
update()
を、使うことで
明示的にキャッシュの更新と、リソース再読込ができるようにしておく
使い方は
applicationCache.update();
とする
これは、ボタンなどで使うことで
再読込ボタンにすることもできる
HTMLで
<button type="submit" id="update">更新</button>
Javascriptで
$(document).on("click","#update",function(e){
//キャッシュのアップデートと画面の再読込
applicationCache.update();
location.load();
});
注意点としては、Androidだと
アプリケーションキャッシュを使うことで
画面遷移ができなくなることがある
このため、Androidでは、Ajaxによる画面遷移を無効化しておく
if(navigator.userAgent.match(/Android/)){
$.mobile.ajaxEnabled = false;
}
match()は正規表現
マッチするものを調べるやり方
詳しくはドットインストールの正規表現を参考にするとわかりやすい
アプリケーションキャッシュについて
HTML5から追加された
アプリケーションキャッシュを使えば
ネットにつながっていなくてもWebアプリを動かすことができる
アプリケーションキャッシュでは
HTML
CSS
画像などのリソースをブラウザーでキャッシュして
サーバーへ読みに行かないようにする
これにより
サーバーへの負荷が減り
レスポンス向上、通信量削減もできる
ただし、デメリットがある
設定ができていないと
コンテンツのアップデートができなくなるので注意
アプリケーションキャッシュを使うには
appcacheファイルを作成する
このファイルの拡張子は
.appcache
になる
HTML5ファイル
が
一番最初の行へ
<DOCTYPE HTML>
としたり
シェルスクリプトファイルで
一番最初の行へ
#!/bin/bash
とするように
アプリケーションキャッシュでは
CACHE MANIFEST
と書く
そして、2行目に
#Version: 1.0
というように、バージョンをコメントアウトで書く
アプリケーションキャッシュファイルのコメントアウトは
Linuxの設定ファイルのように
#を付けることでできる
有効範囲は行末まで
そして、3行目からはキャッシュしたいファイルを記述していく
ファイルのパスは
キャッシュファイルからの相対パスでも
http:// の絶対パスでも構わない
#でコメントアウトができるので
ファイル概要があるとわかりやすくなる
ソースにすると
CACHE MANIFEST #Version: 1.0 index.html menu.html #Javascript js/jquery-1.7.1.min.js js/jquery-mobile-1.1.0.min.js #CSS css/jquery-mobile-1.1.0.min.css
これで、アプリケーションキャッシュファイルができたので
後はHTMLファイルの
html要素へ
manifest=”” でアプリケーションキャッシュファイルを指定する
今回作成したのが
hello.appcacheなら
<! DOCTYPE html> <html manifest="hello.appcache"> </html>
となる
これで、Webアプリの設定はできたので
次に、サーバー側の設定
サーバーソフトとしてApacheを使っている場合
デフォルトだと
.appcacheファイルは
text/plain形式になるので
正しく動作させるため
text/cache-manifestファイルになるように設定する
これは、 .htaccessファイルを作成して
キャッシュファイルと同じディレクトリに置く
.htaccessの内容は
addType text/cache-manifest .appcache
アプリケーションキャッシュを使うと
iOSやAndroidでは
まず、appcacheファイルを取得し
キャッシュの設定のあるファイルを
キャッシュから読み込んで表示する
appcacheファイルをWebサーバーから取得できない場合
キャッシュされたappcacheの情報に基づき
コンテンツをキャッシュから表示する
DOMキャッシュについて
jQueryMobileは、DOMキャッシュ機能を持っている
これほ、一度表示した画面、つまりDOMをjQueryMobileの中にキャッシュして、キャッシュしたDOMを表示する機能
これは、メニュー画面など、
頻繁に表示されるページに利用する
DOMキャッシュで
すべての画面をキャッシュするには
jQueryMobileを初期化時に
$.mobile.page.prototype.options.domCache
をtrueにする
$(document).on("mobileinit",function(){
$.mobile.page.prototype.options.domCache = true;
});
これは、mobileinitイベントで定義する
次に、特定の画面のみキャッシュする方法
すべての画面をキャッシュするのはリソースの無駄なので行わない
キャッシュするのは
メニュー画面など
頻繁に再訪が発生するページのみにする
キャッシュ画面の指定は
画面の要素、つまり
data-role=”page”
に対して
data-dom-cache=”true”
を設定する
ソースにすると
<div data-role="page" data-dom-cache="true" id="menu"> </div>
なお、DOMキャッシュは、アプリケーションキャッシュを使うなら不要になる
次の画面を先読みするプリフェッチ
ある画面から次の画面に移るときに
画面が変わるタイミングでデータ読み込みがあると
画面が表示されるまで時間がかかることがある
特に低速回線の場合は多発する
この対処としては、jQueryMobileで提供されているプリフェッチ機能を使えば
ユーザーに今の画面を表示している間に
次の画面のデータを事前に読み込んでおける
このプリフェッチ機能により
あらかじめ次の画面を読み込んでおくことで
スムーズに画面遷移ができる
これは、アンケートとかユーザー登録みたいな次に遷移するページが決まっているときに使う
プリフェッチ機能を使うには
リンクする a要素へ
data-prefetch=”true”
を設定する
<a href="next.html">次へ</a>
ただし、プリフェッチ機能を乱用すると
ユーザーが見ない画面も取得してしまうため
サーバーに負荷がかかるし
ネットワーク負荷もかかる
このため
プリフェッチ機能は、次にみる可能性の高い画面のみ設定すること
ちなみに、photoSwipeは
デフォルトで画像を表示している間にプリフェッチ機能で前後の画像を取得している
このため、画像をプリフェッチしながら表示するなら
PhotoSwipeを使うと便利
いろいろと使えそうなプリフェッチ機能だけと
アプリケーションキャッシュを使えば
プリフェッチ機能は使わなくても代用できる
$.getScript()でスクリプトの遅延ロード
大きなサイズのJavascriptライブラリーを使う場合
scriptタグで全部読み込むより
一旦画面を表示してから
スクリプトを読み込んだほうがWebアプリのレスポンスがよくなる
また、特定条件のときのみ必要なライブラリーは
ライブラリーを動的に読み込むようにして
不要なJavascriptのロードを避ける
Javascriptを動的に読み込むのに使うのが
$.getScript()
を使う
例えば、iOSでは日付が使えるけど
Androidではできない
なので、Androidなら
jQueryMobile DateBoxを読み込む
というように、ifで判定して使う
<script>
if(navigator.userAgent.indexOf("Android")!=-1){
$.getScript("http://dev.jtsage.com/cdn/datebox/latest/jquery.mobile.datebox.min.js",function(data,status){
$.getScript("http://dev.jtsage.com/cdn/datebox/i18n/jquery.mobile.datebox.i18n.ja.utf8.js",function(data,status){
//Javascript読みこみ処理
});
});
}
</script>
jQueryMobileでは、デフォルトで最初にアクセスしたとき
トップページでJavascriptを読み込むのが望ましい
そして、このときにトップページに必要のないJavascriptは
$.getScript()
を使うことで
まずはトップページを表示して
その後に必要なJavascriptを読み込むようにすれば
低速回線でもストレスなく表示することができる
フォームの遅延ロード
Ajaxのフォームも遅延ロードで作成可能
ただし、これもただ追加しただけでは
jQueryMobileが適用されないため
フォームコンポーネントを追加した時点で
trigger(“create”)
を呼び出す必要がある
$.ajax({
type:"POST",
url:"./form.html",
dataType:'html',
success: function(data){
//データ追加
$("#corapsible-form").append(data);
//jQueryMobile反映
$("#corapsible-form").trigger("create");
},
error:function(msg){
alert(msg.responseText);
}
});
これで、あとはhtmlで
追加する領域の指定
<div data-role="corapsible" data-corapsed="true" id="acordion" name="acordion"> <h3>動的フォームの挿入</h3> <form id="corapsible-form"></form> </div>
続いて、挿入するhtmlファイル
このやり方のメリットは、後から追加できるため
メンテナンスが楽なこと
そして作業の分担ができること
全体的なUIの設定と
フォーム内容担当を分けることができる
アンケートなどではかなりの量になるので
都度アンケート内容だけ変更することもできる
<div data-role="fieldcontain"> <label for="slider">スライダー</label> <input type="range" name="slider" id="slider" value="0" min="0" max="100" /> </div> <fieldset data-role="controlgroup"> <legend>好きなタイプは?</legend> <input type="checkbox" name="rpg" id="rpg" class="custom"/> <label for="rpg">RPG</label> <input type="checkbox" name="action" id="action" class="custom"/> <label for="action">アクション</label> <input type="checkbox" name="puzzle" id="puzzle" class="custom"/> <label for="puzzle">パズル</label> </fieldset> <div data-role="fieldcontain"> <fieldset data-role="controlgroup"> <legend>使うosは?</legend> <input type="radio" name="os" id="android" value="android"/> <label for="android">Android</label> <input type="radio" name="os" id="ios" value="ios" checked="checked"/> <label for="ios">iOS</label> <input type="radio" name="os" id="other" value="other"/> <label for="other">両方</label> </fieldset> </div>
遅延ロードで必要なデータのみ取得
大量のデータや読みこみに時間がかかるデータを画面に表示するときに
かなり時間がかかる
この場合、最低限の画面を表示し
徐々にデータを表示したり
ユーザーがWikipediaのコンテンツみたいに
アコーディオンを開いたらオンデマンドで
データを取得、表示するという遅延ロードが有効
すごい時間をかけて全部でるより
徐々に表示されるほうがストレスは少ない
jQueryMobileで、
リスト表示で
この遅延ロードをするにはコツがある
なぜなら
Javascriptで後からタグを追加しただけだとjQueryMobileのスタイルが適用されないから
なので、追加したら
listview(“refresh”)
をする必要がある
まず、実践するには
<script src="js/loadform.js"></script>
で自作スクリプトの読みこみ
次に、開閉したい場所の領域を
<div data-role="corapsible" data-corapsed="true" id="corapsible-list"> <h3>遅延ロードの実践</h3> <ul data-role="listview" id="list"> </ul> </div>
として設定
data-role=”corapsible”
は、開閉する指定
data-corapsed=”true”
で開いた状態にする
デフォルトは false で閉じた状態
http://dev.screw-axis.com/doc/jquery_mobile/components/content/collapsible/
を参考にするとわかりやすい
そして、処理はJavascript
途中で
$.mobile.showPageLoadingMsg()
と
$.mobile.hidePageLoadingMsg()
があるけど、これは
ローディングアイコンの表示、非表示をする
この動作サンプルとしては
http://www.atmarkit.co.jp/fdotnet/chushin/jqmobile_06/jqmobile_06_02.html
にTwitterのつぶやきを表示したりするサンプルがあるので
こちらを参考にするとわかりやすい
あと
data: “param1=123¶m2=homuhomu”
これは
http://semooh.jp/jquery/api/ajax/jQuery.ajax/options/
や
http://phpjavascriptroom.com/?t=ajax&p=jquery_ajax_requests
や
をみたかんじだと
サーバーip/json.php?param1=123¶m2=homuhomu
になる
$.trim()
は
http://semooh.jp/jquery/api/utilities/jQuery.trim/str/
にあるように、空白の削除するメソッド
つまり
if($.trim($(“#list”).html()) ==””){
なら
id=”list”のタグの中身が空ならとなる
$.each()は
http://semooh.jp/jquery/api/utilities/jQuery.each/object%2C+callback/
にあるように、繰り返し処理をする
繰り返すのは
$(‘#list’).append(“
“);
でリスト追加処理
$(document).on("expand","#corapsible-list",function(e,data){
if($.trim($("#list").html()) ==""){
$.mobile.showPageLoadingMsg();
$.ajax({
type:"POST",
url:"./json.php",
data:"param1=123¶m2=homuhomu",
dataType:'json',
success:function(data){
$.each(data,function(e){
$('#list').append("<li>"+data[e]+"</li>");
});
$('#list').listview("refresh");
$.mobile.hidePageLoadingMsg();
},
error: function(msg){
alert(msg.responseText);
$.mobile.hidePageLoadingMsg();
}
});
}
});
そして、PHPファイルでデータの用意
ファイル名は json.php
<?php
header('Content-type: application/json;charset=utf-8');
$data = array("みかん","りんご","ブドウ","もも");
echo json_encode($data);
?>
json_encode()
で配列をjson形式にしている
クリックレスポンス向上
Androidでは、ボタンなどのイベント処理を行う場合
vclick
tap
などを使うと反応が良くなる
$(document).on("vclick","#mybtn",function(e){
//クリック時の処理
});
Webアプリのパフォーマンスチューニング
まず、通信量の削減
基本的に、ライブラリーを使うときには
.min.js
とついている圧縮版を使う
自作のコードもできる限りツールや
Webサーバーのモジュールで圧縮する
圧縮にはgruntのプラグインなども使えそう
あと、使われる物としては
Google Closure CompilerでJavascriptのコード削減
YUI Compressor によるJavascriptとスタイルシートのコード削減
Apache のmod_deflate によるデータ圧縮など
ただし
Google Closure Compiler
YUI Compressor
についてはJavaが必要になる
Google Closure Compilerは
https://code.google.com/p/closure-compiler/
を参考に
また、Google Closure Compilerは、コマンドからの操作も可能
http://www37.atwiki.jp/aias-closurecompiler/pages/16.html?&flag_mobilex=1
の解説がわかりやすい
このツールは
改行などを削除し、コードを圧縮する
使い方は
java -jar compiler.jar --js ファイル名
結果をファイルへ出力するには
java -jar compiler.js --js ファイル名 --js_output_file 出力ファイル名
とする
また、ファイルを結合するなら
java -jar compiler.js --js_output_file 出力ファイル名 元のファイル名 元のファイル名
とする
次に、YUI Compressor
これは、Yahoo!が開発している
Javascriptとスタイルシートの圧縮ツール
詳しい使い方については
http://stacktrace.jp/tools/yuicompressor/
を参考に
これも、コマンドから実行で行う
CSSファイルを圧縮するには
java -jar yuicompressor.jar --type css --charset utf-8 -o 出力ファイル名 圧縮したいファイル名
となる
これも2つのソースをまとめることが可能で
jar -jar yuicompressor --type css --charset utf-8 -o 出力ファイル名 元ファイルその1 元ファイルその2
とする
次に、データ圧縮をする Apache mod_deflateについて
HTTP 1.1をサポートするWebサーバーを使うと
サーバー側で自動的に圧縮したデータをブラウザー側で解凍して表示できる
Apacheの場合
mod_deflateモジュールを使うことでできる
まずは、http.conf
つまり、Apache設定ファイルの中にモジュール読み込み設定があるか確認
LoadModule deflate_modules/mod_deflate.so
そして、
http://httpd.apache.org/docs/2.2/ja/mod/mod_deflate.html#deflatecompressionlevel
のリファレンスを参考に追記する
DeflateCompressionLevel
の値は、1~9で
値を大きくすれば圧縮率はあがるけど
代償としてサーバーの負荷も上がっていく