HTML5 Canvas vs. SVG vs. div


476

その場で要素を作成し、それらを移動できるようにするための最良のアプローチは何ですか?たとえば、長方形、円、多角形を作成し、それらのオブジェクトを選択して移動したいとします。

HTML5がこれを可能にする3つの要素、svgcanvasdivを提供していることを理解しています。私がやりたいことについて、これらの要素のどれが最高のパフォーマンスを提供しますか?

これらのアプローチを比較するために、それぞれにヘッダー、フッター、ウィジェット、テキストコンテンツが含まれる、視覚的に同一の3つのWebページを作成することを考えていました。最初のページのウィジェットは完全にcanvas要素で作成され、2番目のウィジェットは完全に要素で作成されsvg、3番目のウィジェットはプレーンdiv要素、HTMLおよびCSSで作成されます。


13
これは興味深いかもしれません:CanvasとSVGをいつ使用するかについての考え
robertc

1
この技術に不慣れな方のために、このビデオではSVGとCanvasの両方と、それがhtml5にどのように統合されるかについてのその他の詳細を説明しています。
パウロ・ブエノ

12
短い答え:SVGがMS Powerpointと同じように、CanvasはMS Paintです。キャンバスはラスター、SVGはベクトルです。
GetFree 2014年

2
親愛なる読者:ここですべての比較とステートメントを細かく見て、投稿とコメントの日付を見てください。時代は変わったし、変わるだろう。相対的なパフォーマンス、さらにはオプションも変わります。たとえば、ほとんどの回答はWebGLがないときに書かれたもので、これは間違いなく代替手段です。数年後には古くなりますが、今日の時点では非常に関連性があるかもしれません。
セバスチャン

今日はどのセバスチャンをお勧めしますか?基本サイズ(1280x800など)が指定されていて、コードで要素を手動でスケーリングしたり、常にパーセンテージを使用したりする場合、DIVを使用することにSVGの利点はありますか?
Crashalot

回答:


563

短い答え:

SVGの方が簡単でしょう選択と移動はすでに組み込まれているため、です。SVGオブジェクトはDOMオブジェクトなので、「クリック」ハンドラーなどがあります。

DIVは大丈夫ですが不格好でひどいです大量のパフォーマンス負荷を。

Canvasのパフォーマンスは最も優れていますが、管理状態のすべての概念(オブジェクトの選択など)を自分で実装するか、ライブラリを使用する必要があります。


長い答え:

HTML5 Canvasは単にビットマップの描画面です。あなたは描くように設定し(色と線の太さで)、そのものを描くと、キャンバスはそのことの知識を持っていません:それがどこにあるのか、あなたが今描いたものは何なのかわかりません、それはピクセルのみ。四角形を描画して移動したり、選択可能にしたりする場合は、四角形を描画したことを覚えておくためのコードを含め、すべてを最初からコーディングする必要があります。

一方、SVGは、レンダリングする各オブジェクトへの参照を維持する必要があります。作成するすべてのSVG / VML要素は、DOMの実際の要素です。デフォルトでは、これにより、作成した要素をより適切に追跡でき、マウスイベントなどの処理がデフォルトで簡単になりますが、オブジェクト数が多い場合は速度が大幅に低下します

これらのSVG DOM参照は、描画するものを処理するフットワークの一部があなたのために行われることを意味します。また、非常に大きなオブジェクトをレンダリングする場合はSVGが高速になりますが、多くのオブジェクトをレンダリングする場合は低速になります。

Canvasの方がゲームはおそらく速いでしょう。巨大なマッププログラムは、おそらくSVGの方が高速です。Canvasを使用したい場合は、ここで可動オブジェクトを起動して実行するためのチュートリアルをいくつか用意しています

Canvasは、より高速なものやビットマップ操作(アニメーションなど)の負荷が高い場合に適していますが、多くの対話性が必要な場合はより多くのコードが必要になります。

私は、HTML DIV製の描画とCanvas製の描画で多数の数値を実行しました。私はそれぞれの利点について巨大な投稿をすることができましたが、私はあなたの特定のアプリケーションについて検討するために私のテストの関連する結果のいくつかを与えます:

CanvasとHTML DIVのテストページを作成しましたが、どちらにも移動可能な「ノード」がありました。Canvasノードは、私が作成してJavaScriptで追跡したオブジェクトでした。HTMLノードは移動可能なDivでした。

2つのテストのそれぞれに100,000ノードを追加しました。彼らはまったく異なるパフォーマンスを発揮しました:

HTMLテストタブの読み込みに時間がかかりました(5分弱のタイミングで、Chromeが最初にページを強制終了するように要求しました)。Chromeのタスクマネージャーによると、タブは168MBを占有しています。CPU時間は、私が見ているときは12〜13%、見ないときは0%かかります。

