HTML5 Canvas vs. SVG vs. div

Jakie jest najlepsze podejście do tworzenia elementów w locie i możliwości ich przemieszczania? Załóżmy na przykład, że chcę utworzyć prostokąt, okrąg i wielokąt, a następnie zaznaczyć te obiekty i je przesunąć.

Rozumiem, że HTML5 zawiera trzy elementy, które mogą to umożliwić: svg, canvas i div . Który z tych elementów zapewni najlepszą wydajność?

Aby porównać te podejścia, I myślałem o stworzeniu trzech identycznych wizualnie stron internetowych, z których każda ma nagłówek, stopkę, widget i zawartość tekstową. Widżet na pierwszej stronie zostanie utworzony w całości z elementem canvas, drugi w całości z elementem svg, a trzeci z zwykłym elementem div, HTML i CSS.

Author: Manfred Radlwimmer, 0000-00-00

8 answers

Krótka odpowiedź:

SVG byłby dla Ciebie łatwiejszy , ponieważ zaznaczanie i przesuwanie go jest już wbudowane. Obiekty SVG są obiektami DOM, więc mają procedury obsługi "kliknięć", itd.

Div są w porządku, ale niezgrabne i mają straszne wydajność ładowania w dużych ilościach.

Canvas ma najlepszą wydajność, ale musisz zaimplementować wszystkie koncepcje stanu zarządzanego (wybór obiektów itp.) samodzielnie lub użyć biblioteki.


The long odpowiedź:

HTML5 Canvas jest po prostu powierzchnią rysunkową dla mapy bitowej. Ustawiasz rysowanie (powiedzmy z kolorem i grubością linii), rysujesz to coś, a następnie płótno nie ma wiedzy o tym czymś: nie wie, gdzie jest lub co właśnie narysowałeś, to tylko piksele. Jeśli chcesz narysować prostokąty i sprawić, by się poruszały lub były wybierane, musisz zakodować to wszystko od zera, w tym kod, aby pamiętać, że je narysowałeś.

SVG na drugiej hand musi utrzymywać odniesienia do każdego obiektu, który renderuje. Każdy utworzony element SVG / VML jest rzeczywistym elementem w DOM. Domyślnie pozwala to na znacznie lepsze śledzenie tworzonych elementów i domyślnie ułatwia radzenie sobie z zdarzeniami myszy, ale znacznie spowalnia, gdy istnieje duża liczba obiektów

Te odniesienia do SVG DOM oznaczają, że niektóre prace związane z rysowaniem rzeczy są wykonywane za Ciebie. A SVG jest szybszy podczas renderowania naprawdę duże obiekty, ale wolniejsze podczas renderowaniaWielu obiektów.

Gra prawdopodobnie byłaby szybsza w Canvasie. Wielki program do map byłby prawdopodobnie szybszy w SVG. Jeśli chcesz użyć Canvasa, mam kilka samouczków na temat uruchamiania ruchomych obiektów tutaj .

Płótno byłoby lepsze dla szybszych rzeczy i ciężkich manipulacji bitmapami( jak animacja), ale będzie wymagało więcej kodu, jeśli chcesz dużo interaktywności.

I ' ve run a bunch of numbers na rysunku wykonanym przez HTML div kontra rysunku wykonanym przez Canvas. Mógłbym napisać ogromny post o korzyściach każdego z nich, ale podam niektóre z istotnych wyników moich testów do rozważenia dla konkretnego zastosowania: {]}

Zrobiłem strony testowe Canvas i HTML DIV, obie miały ruchome " węzły."Węzły Canvas były obiektami, które utworzyłem i śledziłem w Javascript. Węzły HTML były ruchomymi divami.

Dodałem 100,000 węzłów do każdego z moich dwóch testów. Wystąpili zupełnie inaczej:

Test HTML tab zajęło wieczność, aby załadować (czas nieco poniżej 5 minut, chrome poprosił o zabicie strony za pierwszym razem). Menedżer zadań Chrome mówi, że tab zajmuje 168mb. Zajmuje to 12-13% czasu procesora, gdy patrzę na niego, 0%, gdy nie patrzę.

Karta Canvas załadowana w ciągu jednej sekundy i zajmuje 30MB. Zajmuje to również 13% czasu procesora przez cały czas, niezależnie od tego, czy ktoś na niego patrzy, czy nie. (edycja 2013: w większości to naprawili)

