HTML5 Canvas ve SVG'ye karşı div


476

Anında öğeler oluşturmak ve onları hareket ettirmek için en iyi yaklaşım nedir? Örneğin, bir dikdörtgen, daire ve çokgen oluşturmak ve sonra bu nesneleri seçmek ve hareket ettirmek istediğimi varsayalım.

HTML5'in bunu mümkün kılabilecek üç öğe sağladığını anlıyorum: svg , canvas ve div . Ne yapmak istediğim için, bu unsurlardan hangisi en iyi performansı sağlayacak?

Bu yaklaşımları karşılaştırmak için, her birinde üstbilgi, altbilgi, widget ve metin içeriği bulunan görsel olarak özdeş üç web sayfası oluşturmayı düşünüyordum. İlk sayfadaki widget tamamen canvasöğe ile, ikincisi tamamen svgöğe ile ve üçüncüsü düz divöğe, HTML ve CSS ile oluşturulur.



1
Bu teknolojide yeni olanlarınız için bu video hem SVG'yi hem de Canvas'ı ve bunun html5'e nasıl entegre edildiğiyle ilgili diğer ayrıntıları kapsamaktadır.
Paulo Bueno

12
Kısa cevap: Tuval MS Paint'e SVG MS Powerpoint'e olduğu gibi. Tuval raster, SVG vektörel.
14'te

2
Sevgili okuyucu: Buradaki tüm karşılaştırmaları ve ifadeleri bir tuz tanesi ile alın ve mesajların ve yorumların tarihine bakın. Zaman değişti ve değişecek. Göreceli performans ve sahip olduğunuz seçenekler bile değişecektir. Örneğin, kesinlikle bir alternatif olan WebGL olmadığında yazılan çoğu cevap, birkaç yıl içinde de modası geçecek, ancak bugün itibariyle çok alakalı olabilir.
Sebastian

@Sebastian bugün hangisini önerirsiniz? bir taban boyutu (ör. 1280x800) verilirse ve öğeleri manuel olarak kodda ölçeklemek veya yüzdeleri her zaman kullanmak istiyorsanız, SVG'nin DIV'leri kullanmanın bir avantajı var mı?
Crashalot

Yanıtlar:


563

Kısa cevap:

Seçim ve hareket ettirme zaten yerleşik olduğundan SVG sizin için daha kolay olurdu . SVG nesneleri DOM nesneleridir, bu nedenle "tıklama" işleyicileri vb.

DIV'leri tamam ama aksak ve sahip korkunç sayıda performans yükleme.

Tuval en iyi performansa sahiptir, ancak yönetilen durumun (nesne seçimi vb.) Tüm kavramlarını kendiniz uygulamanız veya bir kitaplık kullanmanız gerekir.


Uzun cevap:

HTML5 Canvas, sadece bit eşlemi için bir çizim yüzeyidir. Çizmek için ayarladınız (bir renk ve çizgi kalınlığı ile söyleyin), o şeyi çizin ve sonra Tuval'in o şey hakkında hiçbir bilgisi yok: Nerede olduğunu veya ne çizdiğinizi bilmiyor, sadece piksel. Dikdörtgenler çizmek ve hareket ettirmek veya seçilebilir olmak istiyorsanız, bunları çizdiğinizi hatırlamak için kod da dahil olmak üzere , hepsini sıfırdan kodlamanız gerekir.

Öte yandan SVG, oluşturduğu her nesneye referanslar sağlamalıdır. Oluşturduğunuz her SVG / VML öğesi, DOM'daki gerçek bir öğedir. Varsayılan olarak bu, oluşturduğunuz öğeleri daha iyi takip etmenizi sağlar ve fare olayları gibi şeylerle uğraşmayı varsayılan olarak kolaylaştırır, ancak çok sayıda nesne olduğunda önemli ölçüde yavaşlar

Bu SVG DOM referansları, çizdiğiniz şeylerle başa çıkmanın bazı ayaklarının sizin için yapıldığı anlamına gelir. Ve SVG gerçekten büyük nesneleri oluştururken daha hızlıdır , ancak birçok nesneyi oluştururken daha yavaştır .

