14
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

簡単アニメーション!Pixi.jsを触ってみる!(4)パフォーマンスを測定してみた

Last updated at Posted at 2014-03-08

簡単アニメーション!Pixi.jsを触ってみる!
〜(4)パフォーマンスを測定してみた〜

Pixi.jsは 速い! と定評の簡単にアニメーションが作れるライブラリです。


pixi.jsの公式サイトへ

これまで亀のような歩みで使い方を覚えてきましたが、今回は中休み(ネタ考えるのが面倒w)ということでパフォーマンスを測定してみました。

パフォーマンス測定といえば、もうずいぶん前に、ICS池田さんの記事でも、ぶっちぎりの結果が紹介されていて、この記事を見て「pixi.jsしかないじゃん!」と、あっさりとprocessing.jsから乗り換えた思い出があります。

他のjsライブラリとの比較については、池田さんの記事を参照くださいね。

どのくらいの機種で動くのか知りたい!

今回の調査で知りたかったのは、 pixi.jsはどのくらいの機種や環境で動くの? という点です。
なので、手持ちのPCや某所にある機種も借りて、いろいろ見てみました。
(一人では無理なので、手伝ってもらいました。測定にご協力いただいたIさん、ありがとうございます!)

  • iPhoneやiPad (たまたまあったもの)
  • Android端末 (たまたまあったもの)
  • その他PCなど (たまたまあったもの)

つまり、評価機種の選定基準は たまたまあったもの ですw

なぜかAndroid機種が某キャリアに偏っているように見えますが、気のせいです。たぶん。

しかも、pixi.jsしか見ていません!めちゃくちゃ偏りがある点はご容赦ください。

テストプログラム

テストには前回記事の最後に作ったコレをもとに、表示するスプライト数を増やして1秒あたりの描画回数を取得できるようにしたものを使いました。

おもいっきり手抜きですが、目的は果たせるはず!!(と自分に言い聞かせるw)

コードはこんな感じになりました。(テストするスプライト数に応じてspritesMaxを変更しています。)

<script>
var spritesMax = 10; // 表示するスプライト数。

var width = 600;
var height = 400;

// ベンチマーク用
var firsttime;
var bCount = 0;
var cps = 0;
var cpsresults = [];
var testtimes = 0;
var nowtime;
var oldtime;

// ステージ・レンダラーを作ってDOMに配置
var stage = new PIXI.Stage('black');
var renderer = PIXI.autoDetectRenderer(width, height);
document.getElementById("pixiview").appendChild(renderer.view);

// コンテナを2つつくる。(for文かよw)
var containers = [];
for (var i=0;i < 2; i++){
  containers[i] = new PIXI.DisplayObjectContainer();
  containers[i].position.x = 100+(i*300);
  containers[i].position.y = 50+(i*100);
  stage.addChild(containers[i]);
}

// 画像からスプライトオブジェクトを作る
var framenames = [
  "test_r1_c1.png",
  "test_r1_c2.png",
  "test_r1_c3.png",
  "test_r1_c4.png",
  "test_r2_c1.png",
  "test_r2_c2.png",
  "test_r2_c3.png",
  "test_r2_c4.png"];
var sprites = [];
var speed = [];

// Asset Loaderでスプライト・シートをテクスチャフレームに読み込む
loader = new PIXI.AssetLoader(["img/test.json"]);
loader.onComplete = onComp; // 読み込みは非同期で行われます
loader.load(); // ロード開始!

// ロード後の処理 (非同期でコールバックされます)
function onComp()
{
  // テクスチャフレームからスプライトを作ってステージに並べます。
  for(var cnt=0;cnt < spritesMax;cnt ++){
    var name = framenames[cnt % (framenames.length)];
    sprites.push(PIXI.Sprite.fromFrame(name));
    sprites[cnt].position.x = Math.random() * 600;
    sprites[cnt].position.y = Math.random() * 400;
    sprites[cnt].anchor.x = 0.5;
    sprites[cnt].anchor.y = 0.5;

    // 前半と後半を分けてコンテナに入れる。
    if((cnt % 2) == 0){
      containers[0].addChild(sprites[cnt]);
    }else{
      containers[1].addChild(sprites[cnt]);
    }

    var t =+new Date();
    firsttime = Math.floor(t/1000);
    speed.push(Math.random());
  }

  // 次のアニメーションフレームでanimate()を呼び出してもらう
  requestAnimFrame(animate);
}

