HTML5 캔버스 vs. SVG vs. div


476

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

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

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



1
이 기술에 익숙하지 않은 분들을 위해이 비디오 는 SVG와 Canvas 및 html5에서 어떻게 통합되는지에 대한 기타 세부 사항을 다룹니다.
Paulo Bueno

12
짧은 대답 : SVG는 MS Powerpoint에 따라 Canvas는 MS Paint에 있습니다. 캔버스는 래스터이고 SVG는 벡터입니다.
GetFree

2
친애하는 독자 : 소금과 함께 여기에 모든 비교와 진술을 취하고 게시물과 의견의 날짜를보십시오. 시간이 바뀌었고 바뀔 것입니다. 상대 성능과 옵션도 변경됩니다. 예를 들어 WebGL이 없을 때 작성된 대부분의 답변은 대안입니다. 몇 년 후에도 구식이 될 것이지만 오늘날에는 매우 관련성이 있습니다.
Sebastian

@Sebastian 오늘 추천 하시겠습니까? 기본 크기 (예 : 1280x800)가 주어지고 코드에서 요소를 수동으로 스케일하거나 항상 백분율을 사용하려는 경우 SVG가 DIV를 사용하는 것보다 이점이 있습니까?
Crashalot

답변:


563

짧은 대답 :

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가 필요합니다. 광기가 발생합니다.

4
케이크 라이브러리는 캔버스에 개체 이동 객체와 애니메이션을하는 또 다른 예이다
SiggyF

잘못 : P div는 브라우저가 hw 가속 CSS 엔진을 사용하는 경우 확장 가능하며 CSS 아트는 다르며 캔버스와 SVG 외에도 적절한 선택입니다 .CSS 아트 / div 아트는 단지 작은 오버레이를 과도하게 처리 할 필요가 없을 때입니다 : P
ShrekOverflow

DIV와 관련하여 원 / 특수 모양을 만들고 싶을 때 이미지 / 스프라이트를 변경하지 않으려는 경우 PNG를 만들어서 그대로 사용할 background-image수 있습니다. SVG / Canvas에서 비슷한 작업을 수행 할 수 있습니다
luiges90

4
대화식지도 게임을 만드는 경우 어떻게됩니까? : p
Anthony

이것은 (중첩되지 않은) DIV 및 CSS 3D 변환을 사용하여 만들어
졌으므로

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는 가장 효율적이며, 망막 화면의 자동 스케일링은 큰 보너스입니다.
Fijjit

knut 및 @Fijjit SVG 대신 DIV 사용을 고려 했습니까? 기본 크기 (예 : 1280x800)가 주어진 경우 SVG만큼 선명하게 보이도록 DIV를 수동으로 조정할 수 없습니까? 당신의 도움을 주셔서 감사합니다!
Crashalot

24

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

캔버스

SVG

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

8
사람들은 왜 캔버스가 해상도에 의존한다고 말합니까? 일단 비트 맵이 렌더링되면 확장 성이 좋지 않다는 것을 이해합니다. 그러나 해상도 크기 변경에 대해 다시 그릴 수 있으므로 해당 해상도가 어떻게 독립적이지 않습니까?
Alex Bollbach

@AlexBollbach-Canvas는 해상도에 따라 달라집니다. 좋은 결과를 얻으려면 해상도를 고려해야합니다. SVG를 사용하면 해상도에 신경 쓰지 않습니다. 2400DPI 프린터에서 캔버스가 아닌 선과 캔버스 기반 렌더링을 사용하는 것이 좋습니다. SVG에는 문제가 없습니다.
Sebastian

18

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

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

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

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

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


17

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

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

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


14

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

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

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

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


Unix 사용자는 Firefox와 Chromium에서 하드웨어 가속이 기본적으로 비활성화되어 있으며 2019
NVRM