Tuval'de bir oyun muhtemelen daha hızlı olurdu. Büyük bir harita programı SVG'de muhtemelen daha hızlı olacaktır. Canvas'ı kullanmak istiyorsanız, hareketli nesneleri burada çalışmaya ve çalıştırmaya yönelik bazı eğitimlerim var .

Tuval, daha hızlı şeyler ve ağır bitmap manipülasyonu (animasyon gibi) için daha iyi olurdu, ancak çok fazla etkileşim istiyorsanız daha fazla kod alacaktır.

Tuval yapımı çizime karşı HTML DIV yapımı çizimde bir dizi sayı çalıştırdım. Her birinin faydaları hakkında büyük bir yazı gönderebilirim, ancak testlerimin ilgili sonuçlarından bazılarını özel uygulamanız için değerlendireceğim:

Canvas ve HTML DIV test sayfaları yaptım, her ikisinin de hareketli "düğümleri" vardı. Tuval düğümleri, Javascript'te oluşturduğum ve izlediğim nesnelerdi. HTML düğümleri hareketli Div'lerdir.

İki testimin her birine 100.000 düğüm ekledim. Oldukça farklı performans gösterdiler:

HTML test sekmesinin yüklenmesi sonsuza dek sürdü (5 dakikadan biraz az bir sürede zamanlanmış, krom sayfayı ilk kez öldürmek istedi). Chrome'un görev yöneticisi sekmenin 168 MB yer kapladığını söylüyor. Baktığım zaman% 12-13 CPU zamanı, bakmadığım zaman% 0 alıyor.

Canvas sekmesi bir saniyede yüklenir ve 30 MB alır. Ayrıca, bakıp bakmadığına bakılmaksızın her zaman CPU süresinin% 13'ünü alır. (2013 edit: Çoğunlukla bunu düzelttiler)

HTML sayfasındaki sürükleme, tasarımın beklediği daha pürüzsüzdür, çünkü mevcut kurulum, TEST testindeki her 30 milisaniyede bir HER ŞEYİ yeniden çizmektir. Bunun için Canvas için yapılabilecek birçok optimizasyon var. (tuval geçersiz kılma en kolay, aynı zamanda kırpma bölgeleri, seçici yeniden çizim vb.)

Hiç kuşkusuz, Canvas'ın bu basit testteki div'ler olarak nesne manipülasyonunda daha hızlı olmasını ve elbette yükleme süresinde çok daha hızlı olmasını sağlayabilirsiniz. Tuvalde çizim / yükleme daha hızlıdır ve optimizasyonlar için çok daha fazla alana sahiptir (yani, ekran dışı olan şeyleri hariç tutmak çok kolaydır).

