Create.jsのText描画パフォーマンスを改善するキャッシュ処理


はじめに

このドキュメントは、Create.jsのテキスト設定について、

  1. グローバル設定による描画速度の変化
  2. 描画速度低下の対策

の2点を解説するためのものです。

Create.jsでのText描画

Note: Text can be expensive to generate, so cache instances where possible.

公式ドキュメントにもあるとおり、Create.jsでのテキストの描画は比較的重い処理です。
とくにこんな場合に重くなります。

  1. テキストにアウトラインフォントを設定している場合。
  2. snapToPixelの設定を変更した場合。
createjs.Text.prototype.snapToPixel = false;

このグローバル設定を行うとテキスト描画にアンチエイリアスがかかりますが、その分描画処理が重くなります。

描画速度の検証

アウトラインフォントの描画速度を改善する効果的な対策は、ビットマップキャッシュの適用です。

  • 通常のテキストを8000個ステージに並べる。(CodePen
  • テキストに個別にビットマップキャッシュをかける。(CodePen

手元の環境ではFPSでおおよそ3倍の差が出ます。

テキストへのビットマップキャッシュの適用方法

テキストのビットマップキャッシュの適用にはバウンディングボックスの取得が必要になります。
しかしTextは、getBounds関数では厳密にはサイズを取得できません。

公式ドキュメント

const bounds = text.getBounds();
const margin = 8;
text.cache(
  bounds.x - margin,
  bounds.y - margin,
  bounds.width + margin * 2,
  bounds.height + margin * 2
);

上記の例では8pxですが、幾らかのマージンを与えると意図した通りの描画になります。

ビットマップキャッシュの更新判定

キャッシュされたテキストは、更新のない間は高速に描画されます。
しかし再描画が必要になったり、キャッシュの縦横サイズを変更しなくてはならない場合は大きな負荷がかかります。

テキスト更新が発生した場合に、以下の条件で判定を行い、変更がない場合は再描画を抑制すると負荷が軽減できます。

  • 文言が変更されている
  • フォントが変更されている
  • textAlignが変更されている : キャッシュのサイズが変化するので、uncacheをしてから再cacheする。
  • 文字カラーだけが変更されている : キャッシュのサイズは変わらないので、updateCacheする。
  • 文言の変化がない : キャッシュ処理をスキップ。

更新判定のモジュール化

これらの更新判定処理をまとめたモジュールを作成しました。

CreatejsCacheUtil.cacheText(textField, "textContents", option);

第一引数はcreatejs.Textオブジェクト、第二引数が更新するテキストの内容、第三引数がテキストの描画オプション(省略可能)です。なんらかの変更がある場合は第一引数のTextオブジェクトのビットマップキャッシュを更新し、必要がない場合は更新をスキップします。

よりパフォーマンスを重視するならContainerにラップしてからキャッシュ生成

Textインスタンスに個別にビットマップキャッシュを適用するよりも、そのインスタンスをContainerにaddChildして、コンテナー丸ごとをビットマップキャッシュする方がパフォーマンス的には有利です。テキストの更新頻度が低く、大量のテキストを扱う場合はぜひContainerにラップしてください。