[javascript] HTML5 캔버스 vs. SVG vs. div

요소를 즉석에서 생성하고 이동할 수있는 가장 좋은 방법은 무엇입니까? 예를 들어 직사각형, 원 및 다각형을 만든 다음 해당 객체를 선택하고 이동한다고 가정 해 봅시다.

HTML5는이를 가능하게하는 세 가지 요소 svg , canvasdiv를 제공한다는 것을 알고 있습니다 . 내가하고 싶은 일에 대해 어떤 요소가 최고의 성능을 제공합니까?

이러한 접근 방식을 비교하기 위해 각각 머리글, 바닥 글, 위젯 및 텍스트 내용이 포함 된 시각적으로 동일한 웹 페이지 3 개를 만들려고했습니다. 첫 번째 페이지의 위젯은 canvas요소로, 두 번째는 svg요소로, 세 번째는 일반 div요소로 HTML 및 CSS로 작성됩니다.



답변

짧은 대답 :

SVG가 더 쉬울 것입니다 선택과 이동이 이미 내장되어 있기 때문에 입니다. SVG 객체는 DOM 객체이므로 “클릭”핸들러 등이 있습니다.

DIV는 괜찮지 만 어색하고 끔찍합니다 많은 수의 성능 부하를.

Canvas는 최상의 성능을 제공하지만 관리 상태 (개체 선택 등)의 모든 개념을 직접 구현하거나 라이브러리를 사용해야합니다.


긴 대답 :

HTML5 Canvas는 단순히 비트 맵을위한 드로잉 표면입니다. 당신은 (색상과 선 두께로 말해) 그리기를 설정하고, 그 다음에 그 그림을 알지 못합니다. 캔버스는 그 물건에 대해 알지 못합니다. 단지 픽셀. 사각형을 그리거나 이동하거나 선택하려면 사각형 을 그린 것을 기억하는 코드를 포함 하여 처음부터 끝까지 코딩해야합니다.

반면에 SVG는 렌더링하는 각 객체에 대한 참조를 유지해야합니다. 생성 한 모든 SVG / VML 요소는 DOM의 실제 요소입니다. 기본적으로 이렇게하면 생성 한 요소를 훨씬 더 잘 추적 할 수 있으며 기본적으로 마우스 이벤트와 같은 문제를보다 쉽게 ​​처리 할 수 ​​있지만 많은 수의 객체가있을 경우 속도가 크게 느려집니다

이러한 SVG DOM 참조는 당신이 그리는 것들을 다루는 발자국 중 일부가 당신을 위해 수행되었음을 의미합니다. SVG는 실제로 큰 객체를 렌더링 할 때는 빠르지 만 많은 객체를 렌더링 할 때는 느립니다 .

캔버스에서 게임이 더 빠를 것입니다. SVG에서 거대한지도 프로그램이 더 빠를 것입니다. Canvas를 사용하려면 움직일 수있는 객체를 만들고 실행하는 방법에 대한 자습서가 있습니다. .

Canvas는 더 빠른 작업과 많은 비트 맵 조작 (애니메이션과 같은)에는 좋지만 많은 상호 작용을 원할 경우 더 많은 코드를 사용합니다.

HTML DIV 제작 도면과 Canvas 제작 도면에서 많은 숫자를 실행했습니다. 각각의 이점에 대해 큰 글을 쓸 수는 있지만 특정 응용 프로그램에 대해 고려해야 할 관련 테스트 결과를 제공합니다.

Canvas와 HTML DIV 테스트 페이지를 만들었습니다. 둘 다 움직일 수있는 “노드”를 가지고있었습니다. 캔버스 노드는 Javascript에서 만들고 추적 한 객체였습니다. HTML 노드는 움직일 수있는 Divs였습니다.

두 테스트 각각에 100,000 개의 노드를 추가했습니다. 그들은 상당히 다르게 수행했습니다.

HTML 테스트 탭을로드하는 데 시간이 조금 걸렸습니다 (약 5 분이 채 걸리지 않아 Chrome에서 처음으로 페이지를 죽 이도록 요청했습니다). 크롬의 작업 관리자는 탭이 168MB를 차지한다고 말합니다. 내가 볼 때 CPU 시간은 12-13 %,보고 있지 않을 때는 0 %가 걸립니다.

캔버스 탭은 1 초 안에로드되며 30MB를 차지합니다. 또한보고 있든 없든 항상 CPU 시간의 13 %를 차지합니다. (2013 편집 : 그들은 주로 고정했습니다)

현재 설정이 Canvas 테스트에서 30 밀리 초마다 다시 그려 지므로 HTML 페이지를보다 부드럽게 드래그 할 수 있습니다. 이를 위해 Canvas에 대한 최적화가 많이 있습니다. (캔버스 무효화가 가장 쉬우 며 클리핑 영역, 선택적 다시 그리기 등은 구현하려는 느낌에 따라 다릅니다.)

의심 할 여지없이, 간단한 테스트에서 div가 객체 조작에서 Canvas가 더 빨라지고로드 시간이 훨씬 빠를 수 있습니다. 캔버스에서 그리기 /로드가 더 빠르며 최적화를위한 훨씬 더 많은 공간이 있습니다 (예를 들어, 화면 밖의 것을 제외하는 것은 매우 쉽습니다).