Canvasタブは1秒で読み込まれ、30MBを占有します。また、見ているかどうかに関係なく、常にCPU時間の13%を占めます。(2013編集:彼らは主にそれを修正しました)

現在の設定ではCanvasテストで30ミリ秒ごとにすべてを再描画するため、HTMLページでのドラッグはよりスムーズになりました。Canvasには、このための最適化がたくさんあります。(キャンバスの無効化が最も簡単で、クリッピング領域、選択的な再描画なども、実装したいという気持ちに依存します)

Canvasをその単純なテストのdivとしてオブジェクト操作でより速く、そしてもちろんロード時間ではるかに速くすることができることは間違いありません。Canvasでの描画/読み込みはより高速で、最適化の余地もはるかにあります(つまり、画面外のものを除外することは非常に簡単です)。

結論:

  • SVGはおそらく、アプリケーションやアイテムが少ない(1000未満?本当に依存する)アプリケーションに適しています。
  • Canvasは何千ものオブジェクトと注意深い操作には優れていますが、それを実現するには、さらに多くのコード(またはライブラリ)が必要です。
  • HTML Divは不格好で拡大縮小されません。円を作成することは、角が丸い場合にのみ可能です。複雑な形状を作成することは可能ですが、何百もの小さなピクセル幅の小さなdivが含まれます。狂気が続く。

4
ケーキのライブラリは、キャンバス上のオブジェクトと可動オブジェクトとアニメーションを行うための別の例である
SiggyF

間違っている:P divは、ブラウザーがハードウェアアクセラレーションCSSエンジンを使用している場合はスケーリングできます。CSSアートは異なり、ここではCanvasとSVGが適切です。CSSアート/ divアートは、小さなオーバーレイをオーバーキルする必要がない場合です:P
ShrekOverflow

DIVについては、円や特殊な形状を作成したいが、その画像やスプライトを変更しない場合は、PNGを作成して次のように使用background-imageできます
。SVG

4
インタラクティブな地図ゲームを作成している場合はどうなりますか?:p
アンソニー

これは(ネストされていない)DIVとCSS 3D変換を使用して作成されたので、DIVはまったく遅くありません:youtube.com/watch
Erik Kaplun

39

これに追加するために、私はダイアグラムアプリケーションを作成しており、最初はキャンバスから始めました。図は多くのノードで構成されており、かなり大きくなる可能性があります。ユーザーはダイアグラム内の要素をドラッグできます。

私が見つけたのは、私のMacでは、非常に大きな画像にはSVGが優れているということです。私はMacBook Pro 2013 13インチRetinaを使用していますが、下のフィドルをうまく実行します。画像は6000x6000ピクセルで、1000個のオブジェクトがあります。キャンバス内で同様の構造を使用して、ユーザーが図。

最新のディスプレイでは、さまざまな解像度も考慮する必要があります。SVGを使用すると、これらすべてが無料で提供されます。

フィドル:http : //jsfiddle.net/knutsi/PUcr8/16/

フルスクリーン:http : //jsfiddle.net/knutsi/PUcr8/16/embedded/result/

var wiggle_factor = 0.0;
nodes = [];

// create svg:
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.setAttribute('style', 'border: 1px solid black');
svg.setAttribute('width', '6000');
svg.setAttribute('height', '6000');

svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink",
    "http://www.w3.org/1999/xlink");

document.body.appendChild(svg);


function makeNode(wiggle) {
    var node = document.createElementNS("http://www.w3.org/2000/svg", "g");
    var node_x = (Math.random() * 6000);
    var node_y = (Math.random() * 6000);
    node.setAttribute("transform", "translate(" + node_x + ", " + node_y +")");

    // circle:
    var circ = document.createElementNS("http://www.w3.org/2000/svg", "circle");
    circ.setAttribute( "id","cir")
    circ.setAttribute( "cx", 0 + "px")
    circ.setAttribute( "cy", 0 + "px")
    circ.setAttribute( "r","100px");
    circ.setAttribute('fill', 'red');
    circ.setAttribute('pointer-events', 'inherit')

    // text:
    var text = document.createElementNS("http://www.w3.org/2000/svg", "text");
    text.textContent = "This is a test! ÅÆØ";

    node.appendChild(circ);
    node.appendChild(text);

    node.x = node_x;
    node.y = node_y;

    if(wiggle)
        nodes.push(node)
    return node;
}

// populate with 1000 nodes:
for(var i = 0; i < 1000; i++) {
    var node = makeNode(true);
    svg.appendChild(node);
}