var sel1 = 0;
var sel2 = 1;
var counter = 0;

// アニメーション関数
function animate(){
  bCount ++;
  var nt = +new Date();
  nowtime = Math.floor(nt/1000);

  if(nowtime != oldtime){
    cps = bCount;
    bCount = 0;
    oldtime = nowtime;
    document.getElementById("cps").innerHTML=cps;
    if(nowtime > (firsttime + 3)){
      if(testtimes < 10){
        cpsresults.push(cps);
      }else{
        var total = 0;
        for(var i=0;i<cpsresults.length;i++){
          total += cpsresults[i];
        }
        var ave = Math.floor(total/cpsresults.length);
        document.getElementById("ave").innerHTML=ave;
      }
      testtimes ++;
    }
  }
  requestAnimFrame(animate); // 次の描画タイミングでanimateを呼び出す
  for(cnt=0;cnt <sprites.length;cnt++){
    sprites[cnt].rotation += (speed[cnt] / 10);
    sprites[cnt].position.x += (speed[cnt]*10);
    if(sprites[cnt].position.x > 700){
      sprites[cnt].position.x = -200;
      speed[cnt] = Math.random();
      sprites[cnt].position.y = Math.random() * 400;
    }
  }
  // containerを変形させる処理
  if(counter > 100){
    sel1 ^= 1;
    sel2 ^= 1;
    counter = 0;
  }
  containers[sel1].scale.x += 0.015;
  containers[sel1].scale.y += 0.005;
  containers[sel2].scale.x -= 0.015;
  containers[sel2].scale.y -= 0.005;
  renderer.render(stage);   // 描画する
  counter ++;
}
</script>

測定方法

テストサイトを表示してしばらく待つと (Ave): の横に数字が出てきます。
これが、1秒間のに表示できた回数の平均値(10回やって割ってる)です。

各端末ごとに、10000→5000→1000→500→100→50→10
の順にテストを行って、結果を記録しました。

ただ、途中で59点以上が出たら、それより少ないスプライトでは60点以上出るはずなので、
それ以降は行わず、見なしで60点をつけました。
また、1秒間に30回以下だと、スムーズなアニメと言えないので得点に入れないことにしました。

測定の様子(ウソ)

測定結果(得点)

まず、単純に得点を計算してみました。
一応、iOS、Android、その他のように並んでいるので、あえてソートしていませんが、下記のようになりました。
スコアの数え方は、テストしたスプライト数×得点 の合計です。

機種名 (バージョン) スコア
iPhone3GS (4.3) Safari 120
iPhone4S (5.1.1) Safari 9600
iPod touch 5G (6.0.1) Safari 25100
iPhone5 (7.0.3) Safari 77100
iPhone5C (7.0.6) Safari 77100
iPhone5S (7.0.4) Safari 90600
iPad2 (5.1.1) Safari 9600
iPad 3rd (6.1.3) Safari 28100
IS03 (2.2.1) ブラウザ 270
IS11SH (2.3.3) ブラウザ 380
IS11PT (2.3.4) ブラウザ 300
IS11N (2.3.5) ブラウザ 400
KYY04 (4.0.3) ブラウザ 7500
KYY04 (4.0.3) Chrome 25.0 90
HTL21 (4.1.1) ブラウザ 26200
HTL21 (4.1.1) Chrome 30.0 4900
LGL23 (4.2.2) ブラウザ 84600
LGL23 (4.2.2) Chrome 28.0 6150
SCL22 (4.3.0) ブラウザ 79100
SCL22 (4.3.0) Chrome 33.0 274600
NEXUS7 (4.4.2) Chrome 33.0 99600
iMac (10.7.5) Safari 6.0.5 99600
Macbook Air 2013 Chrome 34.0 909600
Windows 7 Desktop Chrome 33.0 739600
Windows 8.1 Note IE 11.0 729600
geeks phone keon (FireFox OS) 330