결론:

  • SVG는 아마도 항목이 적은 응용 프로그램 및 응용 프로그램에 더 좋습니다 (1000 미만? 실제로 의존합니다)
  • 캔버스는 수천 개의 객체와 신중한 조작에 더 좋지만,이를 처리하려면 훨씬 더 많은 코드 (또는 라이브러리)가 필요합니다.
  • HTML Divs는 복잡하고 크기가 조정되지 않으므로 둥근 모서리로만 원을 만들 수 있으며 복잡한 모양을 만들 수 있지만 수백 개의 작은 픽셀 너비 div가 필요합니다. 광기가 발생합니다.

답변

이것에 덧붙여서, 나는 다이어그램 응용 프로그램을하고 있었고 처음에는 캔버스로 시작했습니다. 다이어그램은 많은 노드로 구성되며 상당히 커질 수 있습니다. 사용자는 다이어그램에서 요소를 드래그 할 수 있습니다.

내가 찾은 것은 내 Mac에서 매우 큰 이미지의 경우 SVG가 우수하다는 것입니다. MacBook Pro 2013 13 “Retina가 있는데 아래에서 바이올린을 아주 잘 실행합니다. 이미지는 6000×6000 픽셀이고 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);


답변

SVG와 Canvas의 차이점을 아는 것이 올바른 것을 선택하는 데 도움이 될 것입니다.

캔버스

SVG

  • 독립 해상도
  • 이벤트 핸들러 지원
  • 넓은 렌더링 영역이있는 응용 프로그램에 가장 적합 (Google Maps)
  • 복잡한 경우 느린 렌더링 (DOM을 많이 사용하는 모든 것이 느려질 수 있음)
  • 게임 애플리케이션에 적합하지 않음

답변

Simon Sarris의 결론에 동의합니다.

Protovis (SVG)의 일부 시각화를> 2000 포인트를 표시하는 Processingjs (Canvas)와 비교했으며 processingjs는 protovis보다 훨씬 빠릅니다.

SVG로 이벤트를 처리하는 것은 물론 객체에 연결할 수 있기 때문에 훨씬 쉽습니다. Canvas에서는 수동으로 (마우스 위치 확인 등)해야하지만 간단한 상호 작용을 위해 어렵지 않아야합니다.

dojo 툴킷 의 dojo.gfx 라이브러리 도 있습니다 . 추상화 계층을 제공하며 렌더러 (SVG, Canvas, Silverlight)를 지정할 수 있습니다. 추가 추상화 레이어가 얼마나 많은 오버 헤드를 추가하는지 모르지만 상호 작용과 애니메이션을 쉽게 코딩 할 수 있으며 렌더러와 무관합니다.

흥미로운 벤치 마크는 다음과 같습니다.


답변

div 옵션과 관련하여 2 센트입니다.

Famous / Infamous 및 SamsaraJS (및 기타)는 포지셔닝 및 2D / 3D 변환을 위해 matrix2d / matrix3d와 결합 된 절대 위치가 아닌 div (간편하지 않은 HTML / CSS 내용 포함)를 사용하고, 적당한 모바일 하드웨어에서 안정적인 60FPS를 달성합니다. 그래서 div가 느린 옵션이라고 주장합니다.

Youtube와 다른 곳에서 많은 화면 녹화가 있으며 브라우저에서 실행되는 고성능 2D / 3D 항목 은 60FPS에서 요소검사 할 수있는 DOM 요소이며 (웹 GL과 혼합되어 특정 효과는 있지만 렌더링의 주요 부분).


답변

위의 대부분의 답변에는 여전히 진실이 있지만 업데이트가 필요하다고 생각합니다.

수년에 걸쳐 SVG의 성능이 많이 향상되었으며 이제는 JavaScript 성능에 전혀 의존하지 않는 SVG대한 하드웨어 가속 CSS 전환 및 애니메이션이 있습니다. 물론 JavaScript 성능도 향상되었으며 Canvas의 성능은 향상되었지만 SVG는 향상되지 않았습니다. 또한 오늘날 거의 모든 브라우저에서 사용할 수있는 “새 아이”가 있으며 이는 WebGL 입니다. Simon이 위에서 사용한 것과 동일한 단어를 사용하려면 Canvas와 SVG를 모두 능가합니다. . 그렇다고해서 그것이 기술이되어야한다는 의미는 아닙니다. 왜냐하면 작업하기가 가장 어려우며 매우 구체적인 사용 사례에서만 더 빠르기 때문입니다.

오늘날 대부분의 유스 케이스에 대한 IMHO의 SVG는 최고의 성능 / 사용성 비율을 제공합니다. 시각화는 요소 수와 관련하여 실제로 복잡하고 동시에 요소별로 단순해야하므로 Canvas 및 훨씬 더 WebGL이 실제로 빛납니다.

에서 비슷한 질문이 대답 내가 생각하는 이유는, 더 자세한 정보를 제공하고 조합 세 가지 기술은 때때로 당신이 가지고있는 최선의 방법입니다.


답변

드래그 앤 드롭을 포함한 마우스 처리와 같은 DOM 이벤트가 포함되어 있으므로 자체 다시 그리기를 구현할 필요가 없으며 상태를 추적 할 필요가 없으므로 SVG를 사용하는 것이 좋습니다. 당신의 개체. 비트 맵 이미지 조작을 수행해야하는 경우 Canvas를 사용하고 HTML로 작성된 항목을 조작하려면 일반 div를 사용하십시오. 성능에 관해서는 최신 브라우저가 세 가지 모두 가속화되고 있지만 캔버스는 지금까지 가장 많은 주목을 받았습니다. 반면, 캔버스를 최대한 활용하는 데 자바 스크립트를 얼마나 잘 작성 하는가가 중요하므로 SVG를 사용하는 것이 좋습니다.