521

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

HTML5 には、これを可能にする 3 つの要素 ( svgcanvas、およびdiv ) が用意されていることを理解しています。私がやりたいことに対して、それらの要素のどれが最高のパフォーマンスを提供しますか?

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

4

9 に答える 9

618

簡単な答え:

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

DIV は問題ありませんが、扱いにくく大量にロードするとパフォーマンスが低下します。

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


長い答え:

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

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

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

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

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

私は、HTML DIV で作成した描画と Canvas で作成した描画について、多くの数字を実行しました。それぞれの利点について大きな記事を書くこともできますが、特定のアプリケーションについて検討するために、テストの関連結果のいくつかを紹介します。

Canvas と HTML DIV のテスト ページを作成しました。どちらも移動可能な「ノード」を備えていました。キャンバス ノードは、私が Javascript で作成して追跡したオブジェクトでした。HTML ノードは移動可能な Div でした。

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

HTML テスト タブの読み込みに時間がかかりました (時間は 5 分弱で、Chrome は最初にページを強制終了するように求められました)。Chrome のタスク マネージャーは、タブが 168 MB を占めていると言っています。見ているときは 12 ~ 13% の CPU 時間を消費し、見ていないときは 0% です。

[キャンバス] タブは 1 秒で読み込まれ、30 MB を占めます。また、見ているかどうかに関係なく、常に CPU 時間の 13% を占めています。(2013年編集:彼らはほとんどそれを修正しました)

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

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

結論:

  • SVG は、アイテムが少ない (1000 未満? 本当に依存する) アプリケーションやアプリに適していると思われます。
  • Canvas は何千ものオブジェクトと慎重な操作に優れていますが、それを軌道に乗せるにはさらに多くのコード (またはライブラリ) が必要です。
  • HTML Div は扱いにくく、拡大縮小もできません。円を作成するには、角を丸くする必要があります。複雑な形状を作成することは可能ですが、数百もの小さなピクセル幅の div が必要です。狂気が起こります。
于 2011-05-04T12:02:21.693 に答える
41

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

私が見つけたのは、私の 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);
于 2014-01-26T04:25:26.113 に答える
29

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

キャンバス

SVG

  • 解像度に依存しない
  • イベント ハンドラーのサポート
  • 大きなレンダリング領域を持つアプリケーションに最適 (Google マップ)
  • 複雑な場合はレンダリングが遅くなります (DOM を頻繁に使用するものはすべて遅くなります)
  • ゲームアプリには不向き
于 2016-02-28T14:14:06.970 に答える
19

Simon Sarris の結論に同意します。

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

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

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

興味深いベンチマークを次に示します。

于 2011-05-05T09:39:26.673 に答える
18

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

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

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

于 2015-12-05T01:45:05.743 に答える
13

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

于 2011-05-04T11:55:35.323 に答える