OffscreenCanvas - ウェブワーカーを使用してキャンバスの処理を高速化

Tim Dresser

キャンバスは あらゆる種類のグラフィックを画面上に描画し、WebGL の世界への入り口となっています。 図形や画像の描画、アニメーションの実行、さらには動画コンテンツの表示と処理に使用できます。 メディアが多用されたウェブ アプリケーションで美しいユーザー エクスペリエンスを実現したり、 説明します。

スクリプト化可能です。つまり、キャンバスに描画されるコンテンツをプログラムで作成できます。 使用できます。これによりキャンバスの柔軟性が高まり、

同時に、最新のウェブサイトでは、スクリプトの実行は最も頻繁に行われる ユーザーの反応の問題の原因を特定します。 キャンバスのロジックとレンダリングはユーザー操作と同じスレッドで行われるため、 アニメーションに関わる計算処理は(場合によっては負荷の高い)処理で、アプリの実際の処理に 把握するのに役立ちます

幸いなことに OffscreenCanvas は 脅威への対処です。

対応ブラウザ

  • 69
  • 79
  • 105
  • 16.4

ソース

以前は、キャンバスの描画機能は <canvas> 要素に関連付けられていました。 つまり DOM に直接依存していましたOffscreenCanvas は DOM と Canvas API を画面外に移動して分離しています。

この分離により、OffscreenCanvas のレンダリングは DOM から完全に切り離され、 同期が行われないため、通常のキャンバスより速度が向上します。 比較します。

さらに、ウェブワーカーで使用できる点が異なります。 DOM は利用可能です。これにより、あらゆる種類の興味深いユースケースが可能になります。

ワーカーで OffscreenCanvas を使用する

ワーカー スレッドのウェブ バージョンであり、タスクをバックグラウンドで実行できます。

スクリプトの一部をワーカーに移動すると、アプリがユーザー クリティカルな処理を実行する際の空き容量が増えます。 実行することもできます。OffscreenCanvas がなければ、ワーカーで Canvas API を使用する方法はありませんでした。 DOM がありませんでした

OffscreenCanvas は DOM に依存しないため、使用できます。次の例では OffscreenCanvas を使用しています ワーカーのグラデーション色を計算するには:

// file: worker.js
function getGradientColor(percent) {
  const canvas = new OffscreenCanvas(100, 1);
  const ctx = canvas.getContext('2d');
  const gradient = ctx.createLinearGradient(0, 0, canvas.width, 0);
  gradient.addColorStop(0, 'red');
  gradient.addColorStop(1, 'blue');
  ctx.fillStyle = gradient;
  ctx.fillRect(0, 0, ctx.canvas.width, 1);
  const imgd = ctx.getImageData(0, 0, ctx.canvas.width, 1);
  const colors = imgd.data.slice(percent * 4, percent * 4 + 4);
  return `rgba(${colors[0]}, ${colors[1]}, ${colors[2]}, ${colors[3]})`;
}

getGradientColor(40);  // rgba(152, 0, 104, 255 )

メインスレッドのブロックを解除

負荷の高い計算をワーカーに移動すると メインスレッドに集中できます。transferControlToOffscreen を使用する メソッドを使って通常のキャンバスを OffscreenCanvas インスタンスにミラーリングします。適用先のオペレーション OffscreenCanvas は自動的にソース キャンバスにレンダリングされます。

const offscreen = document.querySelector('canvas').transferControlToOffscreen();
const worker = new Worker('myworkerurl.js');
worker.postMessage({canvas: offscreen}, [offscreen]);

次の例では、カラーテーマが変更されたときに負荷の高い計算が行われています。 高速のデスクトップでも数ミリ秒かかりますアニメーションをメインスレッドで実行することもできます。 ワーカーで実行されますメインスレッドの場合、負荷の大きい処理が行われている間はボタンを スレッドはブロックされます。ワーカーの場合 UI の応答性

<ph type="x-smartling-placeholder">
</ph>
デモ

その逆も同様です。ビジー状態のメインスレッドは、実行中のアニメーションに影響しません。 指定します。この機能を使用すると、視覚的なジャンクを防ぎ、スムーズなアニメーションを保証できます。 すべてのインスタンスを保護します。

<ph type="x-smartling-placeholder">
</ph>
デモ

通常のキャンバスの場合、メインスレッドが人為的にオーバーワークすると、アニメーションが停止します。 ワーカーベースの OffscreenCanvas は滑らかに再生されます。

OffscreenCanvas API は一般に通常の Canvas 要素と互換性があるため、 市場をリードするグラフィック ライブラリとともに、プログレッシブな機能強化として使用できます。

たとえば、Feature-Detect を使用できます。利用可能であれば、Google 検索の canvas オプションを使用します。

const canvasEl = document.querySelector('canvas');
const canvas =
  'OffscreenCanvas' in window
    ? canvasEl.transferControlToOffscreen()
    : canvasEl;
canvas.style = {width: 0, height: 0};
const renderer = new THREE.WebGLRenderer({canvas: canvas});

ここでの問題は、Three.js では、canvas には style.width プロパティと style.height プロパティがあると想定している点です。 OffscreenCanvas は DOM から完全にデタッチされているため、自分で用意する必要があります。 スタブするか、これらの値を元の値に結び付ける 指定します。

以下は、ワーカーで基本的な Three.js アニメーションを実行する方法を示しています。

<ph type="x-smartling-placeholder">
</ph>
デモ

一部の DOM 関連 API は、ワーカーではすぐに利用できないため、 より高度な Three.js 機能(テクスチャなど)を使用する場合は、追加の回避策が必要になることがあります。 これらを試す方法のヒントについては、 Google I/O 2017 の動画

キャンバスのグラフィック機能を多用している場合、OffscreenCanvas は 影響するためですワーカーがキャンバス レンダリング コンテキストを利用できるようにすることで、 並列処理を行い、マルチコア システムをより有効に活用します。

参考情報