Przeciąganie strony HTML jest gładsza, czego oczekuje projekt, ponieważ obecna konfiguracja polega na przerysowaniu wszystkiego co 30 milisekund w teście Canvas. Istnieje wiele optymalizacji dla Canvas do tego. (unieważnienie płótna jest najłatwiejsze, również regiony przycinania, selektywne przerysowywanie itp.. tylko zależy jak bardzo masz ochotę na wdrożenie)

Nie ma wątpliwości, że Canvas może być szybszy w manipulacji obiektami jako divs w tym prostym teście, i oczywiście znacznie szybciej w obciążeniu czas. Rysowanie/ładowanie jest szybsze w kanwie i ma znacznie więcej miejsca na optymalizacje (tj. wykluczenie rzeczy, które są poza ekranem, jest bardzo łatwe).

Wniosek:

  • SVG jest chyba lepszy dla aplikacji i aplikacji z kilkoma elementami (mniej niż 1000? Zależy naprawdę)
  • Canvas jest lepszy dla tysięcy obiektów i starannej manipulacji, ale dużo więcej kodu (lub biblioteki) jest potrzebne, aby go uruchomić.
  • divy HTML są niezgrabne i nie skalują się, dzięki czemu okrąg jest możliwy tylko z zaokrąglonymi rogami, tworzenie złożonych kształtów jest możliwe, ale obejmuje setki małych pikseli divs szerokości. Następuje szaleństwo.
 491
Author: Simon Sarris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-15 16:14:56

Aby dodać do tego, robiłem aplikację diagramową i początkowo zaczynałem od canvas. Diagram składa się z wielu węzłów i mogą stać się dość duże. Użytkownik może przeciągać elementy na diagramie.

Znalazłem to, że na moim Macu, dla bardzo dużych obrazów, SVG jest lepszy. Mam MacBooka Pro 2013 13" Retina i całkiem dobrze działa na skrzypcach poniżej. Obraz ma wymiary 6000x6000 pikseli i zawiera 1000 obiektów. Podobna konstrukcja w canvas była niemożliwa do animowania dla mnie, gdy użytkownik przeciągał obiekty na diagramie.

Na nowoczesnych wyświetlaczach musisz również uwzględnić różne rozdzielczości, a tutaj SVG daje Ci to wszystko za darmo.

Http://jsfiddle.net/knutsi/PUcr8/16/

Fullscreen: 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 100 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);
 33
Author: knut,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-06 14:31:43

Znajomość różnic między SVG i Canvas byłaby pomocna przy wyborze właściwego.

Canvas

  • zależna od Rozdzielczości
  • Brak obsługi zdarzeń
  • słabe możliwości renderowania tekstu
  • wynikowy obraz można zapisać jako .png lub .jpg
  • dobrze nadaje się do gier intensywnych graficznie

SVG

  • Rozdzielczość niezależna
  • obsługa programów obsługi zdarzeń
  • najlepiej nadaje się do zastosowań o dużych obszary renderowania (Mapy Google)
  • powolne renderowanie, jeśli złożone (wszystko, co dużo używa DOM, będzie slow)
  • nie nadaje się do stosowania w grach
 19
Author: Leo The Four,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-28 14:14:06

Zgadzam się z wnioskami Simona Sarrisa:

Porównałem niektóre wizualizacje w Protovis (SVG) do Processingjs (Canvas), które wyświetlają > 2000 punktów i processingjs jest znacznie szybszy niż protovis.

Obsługa zdarzeń za pomocą SVG jest oczywiście znacznie łatwiejsza, ponieważ można je dołączać do obiektów. W Canvas musisz to zrobić ręcznie (sprawdź pozycję myszy, itp), ale dla prostej interakcji nie powinno to być trudne.

Istnieje również dojo.gfx biblioteka zestaw narzędzi dojo. Zapewnia warstwę abstrakcji i można określić renderer (SVG, Canvas, Silverlight). To może być również realny wybór, chociaż Nie wiem, ile narzutu dodaje dodatkowa warstwa abstrakcji, ale ułatwia to kodowanie interakcji i animacji i jest renderer-agnostyczny.

Oto kilka ciekawych benchmarki:

 18
Author: Ümit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-02 07:03:33

Tylko moje 2 centy dotyczące opcji divs.

Famous / Infamous i SamsaraJS (i być może inni) używają absolutnie pozycjonowanych nie zagnieżdżonych divów( z nietrywialną zawartością HTML / CSS), w połączeniu z matrix2d/matrix3d do pozycjonowania i transformacji 2D/3D i osiągania stabilnych 60 klatek na umiarkowanym sprzęcie mobilnym, więc argumentowałbym przeciwko div-owi jako powolnej opcji.