上記のようにAndroid2.x系は全滅でした。
今回、会社にたまたま転がってた話題のFireFox OS端末でも見てみたのですが、これもAndroid2.x系と同じような印象。
面白かったのが、AndroidのChrome。25だと酷い結果なんですが、30以上だと速くなります。
WebGLがデフォルトで有効になっているのが効いているのではないでしょうか。
上の表に載せるまでもなく、途中でやる気がなくなったのがIE9。Core i5マシーンで試したにも関わらず。。。はっきり言ってまともに動きませんw ガタガタです。FireFox OS端末の方が幾分スムーズに動く、といったレベルでした。

測定結果(どのくらいのスプライトがスムーズに動いた?)

先ほどのまとめ方だと、 結局、どのくらいのスプライト数までスムーズに動くの? という点がよくわかりません。
そこで機種別に、50フレーム以上で動いた一番高負荷なテスト(=スプライト数)を出してみました。

機種名 (バージョン) スムーズに動いた一番一番高負荷なテスト
iPhone3GS (4.3) Safari -
iPhone4S (5.1.1) Safari 100
iPod touch 5G (6.0.1) Safari 100
iPhone5 (7.0.3) Safari 500
iPhone5C (7.0.6) Safari 500
iPhone5S (7.0.4) Safari 1000
iPad2 (5.1.1) Safari 100
iPad 3rd (6.1.3) Safari 100
IS03 (2.2.1) ブラウザ -
IS11SH (2.3.3) ブラウザ -
IS11PT (2.3.4) ブラウザ -
IS11N (2.3.5) ブラウザ -
KYY04 (4.0.3) ブラウザ 50
KYY04 (4.0.3) Chrome 25.0 -
HTL21 (4.1.1) ブラウザ 100
HTL21 (4.1.1) Chrome 30.0 10
LGL23 (4.2.2) ブラウザ 500
LGL23 (4.2.2) Chrome 28.0 50
SCL22 (4.3.0) ブラウザ 500
SCL22 (4.3.0) Chrome 33.0 1000
NEXUS7 (4.4.2) Chrome 33.0 1000
iMac (10.7.5) Safari 6.0.5 1000
Macbook Air 2013 Chrome 34.0 10000
Windows 7 Desktop Chrome 33.0 5000
Windows 8.1 Note IE 11.0 5000
geeks phone keon (FireFox OS) -

こうして見ると、まぁ、ちゃんと動かない機種・環境はどうしようも無いとして、スマートフォン向けだとスプライト数100くらいで作った方が良いと思いました。

理由は、

私のiPod touch 5Gでうごかしたい!wwwwwwww

からです!
(なんだか、これ、最後のiPod touchになりそう。大事にしたい。。。)

測定結果(生データ)

見たい人はいないと思いますが、将来の自分のために、テスト結果の生データを下記に置いておきます。
生データ

まとめ。次回は「インタラクションに挑戦!」

いろいろな機種で動かしてみましたが、やはり古めの機種ではたくさんのスプライトを動かすのは辛いようです。
新しめの機種では、1000スプライトでもギュンギュン動きます。これは楽しいです。
これからギュンギュン動く機種ばかりになると予想されるので、さっさと使えるようになりたいと改めて思いました。

  • iPod touch 5Gは重要!スプライトは100くらいにしとけ(最重要)
  • MacのChromeとかだと画面リフレッシュレートとrequestanimationframeのコールバックがたぶん同期してて60fps以上にならないんだけど、iPhoneのSafariとかだと、64とかになることも。本当に画面のリフレッシュレートと同期してるか怪しい気がする。
  • スマートフォンは2年くらい前の機種だと結構つらい。AndroidのVersionというよりハードウエアスペックな気がする。
  • Androidだと4.1、iOSだと5がプリインされてたくらいの機種からそれなりに動く感じ。
  • AndroidのChromeもVersion 30以前だと厳しくなる(設定でWebGLを有効にできるらしいけど、コンテンツ作る人はそこに期待できないので)
  • IEは9はダメダメでしたが、11は普通に速かった。(10はやってない)

さて、次回はいよいよ、 ユーザー操作に反応する何か に挑戦してみたいと思います!

お楽しみに!

14
14
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?