HTMLのCanvas要素の描画性能を調べてみる

HTMLのCanvas要素にビットマップを描画する場合、どの程度の性能がでるのか、試してみました。

<html>
    <body>
        <script
            src="https://code.jquery.com/jquery-3.2.1.js"
            integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE="
            crossorigin="anonymous"></script>
        <p><div id="time">Time[ms]</div></p>
        <canvas id="canvas" width="1920" height="1080"></canvas>
        <script type="text/javascript">
            $(window).on('load', function(){
                var tm = 0;
                var canvas = $('#canvas').get(0);
                var width = canvas.width;
                var height = canvas.height;
                var ctx = canvas.getContext('2d');
                var imageData = ctx.getImageData(0, 0, width, height);

                var buf = new ArrayBuffer(imageData.data.length);
                var buf8 = new Uint8ClampedArray(buf);
                var data = new Uint32Array(buf);
                var start_ms = performance.now();
                var elapsed_ms;

                var draw = function(){
                    for (var j = 0; j < height; j++){
                        for (var i = 0; i < width; i++){
                            var val = (i+j+tm) & 0xFF;
                            data[j*width+i] =   (255 << 24) |
                                                (val << 16) |
                                                (val << 8) |
                                                val;
                        }
                    }
                    imageData.data.set(buf8);
                    ctx.putImageData(imageData, 0, 0);
                    tm++;
                    if (tm % 60 == 0){
                        var current = performance.now();
                        elapsed_ms = current - start_ms;
                        $("#time").text(elapsed_ms/60.0 + "[ms]");
                        start_ms = current;
                    }
                }
                setInterval(draw, 5);
            });
        </script>
    </body>
</html>

setIntervalに小さめの値を設定することで、できるだけ頻繁にdraw関数での描画が実行されるようにしました。

試してみると、ジッタがありますが、12-15[ms]程度に1回の描画が行われているようです。 試した環境は、Core i7-6500U, Windows 10, Firefox 57.0.2 (64bit)です。 動作中は、Firefoxのプロセスが30%程度のCPU時間を消費し、GPUは55%程度を示しています(タスクマネージャで計測)。

以上から、この程度のコードでも、ハイビジョン解像度で60fps程度の性能は達成できそうだということが分かりました。

参考:Fast pixel drawing on canvas

comments powered by Disqus