Sonuç:

  • SVG, az sayıda öğeye sahip uygulamalar ve uygulamalar için muhtemelen daha iyidir (1000'den az mı? Gerçekten bağlıdır)
  • Tuval binlerce nesne ve dikkatli manipülasyon için daha iyidir, ancak yerden kaldırmak için çok daha fazla kod (veya kütüphane) gerekir.
  • HTML Div'leri tıknazdır ve ölçeklenmez, bir daire yapmak sadece yuvarlatılmış köşelerle mümkündür, karmaşık şekiller yapmak mümkündür, ancak yüzlerce küçük piksel çapında küçük div içerir. Delilik başlar.

4
Kek kütüphane bir tuval üzerinde nesnelerle hareketli nesneleri ve animasyonlar yaparak başka bir örnektir
SiggyF

Yanlış: P div tarayıcı hw hızlandırılmış CSS motoru kullanıyorsa ölçeklendirilebilir, css sanat farklıdır ve Canvas ve SVG'nin yanı sıra burada doğru seçimdir, CSS sanat / div sanatı sadece u küçük bir katmanı aşmaya gerek duymadığında: P
ShrekOverflow

Eğer sadece bir PNG oluşturmak ve olarak kullanabilirsiniz, sen çevreler / özel şekiller yapmak istiyorsanız, DIV'leri ilgili ve resim / sprite nedeniyle gidişatını değiştirmek için gitmiyor background-image... SVG / Tuval benzer şeyler yapabilirsiniz olsa
luiges90

4
Etkileşimli bir harita oyunu oluşturuyorsanız ne olacak? : p
Anthony

Bu, (iç içe) DIV'ler ve CSS 3D dönüşümleri kullanılarak oluşturuldu, bu yüzden DIV'lerin hiç yavaş olmadığını söyleyebilirim: youtube.com/watch?v=fzBC20B5dsk
Erik Kaplun

39

Buna eklemek için bir diyagram uygulaması yapıyordum ve başlangıçta tuvalle başladım. Diyagram birçok düğümden oluşur ve oldukça büyüyebilirler. Kullanıcı, şemadaki öğeleri sürükleyebilir.

Bulduğum şey, Mac bilgisayarımda, çok büyük görüntüler için SVG'nin üstün olduğuydı. MacBook Pro 2013 13 "Retina'm var ve aşağıda oldukça iyi çalışıyor. Görüntü 6000x6000 piksel ve 1000 nesneye sahip. Tuvaldeki benzer bir yapı, kullanıcı nesneleri sürüklerken benim için canlandırmak imkansızdı. diyagram.

Modern ekranlarda farklı çözünürlükleri de hesaba katmanız gerekiyor ve burada SVG size tüm bunları ücretsiz olarak veriyor.

Keman: http://jsfiddle.net/knutsi/PUcr8/16/

Tam ekran: 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
Tuval'in bizim için çalışmasını umutsuzca denedikten sonra SVG'ye de yerleştik. Çok büyük bir diyagramımız var ve SVG bugüne kadar en verimli olanıydı, ayrıca retina ekranlarındaki otomatik ölçeklendirme büyük bir bonus.
Fijjit

knut ve @Fijjit SVG yerine DIV kullanmayı düşündünüz mü? taban boyutu verilirse (ör. 1280x800) DIV'leri manuel olarak ölçekleyemezdiniz, böylece SVG kadar keskin görünürler mi? yardımın için teşekkürler!
Crashalot

24

SVG ve Canvas arasındaki farkları bilmek, doğru olanı seçmede yardımcı olacaktır.

Tuval

SVG

  • Çözünürlük bağımsız
  • Olay işleyicileri için destek
  • Geniş işleme alanlarına sahip uygulamalar için en uygun yöntem (Google Haritalar)
  • Karmaşıksa yavaş oluşturma (DOM'u çok kullanan her şey yavaş olacaktır)
  • Oyun uygulaması için uygun değil

8
insanlar neden Canvas'ın çözünürlüğe bağlı olduğunu söylüyor? Bitmap oluşturulduktan sonra güzel ölçeklenmediğini anlıyorum. ancak çözünürlük boyutu değişikliklerini yeniden çizebilirsiniz, dolayısıyla bu çözünürlük nasıl bağımsız değildir?
Alex Bollbach

@AlexBollbach - Tuval çözünürlüğe bağlıdır, çünkü iyi sonuçlar elde etmek için çözünürlüğü dikkate almanız gerekir. SVG ile çözünürlüğü umursamazsınız. 2400DPI yazıcıda ve Canvas tabanlı bir renderde jaggy olmayan çizgiler elde etmekte iyi şanslar SVG ile sorun değil.
Sebastian

18

Simon Sarris'in sonuçlarına katılıyorum:

Protovis'teki (SVG) bazı görselleştirmeyi> 2000 noktayı görüntüleyen Processingjs (Canvas) ile karşılaştırdım ve işlemejs protokollerden çok daha hızlı.

Olayları SVG ile yönetmek elbette çok daha kolaydır çünkü bunları nesnelere ekleyebilirsiniz. Canvas'ta manuel olarak yapmalısınız (fare konumunu kontrol edin, vb.) Ancak basit etkileşim için zor olmamalıdır.

Ayrıca dojo araç setinin dojo.gfx kütüphanesi de vardır . Bir soyutlama katmanı sağlar ve oluşturucuyu (SVG, Canvas, Silverlight) belirleyebilirsiniz. Ek soyutlama katmanının ne kadar ek yük getirdiğini bilmememe rağmen bu da uygun bir seçim olabilir, ancak etkileşimleri ve animasyonları kodlamayı kolaylaştırır ve oluşturucu agnostiktir.

İşte bazı ilginç kriterler:


17

Div seçeneği ile ilgili sadece 2 sent.

Famous / Infamous ve SamsaraJS (ve muhtemelen diğerleri), konumlandırma ve 2D / 3D dönüşümleri için matris2d / matrix3d ​​ile birlikte kesinlikle konumlandırılmış iç içe olmayan div (önemsiz HTML / CSS içeriği ile) kullanır ve ılımlı mobil donanımda istikrarlı bir 60FPS elde eder , bu yüzden div'ların yavaş bir seçenek olduğunu savunuyorum.

Youtube'da ve başka yerlerde, 60FPS'de (belirli efektler için WebGL ile karıştırılmış, ancak belirli efektler için karıştırılmamış) her şeyi Element'i İnceleyebileceğiniz bir DOM öğesi olan yüksek performanslı 2D / 3D şeylerden oluşan çok sayıda ekran kaydı vardır. oluşturma işleminin ana bölümü).


14

Yukarıdaki cevapların çoğunda hala bazı gerçekler olsa da, bir güncellemeyi hak ettiklerini düşünüyorum:

Yıllar içinde SVG'nin performansı çok gelişti ve artık SVG için JavaScript performansına bağlı olmayan donanım hızlandırmalı CSS geçişleri ve animasyonları var . Tabii ki JavaScript performansı da ve bununla birlikte Canvas'ın performansını geliştirdi, ancak SVG'nin geliştirdiği kadar değil. Ayrıca blokta bugün hemen hemen tüm tarayıcılarda bulunan ve bu WebGL olan bir "yeni çocuk" var . Simon'un yukarıda kullandığı kelimeleri kullanmak için: Canvas ve SVG'nin her ikisini de yener . Bu, onun gitmesi gereken teknoloji olması anlamına gelmez, çünkü çalışmak için bir canavar ve çok spesifik kullanım durumlarında sadece daha hızlıdır.

Bugün çoğu kullanım durumu için IMHO, SVG en iyi performans / kullanılabilirlik oranını vermektedir. Görselleştirmelerin gerçekten karmaşık (öğe sayısına göre) ve aynı zamanda (öğe başına) gerçekten basit olması gerekir, böylece Canvas ve daha da fazlası WebGL gerçekten parlar.

Gelen benzer bir soruya bu cevabı ben düşünüyorum neden, daha fazla ayrıntı sağlayan am kombinasyonu her üç teknolojilerin bazen sahip olduğumuz en iyi seçenektir.


Unix kullanıcıları,
2019'un

@NVRM - Bu, video kod çözme ile ilgili değil, CSS ve SVG'nin donanım hızlandırmasıyla ilgilidir. AFAIK eski yıllardır mevcut: krom çıktısını kontrol edin: // gpu
Sebastian

layers.acceleration.force-enabledFirefox'ta video kod çözme ile ilgili değildir. Bu iyi bilinen bir gerçektir. RequestAnimationFrame kullanılarak döngüler yapıldığında, daha fazla yeniden boyamaya izin veren başka bir düzeydir. Hiç video hakkında değil.
NVRM

@NVRM - Linux'ta bu GPU sorunları için FF ve Chromium hatalarına bağlantılar sağlayabilir misiniz? Ayrıca "donanım hızlandırmalı" tarafından ben sadece GPU hızlandırma atıfta bulundu unutmayın, aynı zamanda hiçbir JavaScript çalışırken dönmeye devam ediyor veya örneğin yükleme iplikçiler gibi, kompozisyon ve animasyonlar-çoklu iş parçacıklı ise JS yürütülmektedir. Bu, Canvas ile imkansızdır ve saf "JavaScript" ile karşılaştırıldığında, tüm platformlarda kesinlikle Chrome ve FF'de bulunan bir çeşit donanım hızlandırmasıdır (çoklu iş parçacığı). Teşekkürler!
Sebastian

1
Mevcut durumu özetlemek gerekirse: Chrome ve Chromium'da benim için çalışıyor. Linux üzerinde. Tüm durumlarda özel yapılandırma olmadan test ettim. Firefox / Mozilla Linux için üzerinde çalışıyor , ancak işlem dışı oluşturma FF için de yeni bir şey değil ve her zaman SVG, CSS vb. İle Canvas için olduğundan daha iyi çalışacak.
Sebastian

13

Amacınız için, SVG kullanmanızı öneririz, çünkü sürükle bırak dahil fare işleme gibi DOM olayları alırsınız, kendi yeniden çiziminizi uygulamak zorunda değilsiniz ve durumunu takip etmek zorunda değilsiniz. nesneleriniz. Bitmap görüntü manipülasyonu yapmanız gerektiğinde Tuval'i kullanın ve HTML'de oluşturulan şeyleri değiştirmek istediğinizde normal bir div kullanın. Performansa gelince, modern tarayıcıların artık üçünü de hızlandırdığını göreceksiniz, ancak o tuval şimdiye kadar en çok dikkat çekti. Öte yandan, javascript'inizi ne kadar iyi yazdığınızı tuval ile en iyi performansı elde etmek için önemlidir, bu yüzden SVG'yi kullanmanızı tavsiye ederim.


1
Aslında düz HTML kullanmak, CSS görüntüleri ile birlikte en yüksek performansa sahiptir.
Raynos

16
@Raynos: Kaynak?
Janus Troelsen

3

Googling ederken ben kullanımı ve sıkıştırılması konusunda iyi bir açıklama bulmak SVG ve Canvas de http://teropa.info/blog/2016/12/12/graphics-in-angular-2.html

Umarım yardımcı olur:

  • HTML gibi SVG de tutulan oluşturma kullanır : Ekranda bir dikdörtgen çizmek istediğimizde, DOM'umuzda bildirilen bir öğeyi kullanırız. Tarayıcı daha sonra bir dikdörtgen çizer, ancak dikdörtgeni temsil eden bir bellek içi SVGRectElement nesnesi de oluşturur . Bu nesne, manipüle etmemiz için etrafta dolaşan bir şeydir - korunur. Zaman içinde farklı konumlar ve boyutlar atayabiliriz. Etkinlik dinleyicilerini etkileşimli hale getirmek için de ekleyebiliriz.
  • Kanvas anında oluşturma kullanır : Bir dikdörtgen çizdiğimizde , tarayıcı hemen ekranda bir dikdörtgen oluşturur, ancak onu temsil eden hiçbir "dikdörtgen nesnesi" olmayacaktır. Tuval arabelleğinde sadece bir grup piksel var. Dikdörtgeni hareket ettiremiyoruz. Sadece başka bir dikdörtgen çizebiliriz. Dikdörtgendeki tıklamalara veya diğer etkinliklere yanıt veremiyoruz. Yalnızca tüm tuvaldeki olaylara yanıt verebiliriz .

Tuval, SVG'den daha düşük seviyeli, kısıtlayıcı bir API'dir. Ama bunun tersi var, yani tuvalle aynı miktarda kaynakla daha fazlasını yapabilirsiniz. Tarayıcı, çizdiğimiz tüm şeylerin bellek içi nesne grafiğini oluşturmak ve korumak zorunda olmadığından, aynı görsel sahneyi çizmek için daha az bellek ve hesaplama kaynağına ihtiyaç duyar. Çizmek için çok büyük ve karmaşık bir görselleştirmeniz varsa, Canvas sizin biletiniz olabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.