ハイブリッドアプリをなるべく高速化するために(3)

ハイブリッドアプリをなるべく高速化するために(3)

ハイブリッドアプリをなるべく高速化するために(1)
ハイブリッドアプリをなるべく高速化するために(2)

麻雀点数計算アプリsuzumeで実際に使っている小技の続きです。

7. ハイブリッドアプリだからといってa要素で画面遷移しない

アプリによっては非常に難しい話なのですが、とことんSPAにしてしまいます。
広義でいうところのAjaxの手法ですね。

表示しているのはindex.htmlのみ。
その内容はJavascriptで書き換えていって、別画面を表示しているように見せます。
別のhtmlファイルを読みに行ったりしないし、画面が見えたり隠れたりするのはCSSで描画するので当然表示スピードは速いです。

ネイティブアプリ開発経験のないノンプログラマーがMonacaで作ったアプリ内で別の画面を開こうとすると、Activityとかが理解できないものですからa href=””ってするしかないんですよね。
実際やってみたところ、めっちゃくちゃ時間かかる。
画面真っ白になって待たされるんですよ。

そこで前回お見せしたこのソース。

  //ヘルプ
  $('#help-open').on('touchstart', function(e){
    e.preventDefault();
    $(this).attr('class', 'hover');
  });
  $('#help-open').on('touchend', function(e){
    e.preventDefault();
    $(this).removeAttr('class');
    $(this).trigger('touched');
  });
  $('#help-open').on('touched', function(e){
    window.location.href = '#help';
  })

最後の「window.location.href = ‘#help’;」でindex.html#helpにページ内リンクしています。
id=”help”は普段はdisplay:none;で、ハッシュが#helpのときだけdisplay:block;になっています。
これもCSSの小技。

#help:target {
  display: block;
}

ヘルプ画面は、遷移して読み込むのではなく、最初からindex.html内にあります。

計算結果画面も同じ。計算結果のhtmlをすべて記述し終わったら、「window.location.href = ‘#result’;」で表示するという処理になっています。

ハッシュなので、端末のバックキーで戻れるし、遷移していないので入力済みの設定もそのまま。
「ちょっと間違えてた!」っていうときでもイチからやり直しにならなくて済みます
ε-(´∀`*)ホッ

8. ハイブリッドアプリだからといってformで送信しない

今まで出てきた内容と理由が重複するのですが、高速化するためにはサーバ通信、画面遷移を極力しないというアプローチです。

ついつい、入力した内容をformでsubmitとかしたくなりますが、サーバ通信が発生したり画面遷移が発生したりすると遅くなりますし、ノンプログラマーはそんな知識と技術持ってません。
Ajaxなら非同期通信で入力中に実行結果を取得してきてリアルタイムで表示するなんてこともできるわけですが、それすらもしません。

ユーザーは入力中に誤操作したり、入力項目を行ったり来たりします。
まだ入力しきっていないのに、目的でない結果をわざわざ表示したり、そのためにパフォーマンスが落ちてもっさりするのは、ユーザーのためにはなりませんよね。
まして、ネットワークにつながっていない状態では使えないわけですから、不便なことこのうえない。

で、あれば、ユーザーが「入力おーわった!これで計算して!」って言ってきた時に1回だけ計算すればいいんですよ。

それも、わざわざパラメータを送信しなくても、入力中にDOMが書き換えられているから、そのデータを見て処理すればオッケー☆⌒d(´∀`)ノ
せっかくHTML5ですから、suzumeでは「data-」カスタム属性を存分に使ってやっています。

<li data-hai="a01"></li>

牌姿は[data-hai]で管理。

a:萬子01~09
b:筒子01~09
c:索子01~09
d:字牌01~07

計算するときに、abcdで牌の種類を判定したり、番号を照らし合わせて当てはまる役を弾き出したりしています。

それからもうひとつ計算に使っているのが役のチェックボックス。
「役設定」画面で設定している以外の役も、画面上には見えていませんがチェックボックスが存在しています。
計算中、当てはまるものは.prop(‘checked’, true)としたり、反対にデフォルトがtrueの役もあって、それは牌姿から判定して当てはまらない場合にチェックを外したりしています。

<input type="checkbox" name="option-yaku" id="option-yaku10" data-fan="0" value="役牌">

各チェックボックスは[data-fan]というカスタム属性をもっていて、これが飜数になっています。
リーチなら常に1、食い下がりのある役は、判定してマイナスしたりします。
(上記のソースは例外でデフォルト0。役牌があったら1ずつ増やしていきます)

計算結果をhtmlにどーんして、その後計算結果画面を表示。
すべてJavascriptの処理のみで、サーバ通信は不要です。

9. いちいち計算せず、固定データはJSONで管理する

親だったら1.5倍で~、子のあがりだから親がいくらで~子がいくらで~

ってそんなところまで計算する必要ないんです。
いやアプリによってはスコアの出し方とか、レートがどうとかあるかもしれないんですけどもsuzumeは必要ないんです。
○飜○符で親が上がったら○点、各家の払いが○点、っていうのは決まっています。
だったら、その決められたテーブルから値をひっぱってくれば済みますよね。

そこで、JSONに点数のデータを格納して、これを参照するようにしています。

{
	"1_30":{
	"name": "1飜30符",
		"result":"1,000",
		"resultOya":"1,500",
		"oya":"500",
		"ko":"500/300"
	},
	"1_40":{
		"name": "1飜40符",
		"result":"1,300",
		"resultOya":"2,000",
		"oya":"700",
		"ko":"700/400"
	},
	//中略
	"yakuman":{
		"name": "役満",
		"result":"36,000",
		"resultOya":"48,000",
		"oya":"1,6000",
		"ko":"1,6000/8,000"
	}
}

ってな感じのJSONファイルを用意しておきます。
たとえば1飜40符まで算出できたら、「1_40」というところのデータを取得して、nameとかresultを代入してhtmlに埋め込んでいけばいいわけですね。

JSONファイルの利用方法についてはこのあたりが詳しいです。

ざざーっと駆け足で説明してしまいましたが、Webではいろいろな技術が次々と出てくるので、こういった小技をどんどん取り入れてパフォーマンスをあげていきましょう。
ハイブリッドアプリを作るなら、Web制作の基本からおさえていると有利ですよ~
( ´∀`)bグッ!