Help us understand the problem. What is going on with this article?

重いTableViewを開く時に体感速度を上げる小ネタ

More than 5 years have passed since last update.

Titanium Advent Calendar 2014 5日目の記事です。

はじめに

久々ですが、またTitaniumを使い始めました。
ずいぶん使い勝手が良くなって安定性も向上しておりびっくりしています。

iOSとAndroidの両方への対応がほぼ必須となった現在、Titaniumは非常に有力な選択肢だと思っています。
特にスマートフォンをクライアントと捉える、サーバーサイド主体のWebアプリとの相性は抜群ですね。

わたしはちょっと細かいですが、アプリの質が上がったかなと思える小ネタを紹介します。

使えるならListViewを使う

Titaniumでコレクションを扱うUIコンポーネントとして、長い間TableViewが利用されてきましたが、SDK 3.1.0からパフォーマンスや使い勝手が改善されたListViewが登場し、問題はかなり改善されました。

ListViewはテンプレートを事前に定義しておき、そこにデータをバインドすることで高速にUIを構築することが出来ます。
そのため現在では通常ListViewを使うことによって性能の改善が行えます。
しかしListViewはTableViewと異なってRowを動的に書き換えるなどの動作を行うことは出来ません。

そこで、重いTableViewが含まれたWindowを開くときの体感速度を上げる方法です。

Windowを開いてからTableViewRowを生成する

Alloyフレームワークを使った時の一例です。

<Alloy>
    <Window id="window">
        <TableView id="table" onClick="openItem">
            <TableViewRow>
                <ActivityIndicator id="indicator" />
            </TableViewRow>
        </TableView>
     </Window>
</Alloy>

var jsonData = [
    {
        text: 'text1'
    },
    {
        text: 'text2'
    }
];

function createTableData(data) {
    var tableData = [];

    _.each(data, function(v, i) {
        var row = Ti.UI.createTableViewRow({
            rowIndex: i,
            json: v
        });

        var textLabel = Ti.UI.createLabel({
            text: v.text,
        });

        row.add(textLabel);

        // 他にも要素をTableViewRowに追加するなど

        tableData.push(row);
    });

    return tableData;
}

function openItem(e) {
    var item = e.rowData;
    alert(item.json.text);
}

// テーブルの生成を遅延させてウィンドウのOpenを高速化
setTimeout(function() {
    $.table.data = createTableData(jsonData);
}, 100);

最後のsetTimeoutが肝

最初にViewとなるXMLでTableViewを作成し、RowにActivityIndicatorを入れておきます。
これでRowの1つ目にインジケータが表示されます。
次にTableViewRowを作成する処理は関数化しておき、最後にsetTimeoutで100ms遅延させてから呼び出してTableViewにdataをセットします。

普通はWindowをopenしたとき、TableViewRowが生成されるのを待ってからWindowが開かれるので、タップしてから数秒の待ち時間が発生してしまいます。

しかしsetTimeoutで遅延させることで、まずWindowはタップされたら即時openし、重いTableViewの場合は生成されるまでインジケータが回るので体感速度が大幅に上がって気持ちサクサクになります。

私が調べたところ、iOSではsetTimeoutのウェイト時間は0でもOKでしたがAndroidでは100ms必要でした。

どうしても、重いTableViewを扱わなければならないシーンに出くわしたら思い出して見て下さいね。

次は

明日は @ganezasan さんです。よろしくお願いします!

moroya
アキバではたらくWebエンジニア。最近はディレクターはじめました。
https://moroya.net
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away