Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

【HTML】Canvasの高速化【JavaScript】

More than 1 year has passed since last update.

Canvasで描画をしていて遅いってことはありませんか?

仕事で実際に試した方法を記載いたします。
iPadの第4世代のsafari、AndroidのChrome、Windowsのie11,Edgeで効果があることを確認しております。

1: requestAnimationFrameを使おう

requestAnimationFrameはsetTimeoutのようなAPIです。
requestAnimationFrameの使い方については、こちらを参照してください。

1-1: まずは単純なアニメーションでrequestAnimationFrameを使おう

これはそれほど効果ありませんが、setTimeoutやsetIntervalでアニメーション作成するより
いいそうです。

1-2: mousemove/touchmoveなどの動作イベントでもrequestAnimationFrameを使おう

canvas上に四角が存在し、それをドラッグするプログラムを考えます。
描画をmousemove / touchmoveのタイミングで行うのではなく、
mousemove / touchmoveでは描画に必要な情報を更新し、requesAnimationFrameで描画するようにすると、
表示が滑らか?になります。

2: backBuffer(DOMに追加されないCanvas)を使おう

動的にCanvasを作成し、それに事前に描画しておき、最終的に表示したいCanvasにレンダリングすると表示が速くなります。
例えば、Canvas上にある位置に丸、三角、四角が表示されていて、それが3つある場合を考えてみます。
丸、三角、四角は画像であるとします。
以下のようなケースです。
frontbuffer.png
普通に実装すると、画像の読み込み後、canvasに丸、三角、四角を3回ずつ描画することになります。

ですが、ここでcanvasを作成して(backBufferと呼ぶことにします。)、それに丸、三角、四角をまとめて描画しておけば、
そのbackBufferをcanvasに3回描画すればよいことになります。

backbuffer.png

3: クリアする矩形のサイズ又は回数を減らそう

canvasに描画する前にclearRectメソッドを呼び出してcanvas全体をクリアしていると思いますが、
全体をクリアするのではなく必要な箇所のみクリアするとパフォーマンスがよくなります。
また複数のcanvasを使用している場合、canvasをクリアする回数を減らすとパフォーマンスがよくなります。

4: GPU使えばいいんじゃね?

正解です。書き直す工数のある方はwebGL使いましょう。
2DのwebGLのライブラリとしてはpixi.js,createJSが有名です。

PG0721
最近は機械学習、統計、データ解析に興味があります。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away