Na Youtube i w innych miejscach jest mnóstwo nagrań ekranowych o wysokiej wydajności 2D/3D działających w przeglądarka ze wszystkim jest elementem DOM, który można sprawdzić Element na, 60FPS( mieszane z WebGL dla niektórych efektów, ale nie dla głównej części renderowania).

 15
Author: Erik Allik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-10 10:02:33

Do Twoich celów, polecam używanie SVG, ponieważ dostajesz zdarzenia DOM, takie jak obsługa myszy, w tym przeciąganie i upuszczanie, włączone, nie musisz implementować własnego przerysowania, ani nie musisz śledzić stanu swoich obiektów. Użyj Canvas, gdy musisz manipulować obrazem bitmapowym i użyj zwykłego div, gdy chcesz manipulować rzeczami utworzonymi w HTML. Co do wydajności, przekonasz się, że nowoczesne przeglądarki przyspieszają teraz wszystkie trzy, ale canvas otrzymał najwięcej uwaga na razie. Z drugiej strony, to, jak dobrze piszesz swój javascript, ma kluczowe znaczenie dla uzyskania największej wydajności z płótnem, więc nadal polecam używanie SVG.

 13
Author: Gaurav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-04 11:55:35

Mimo że w większości powyższych odpowiedzi jest jeszcze trochę prawdy, myślę, że zasługują na aktualizację:

Przez lata wydajność SVG znacznie się poprawiła, a teraz istnieją przyspieszane sprzętowo przejścia CSS i animacje dla SVG , które w ogóle nie zależą od wydajności JavaScript. Oczywiście poprawiła się również wydajność JavaScript, a wraz z nią wydajność Canvas, ale nie tak bardzo jak poprawił się SVG. W bloku jest też "nowe dziecko", które jest dostępne w prawie wszystkie przeglądarki dzisiaj i to jest WebGL . Aby użyć tych samych słów, które Simon użył powyżej: It bije zarówno Canvas, jak i SVG ręce w dół. Nie oznacza to jednak, że powinna to być Technologia go-to, ponieważ jest to bestia do pracy i jest szybsza tylko w bardzo konkretnych przypadkach użycia.

IMHO w większości przypadków, SVG daje najlepszy stosunek wydajności do użyteczności. Wizualizacje muszą być bardzo złożone (pod względem liczby elementów), a jednocześnie bardzo proste (na element), aby płótno i jeszcze bardziej WebGL naprawdę świeciły.

W ta odpowiedź na podobne pytanie podaję więcej szczegółów, dlaczego uważam, żekombinacja wszystkich trzech technologii czasami jest najlepszą opcją, jaką masz.

 6
Author: Sebastian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-04 06:26:58

Podczas googlowania znajduję dobre wyjaśnienie dotyczące użycia i kompresji SVG i Canvas w http://teropa.info/blog/2016/12/12/graphics-in-angular-2.html

Hope it helps:

  • SVG, podobnie jak HTML, używa zatrzymanego renderowania : gdy chcemy narysować prostokąt na ekranie, używamy elementu w naszym DOM. Przeglądarka następnie narysuje prostokąt, ale również utworzy in-memory SVGRectElement obiekt, który reprezentuje prostokąt. To obiekt jest czymś, co pozwala nam manipulować-jest zatrzymane. Z czasem możemy przypisać mu różne pozycje i rozmiary. Możemy również dołączyć słuchaczy zdarzeń, aby uczynić je interaktywnymi.
  • Canvas używa natychmiastowego renderowania : gdy narysujemy prostokąt, przeglądarka natychmiast renderuje prostokąt na ekranie, ale jest nigdy nie będzie to żaden "obiekt prostokątny", który go reprezentuje. Jest just a bunch pikseli w buforze obszaru roboczego. Nie możemy się ruszyć. prostokąt. Możemy narysować tylko inny prostokąt. Nie możemy odpowiedzieć na kliknięć lub innych zdarzeń na prostokącie. Możemy reagować tylko na zdarzenia na całe płótno .

Więc canvas jest bardziej niskopoziomowym, restrykcyjnym API niż SVG. Ale jest flipside do tego, czyli z canvas można zrobić więcej z tyle samo zasobów. Ponieważ przeglądarka nie musi tworzyć i utrzymanie obiektu w pamięci Wykres wszystkich rzeczy, które mamy rysowane, potrzebuje mniej pamięci i zasobów obliczeniowych, aby narysować to samo scena wizualna. Jeśli masz bardzo dużą i złożoną wizualizację do narysuj, płótno może być twoim biletem.

 1
Author: Alireza Fattahi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-03 07:37:46