// make one mapped to mouse:
var bnode = makeNode(false);
svg.appendChild(bnode);

document.body.onmousemove=function(event){
    bnode.setAttribute("transform","translate(" +
        (event.clientX + window.pageXOffset) + ", " +
        (event.clientY + window.pageYOffset) +")");
};

setInterval(function() {
    wiggle_factor += 1/60;
    nodes.forEach(function(node) {

        node.setAttribute("transform", "translate(" 
                          + (Math.sin(wiggle_factor) * 200 + node.x) 
                          + ", " 
                          + (Math.sin(wiggle_factor) * 200 + node.y) 
                          + ")");        
    })
},1000/60);

2
Canvasを動作させるために必死に努力した後、私たちはSVGにも落ち着きました。非常に大きな図があり、SVGが群を抜いて最も効率的であり、さらに網膜画面での自動スケーリングは大きなボーナスです。
フィジット2015年

knutと@Fijjitは、SVGの代わりにDIVの使用を検討しましたか?基本サイズ(たとえば、1280x800)が指定されている場合、DIVを手動でスケーリングしてSVGと同じくらいシャープに見えないでしょうか?ご協力いただきありがとうございます!
Crashalot

24

SVGとCanvasの違いを理解しておくと、正しいものを選択するのに役立ちます。

キャンバス

SVG

  • 解像度に依存しない
  • イベントハンドラーのサポート
  • レンダリング領域が大きいアプリケーションに最適(Googleマップ)
  • 複雑な場合のレンダリングが遅い(DOMを頻繁に使用するものはすべて遅くなります)
  • ゲームアプリケーションには適していません

8
Canvasは解像度に依存していると人々が言うのはなぜですか?ビットマップがいったんレンダリングされると、うまくスケーリングしないことを理解しています。しかし、解像度サイズの変更時に再描画することができるので、その解像度はどのようにして独立しないのですか?
Alex Bollbach 2017

@AlexBollbach-Canvasは解像度に依存します。良い結果を得るには解像度に考慮する(依存する)必要があるためです。SVGでは、解像度を気にする必要はありません。2400DPIプリンターとCanvasベースのレンダリングでぎざぎざの線が表示されないように頑張ってください。SVGで問題ありません。
セバスチャン

18

サイモンサリスの結論に同意します。

Protovis(SVG)でのいくつかの視覚化を> 2000ポイントを表示するProcessingjs(Canvas)と比較しましたが、processingjsはprotovisよりもはるかに高速です。

もちろん、SVGを使用してイベントを処理する方が、イベントをオブジェクトにアタッチできるため、はるかに簡単です。Canvasでは、手動で行う必要があります(マウスの位置を確認するなど)が、簡単な操作では難しくありません。

dojoツールキットのdojo.gfxライブラリーもあります。抽象レイヤーを提供し、レンダラー(SVG、Canvas、Silverlight)を指定できます。追加の抽象化レイヤーが追加するオーバーヘッドの量はわかりませんが、これも実行可能な選択肢かもしれませんが、インタラクションとアニメーションのコーディングが簡単になり、レンダラーに依存しません。

ここにいくつかの興味深いベンチマークがあります:


17

divsオプションに関する私の2セント。

Famous / InfamousとSamsaraJS(そしておそらく他の人)は、位置付けと2D / 3D変換のためにmatrix2d / matrix3dと組み合わせて、絶対に配置されたネストされていないdiv(重要なHTML / CSSコンテンツを含む)を使用し、中程度のモバイルハードウェアで安定した60FPSを実現します、それで私はdivが遅いオプションであることに対して反対するでしょう。

Youtubeや他の場所には、ブラウザで実行されている高性能の2D / 3D要素の多くの画面記録があります。すべてが60FPSで要素検査できるDOM要素です(特定の効果のためにWebGLと混合されますが、レンダリングの主要部分)。


14

上記の答えのほとんどにはまだいくつかの真実がありますが、私はそれらが更新に値すると思います:

長年にわたり、SVGのパフォーマンスは大幅に改善され、JavaScriptのパフォーマンスにまったく依存しない、SVGのハードウェアアクセラレーションによるCSSトランジションとアニメーションが存在しています。もちろん、JavaScriptのパフォーマンスも向上し、それに伴いCanvasのパフォーマンスも向上しましたが、SVGは向上していません。また、現在、ほぼすべてのブラウザーで利用可能な「新しい子供」がいて、それがWebGLです。上記でSimonが使用したのと同じ単語を使用するには:CanvasとSVGの両方に勝る手をます。ただし、これは頼りになるテクノロジである必要があるという意味ではありません。これは、動作するのは野獣であり、非常に特定のユースケースでのみ高速になるためです。

