2013年4月17日水曜日

TitaniumのTableViewのパフォーマンス改善

  • このエントリーをはてなブックマークに追加

TitaniumでTableViewを普通に使っていれば問題はないんだけど、
データベースに入っているデータを全て取り出して、
行としてどんどん追加する場合、行数によっては表示まですごく時間がかかってしまう。

そこで改善策を!と言いたいところだけど、
劇的な改善については今のTitaniumの仕様だと無理だった。。。
とりあえず色々と調べた結果を書いていこうと思う。

■appendRowを使わずにsetDataでまとめて行を追加

//駄目な書き方
var table = Ti.UI.createTableView();
for(var i = 0;i < 2000;i++){
  var row = Ti.UI.createTableViewRow({
    height:40
  });

  row.add(Ti.UI.createLabel({
    text:i
  }));

  table.appendRow(row);
}

//正しい書き方
var table = Ti.UI.createTableView();

var rows = [];
for(var i = 0;i < 2000;i++){
  var row = Ti.UI.createTableViewRow({
    height:40
  });

  row.add(Ti.UI.createLabel({
    text:i
  }));

  rows.push(row);
}

table.startLayout();
table.setData(rows);
table.finishLayout();
行数が100程度だったらまだ上の方の書き方でも大丈夫だけど、
それ以上になると見るからにおっそいなぁーと思う。
実際に計測すればいいんだけどそれを書くのがちょっと面倒なので省略。

なのでappendRowではなくてsetDataでrow配列を格納してあげるとよい。


■setDataする際にstartLayout()、finishLayout()をちゃんとする
table.startLayout();
table.setData(rows);
table.finishLayout();
どうしてこれを記述する必要があるかというと、
膨大なデータを挿入した際に、全てが描画OKにならないと描画が完了しないから。
で、そのタイミングはtitaniumの方で判断してるっぽいんだけど、
もちろん教えてあげれば親切だからtitaniumも判断しやすいわけであるし。

ということでこれは描画完了までを早める点で絶対に書いておくべきもの。


■複雑なレイアウトの行でなく単純な行なら、単純に入れるべき
var table = Ti.UI.createTableView();

var rows = [];
for(var i = 0;i < 2000;i++){
  rows.push({title:i});
}

table.startLayout();
table.setData(rows);
table.finishLayout();
この書き方はtitaniumの本などによく書かれてる方法。
何が違うのかというと、Ti.UI.createTableViewRow()を使って行を入れているわけではなく、
objectをそのまま突っ込めば自動的に行を作ってくれるという感じ。
ネイティブに近い動きになるから明らかにスピードが変わるのでおすすめ。
ただしcreateTableViewRow()をするのと違って、
単純なテーブルしか作れないのであまり使用出来る機会は少ない。
色々と頑張ってみたけれども、単純な場合しか出来なかった。


■そもそも全てを一回で描画しない
上記の方法は一回で全ての行を表示する方法ではあるけれども、
TwitterのクライアントやFacebookのクライアントみたいに下にスクロールするたびに行を追加していくのが良い。
というか本来はそうやってtableは表示していくものであるのではないかとも思う。

仕組みとしては、最初は50行ほどまでのみ描画。
TableViewのスクロールイベントで何行目までスクロールしたかを取得。
スクロールした分の行をappendRow()していく。

こんな感じで実装出来る。
ただこれはTwitterやFacebookクライアントみたいなものだったらよいのだけれども、
コンテンツによってはどうしても一番下まで描画したいものとかもあるわけで。
そういった場合はsetTimeoutで50行ずつappendしていくとか、
描画完了するまでインジケータとかプログレスバーを出すとかしかないような気がする。


ということで劇的なパフォーマンス改善をするのはすごく難しい。
なんかこうなってくるとあまりTitaniumを使う旨味とかがあまり無いような気がする。
特に普通のwebサイト作っていてもそうだけど、スピードって重要であるし。

最近だとsencha touchがかなり良いパフォーマンスを発揮してるだとか、
Airが中々良いだとかっていう話を聞いたりもするし、
いっそのことHybridアプリで全て構築した方が、
TitaniumのiPhone・Android問題を考えなくても良さそうでもあるなぁと思う。
それにアプリじゃなくて通常のサイトとしても使えるわけでもあるし。
それかまぁ仕様としてAndroidさえなければネイティブで書けるのになぁとも思ったり思わなかったり。

Adsense