本文へスキップ

PixiJS のゲームがカクつくのはなぜ? ​

PixiJS は速いです。だからこそ、Pixi のゲームのカクつきはもどかしいのです。レンダラーは何万ものスプライトを描けるので、フレームが落ちたなら何か別のことが起きています。Myaku はそれが何かを突き止めます。

ゲームに追加する ​

bash
npm install -D myaku
html
<!-- index.html:ゲームのスクリプトより前に -->
<script type="module">import "myaku/auto";</script>
<script type="module" src="/src/main.ts"></script>

これだけです。Myaku は Pixi 自身の devtools と同じフック(__PIXI_APP_INIT__)を使って PixiJS 8 にフックするので、Application が起動すると Myaku が自分で見つけます。何かを渡す必要も、ラップする必要もありません。

ticker か、レンダラーか ​

Pixi のフレームが遅いとき、まず知りたいのは、時間を使ったのがゲームロジックと描画のどちらなのかです。Myaku は 2 つのスパンでこれに答えます。

  • update:ticker のリスナー、つまり app.ticker.add(…) で追加したコードすべて
  • render:Pixi のレンダラーがステージを描く処理

PixiJS 8 のゲームに 3 ms 忙しく働くだけの ticker リスナーを追加して確かめたところ、Myaku は update を 1 フレームあたり 3 ms、render を 0.2 ms と報告しました。

つまり、遅いフレームの判定はこう読めます。

Frame 4,410 took 31 ms (budget 25 ms). The game's frame code ran 29 ms. Spans: update 27 ms, render 1.6 ms.

(フレーム 4,410 に 31 ms かかりました(予算 25 ms)。ゲームのフレーム処理に 29 ms。スパン:update 27 ms、render 1.6 ms)

問題は Pixi ではなく、あなたのロジックです。どの部分かを知るには、自分のシステムを計測しましょう。

ts
import { myaku } from "myaku";
const profiler = myaku();

app.ticker.add((ticker) => {
  profiler.span("movement", () => moveEntities(ticker.deltaMS));
  profiler.span("collisions", () => checkCollisions());
});

PixiJS でよくある容疑者 ​

  • upload:プレイ中の新しいテクスチャ。 Texture.from(canvas)、毎フレーム文字が変わる Text オブジェクト、その場で作る RenderTexture が当てはまります。テクスチャがまだアップロードされていないスプライトの初回描画もそうです。Myaku はフレームごとのアップロード回数とバイト数を数えます。テクスチャは prepare プラグイン(import "pixi.js/prepare" してから renderer.prepare.upload(…))で先にアップロードしましょう。頻繁に変わるテキストには BitmapText がおすすめです。
  • gc:毎フレームのメモリ確保。 ticker の中で作る新しい Point や Rectangle、表示リストに対する filter/map、ホットループ内の getBounds()(メモリを確保します)。オブジェクトを使い回しましょう。
  • compile:フィルターの初回使用。 新しいフィルターやカスタムシェーダーは、初めて描かれるときにコンパイルされます。ローディング画面の裏で温めておきましょう。
  • 大量のドローコール。 フレームは遅いのにコードは速かった場合、ドローコールが多ければ Myaku の判定がそれに触れます。テクスチャを減らし(アトラス化)、ブレンドモードやフィルターの切り替えを減らせば、Pixi はもっとまとめてバッチできます。
  • throttled:ゲームのせいではありません。 隠れたウィンドウや最小化されたウィンドウはブラウザに間引かれます。Myaku はそう伝えます。

共有できる数字 ​

window.__MYAKU__.report() はただの JSON です。p50、p95、p99 のフレーム時間、1 分あたりのヒッチ回数、判定付きのワーストのヒッチ、そして update、render、自分で追加したスパンの平均コストが入っています。

Myaku を始める → · スパンとエンジン · 判定の読み方