今日のほとんどのユースケースで私見であるSVGは、最高のパフォーマンス/ユーザビリティ比を提供します。可視化は、(要素の数に関して)非常に複雑であり、同時に(要素ごとに)本当に単純である必要があります。これにより、Canvasはさらに、WebGLは本当に輝きます。

同様の質問への答えは、この私がいることを考える理由私は、より多くの詳細を提供しています組み合わせ、すべての3つの技術のは時々あなたが持っている最高のオプションです。


Unixユーザーは、FirefoxとChromiumの両方でハードウェアアクセラレーションがデフォルトで無効になっていることに注意する必要があります。2019
同じ

@NVRM-これはCSSおよびSVGのハードウェアアクセラレーションに関するものであり、ビデオのデコードに関するものではありません。前者のAFAIKは何年も前から利用可能です。chrome :// gpuの出力を確認してください
セバスチャン

layers.acceleration.force-enabledFirefoxでは、ビデオのデコードについてではありません。それはよく知られた事実です。完了したら、requestAnimationFrameを使用したループは別のレベルであり、より多くの再描画が可能です。全くビデオについてではありません。
NVRM

@NVRM-LinuxでのこれらのGPU問題に関するFFおよびChromiumのバグへのリンクを提供できますか?また、「ハードウェアアクセラレーション」とは、GPUアクセラレーションだけでなく、マルチスレッドの合成やアニメーション(JavaScriptが実行されていない間、またはJSが実行されている間も回転し続けるスピナーの読み込みなど)も指していることに注意してください。これはCanvasでは不可能であり、純粋な「JavaScript」と比較すると、すべてのプラットフォームのChromeとFFで確実に利用できるある種のハードウェアアクセラレーション(マルチスレッド)です。ありがとう!
セバスチャン

1
現在の状況を要約すると、ChromeとChromiumで動作します。Linuxの場合。2019年。すべてのインスタンスで、特別な構成なしでテストしました。Firefox / MozillaはLinuxで動作しますが、アウトプロセスレンダリングはFFにとっても新しいものではなく、SVGやCSSなどでCanvasの場合よりも常にうまく機能します。
セバスチャン

13

ドラッグアンドドロップを含むマウス処理などのDOMイベントが含まれているため、SVGを使用することをお勧めします。独自の再描画を実装する必要はなく、状態を追跡する必要もありません。あなたのオブジェクト。ビットマップ画像の操作を行う必要がある場合はCanvasを使用し、HTMLで作成されたものを操作する場合は通常のdivを使用します。パフォーマンスについては、最近のブラウザーが3つすべてを高速化していることがわかりますが、そのキャンバスはこれまで最も注目されています。一方、JavaScriptをいかに上手に書くかは、canvasで最大のパフォーマンスを得るのに重要であるため、SVGの使用をお勧めします。


1
実際にプレーンHTMLを使用することは、CSS画像と組み合わせると最もパフォーマンスが高くなります。
レイノス

16
@Raynos:ソース?
Janus Troelsen 2013年

3

グーグルしながら、SVGの使用法と圧縮についての良い説明を見つけますhttp://teropa.info/blog/2016/12/12/graphics-in-angular-2.htmlCanvasの

それが役に立てば幸い:

  • HTMLと同様に、SVGは保持レンダリングを使用します。画面上に四角形を描画する場合、DOM内の要素を宣言的に使用します。その後、ブラウザは長方形を描画しますが、長方形を表すメモリ内のSVGRectElementオブジェクトも作成します。このオブジェクトは、私たちが操作するために固執するものです–それは保持されます。時間の経過とともに、さまざまな位置とサイズを割り当てることができます。イベントリスナーをアタッチしてインタラクティブにすることもできます。
  • Canvasは即時レンダリングを使用します長方形描画すると、ブラウザはすぐに画面上に長方形をレンダリングしますが、それを表す「長方形オブジェクト」はありません。キャンバスバッファーにあるのは、ピクセルの束です。長方形は移動できません。別の長方形を描くことしかできません。四角形のクリックやその他のイベントには応答できません。キャンバス全体のイベントにのみ応答できます

したがって、canvasはSVGよりも低レベルの制限的なAPIです。しかし、それとは逆に、canvasを使用すると、同じ量のリソースでより多くのことができるようになります。ブラウザは、描画したすべてのオブジェクトのメモリ内オブジェクトグラフを作成して維持する必要がないため、同じビジュアルシーンを描画するために必要なメモリと計算リソースが少なくて済みます。描画する非常に大きく複雑な視覚化がある場合、Canvasがあなたのチケットになるかもしれません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.