@NVRM-이것은 비디오 디코딩이 아니라 CSS 및 SVG의 하드웨어 가속에 관한 것입니다. AFAIK 전자는 몇 년 동안 사용 가능합니다. chrome : // gpu의 출력을 확인하십시오
Sebastian

layers.acceleration.force-enabledFirefox에서 비디오 디코딩에 관한 것이 아닙니다. 잘 알려진 사실입니다. requestAnimationFrame을 사용하여 루프를 완료하면 다른 레벨로 다시 칠할 수 있습니다. 전혀 비디오가 아닙니다.
NVRM

@NVRM-Linux에서 이러한 GPU 문제에 대한 FF 및 Chromium 버그에 대한 링크를 제공 할 수 있습니까? 또한 "하드웨어 가속"에 의해 나는뿐만 아니라 GPU 가속을 언급하고 있습니다, 또한 어떤 자바 스크립트가 실행되지 않는 동안 회전 계속 또는 예를 들어 로딩 스피너처럼, 합성 및 애니메이션 멀티 스레드 동안 JS가 실행되고있다. 이것은 캔버스에서는 불가능하며 순수한 "자바 스크립트"와 관련하여 실제로 모든 플랫폼에서 Chrome과 FF에서 확실히 사용할 수있는 일종의 하드웨어 가속 (멀티 스레딩)입니다. 감사!
Sebastian

1
현재 상황을 요약하면 다음과 같습니다. Chrome 및 Chromium에서 작동합니다. Linux에서. 2019 년에 모든 인스턴스에서 특별한 구성없이 테스트했습니다. Firefox / Mozilla는 Linux 용으로 작업하고 있지만 프로세스 외부 렌더링은 FF의 새로운 기능이 아니며, SVG보다 CSS, CSS 등에서 항상 더 잘 작동합니다.
Sebastian

13

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


1
실제로 일반 HTML을 사용하는 것이 CSS 이미지와 함께 가장 성능이 좋습니다.
Raynos

16
@Raynos : 출처?
야누스 Troelsen

3

인터넷 검색 중 http://teropa.info/blog/2016/12/12/graphics-in-angular-2.html 에서 SVG캔버스 의 사용 및 압축에 대한 좋은 설명을 찾았습니다.

그것이 도움이되기를 바랍니다.

  • HTML과 마찬가지로 SVG는 유지 렌더링을 사용 합니다. 화면에 사각형을 그리려면 DOM에서 요소를 선언적으로 사용합니다. 그런 다음 브라우저는 사각형을 그리지 만 사각형 을 나타내는 메모리 내 SVGRectElement 객체 도 생성합니다 . 이 객체는 우리가 조작하기 위해 고수하고있는 것입니다. 시간이 지남에 따라 다른 위치와 크기를 할당 할 수 있습니다. 또한 이벤트 리스너를 연결하여 대화식으로 만들 수 있습니다.
  • Canvas는 즉각적인 렌더링을 사용 합니다 . 사각형그릴 때 브라우저는 즉시 화면에 사각형을 렌더링하지만 사각형을 나타내는 "사각형 개체"는 절대 없습니다. 캔버스 버퍼에는 많은 픽셀이 있습니다. 사각형을 움직일 수 없습니다. 다른 직사각형 만 그릴 수 있습니다. 사각형의 클릭 또는 다른 이벤트에는 응답 할 수 없습니다. 캔버스 전체의 이벤트에만 응답 할 수 있습니다 .

따라서 canvas는 SVG보다 낮은 수준의 제한적인 API입니다. 그러나 캔버스와 같은 양의 리소스로 더 많은 것을 할 수 있다는 단점이 있습니다. 브라우저는 우리가 그린 모든 것의 메모리 내 객체 그래프를 생성하고 유지할 필요가 없기 때문에 동일한 시각적 장면을 그리는 데 필요한 메모리와 계산 리소스가 더 적습니다. 그릴 매우 크고 복잡한 시각화가있는 경우 Canvas가 티켓 일 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.