ことれいのもり

【PixiJS】タブのアクティブ切り替えでFPSが変化してしまう問題の対処法

はじめに

PixiJS で、ある挙動の後に一時停止し、動き出すという処理を作っていました。

この一時停止処理には ticker.deltaTime を使用して時間を計測しています。

しかし、ブラウザのタブを変えるなど、ゲームのタブが見えなくなる状態にしてからゲームに戻ると、一時停止処理がなくなってしまいました。

この問題を解決したので記しておきます。

前提

バージョン: PixiJS v8

参考リンク

原因

これはPixiJSの問題ではなく、ブラウザの処理の問題のようです。

ブラウザは複数タブを開いているとき、アクティブなタブのパフォーマンスを最適化する仕様になっています。

そのため、非アクティブのタブはFPSを下げたり requestAnimationFrame や setTimeout の実行頻度を減らすなどの調整を行なっています。

非アクティブからアクティブに戻ったときに deltaTIme が通常よりも大きな値で計算されてしまい、予期しない挙動を生み出すようです。

対策

JavaScript を用いるとブラウザのアクティブ・非アクティブを検知することができます。

これを利用して非アクティブになったらアプリケーションの処理を止め、アクティブになったら再開するようにしました。

// ブラウザのアクティブ・非アクティブを検知
document.addEventListener("visibilitychange", () => {
  // 非アクティブのとき
  if (document.hidden) {
    app.stop(); // アプリを止める
    console.log("タブが非アクティブです");
  }
  // アクティブのとき
  else {
    app.start(); // アプリを再開する
    console.log("タブをアクティブにしました");
  }
});

これを行なうとブラウザを切り替えてもしっかり一時停止するようになりました。

おわりに

ブラウザ側の仕様なので、完全に解決したというよりむりやりな対策だと思います。

より良い方法が見つかったら記事にしておこうと思います。