Güncelleme: Bu cevap oldukça popüler görünüyor, bu yüzden biraz temizlemek, yeni bilgiler eklemek ve yeterince net olmadığını düşündüğüm birkaç şeyi açıklığa kavuşturmak için biraz zaman harcadım. Başka bir şeyin açıklığa veya güncellemeye ihtiyacı olduğunu düşünüyorsanız lütfen yorum yapın.
Kaygılarınızın çoğu gerçekten bir düşünce ve kişisel tercih meselesidir, ancak elimden geldiğince nesnel cevap vermeye çalışacağım:
Yerel ve Derlenmiş
Vanilya JavaScriptine JavaScript yaz, CSS'ye CSS yaz, HTML'ye HTML yaz.
Eskiden bir yazma gerekip gerekmediğini sıcak tartışmalar vardı yerli elle Kurul veya derleyici sizin için Meclis kodu oluşturmak yapmak C gibi daha yüksek bir seviyede dil kullanmak. Bundan önce bile insanlar montajcılara güvenmeyi reddetti ve elle yerel makine kodunu yazmayı tercih etti ( ve şaka yapmıyorum ).
Bu arada, bugün HTML yazma bir sürü insan vardır Haml veya Jade içinde, CSS Sass veya Daha Az ve JavaScript CoffeeScript veya daktilo yazısı . Orada. İşe yarıyor. Bazı insanlar bunu tercih eder, bazıları istemez.
Mesele şu ki , vanilya JavaScript'inde JavaScript, CSS'de CSS ve HTML'de HTML yazmamakta temel olarak yanlış bir şey olmadığıdır . Bu gerçekten tercih meselesi.
Dahili ve Harici DSL'ler
Gölge DOM React kullanarak stil kapsülleme, bunun yerine, JavaScript'te CSS yazmayı gerektirir. Güzel değil.
Güzel ya da değil, kesinlikle etkileyici. JavaScript, CSS'den çok daha güçlü (çok CSS işlemcileri de dahil olmak üzere) çok güçlü bir dildir. Bu tür şeyler için iç veya dış DSL'leri tercih edip etmemenize bağlı olarak değişir. Yine, bir tercih meselesi.
(Not: Orijinal soruya atıfta bulunulan React'teki satır içi stillerden bahsediyordum .)
DSL Türleri - açıklama
Güncelleme: Bir süre sonra cevabımı okuduktan sonra burada ne demek istediğimi açıklamam gerektiğini düşünüyorum. DSL, etki alanına özgü bir dildir ve dahili olabilir (JavaScript gibi ana dilin sözdizimini kullanarak - örneğin, JSX olmadan Tepki gibi veya yukarıda belirtilen React'deki satır içi stilleri gibi) veya dışta olabilir (farklı bir sözdizimi kullanarak). ana bilgisayardan daha çok - bu örnekte olduğu gibi, JavaScript içinde CSS'yi (harici bir DSL) yerleştirmek gibi olacaktır.
Kafa karıştırıcı olabilir, çünkü bazı literatürler bu tür DSL'leri tanımlamak için "dahili" ve "harici" terimlerinden farklı terimler kullanır. Bazen "dahili" yerine "gömülü" kullanılır, ancak "gömülü" kelimesi farklı anlamlara gelebilir - örneğin, Lua , gömülü (dahili) DSL ile ilgisi olmadığı "Lua: genişletilebilir bir gömülü dil" olarak tanımlanır . bunun tam tersi bir anlam ifade ediyor - harici bir DSL) fakat aynı anlamda, yani SQLite'nin gömülü bir veritabanı olduğu gibi gömülü olduğu anlamına geliyor. "E" nin üçüncü anlamda "gömülü" ifadesini gösterdiği eLua bile vardır - gömülü sistemler içindir! Bu yüzden "gömülü DSL" terimini kullanmaktan hoşlanmıyorum çünkü eLua gibi şeyler "gömülü DSL" olmasa da iki farklı anlamda "gömülü" olan DSL'ler olabilir!
İşleri daha kötü hale getirmek için bazı projeler karışıma daha da karışıklık getirir. Örneğin. Flatiron şablonları "DSL içermeyen" olarak tanımlanırken, gerçekte şöyle bir sözdizimine sahip mükemmel bir DSL örneğidir:map.where('href').is('/').insert('newurl');
“JavaScript çok güçlü bir dil, CSS'den çok daha güçlü bir dil (hatta herhangi bir CSS önişlemcisini de dahil)) yazdığımda, bu tür şeyler için dahili veya harici DSL'leri tercih edip etmemenize bağlı. tercih meselesi. " Bu iki senaryo hakkında konuşuyordum:
Bir:
/** @jsx React.DOM */
var colored = {
color: myColor
};
React.renderComponent(<div style={colored}>Hello World!</div>, mountNode);
İki:
// SASS:
.colored {
color: $my-color;
}
// HTML:
<div class="colored">Hello World!</div>
İlk örnek, soruda tanımlandığı şeyi kullanır: "CSS'yi JavaScript'te yazmak. Güzel değil." İkinci örnek ise Sass'ı kullanıyor. CSS yazmak için JavaScript kullanmanın güzel olmayabilir ("güzel" in bazı tanımları için) ancak bunu yapmanın bir avantajı olduğunu kabul ediyorum.
Sass'ta değişkenler ve fonksiyonlar olabilir, ancak bunlar sözcüksel olarak mı kapsamda ya da dinamik olarak kapsamda mı? Statik mi yoksa dinamik olarak mı yazılmıştır? Güçlü mü yoksa zayıf mı? Sayısal türlerden ne haber? Zorlama türü? Hangi değerler truthy, hangileri sahtedir? Daha üst düzey fonksiyonlar alabilir miyim? Özyineleme? Kuyruk çağrıları? Sözlüksel kapanışlar? Normal sırayla mı yoksa uygulamalı sırayla mı değerlendiriliyorlar? Tembel veya istekli değerlendirme var mı? İşlevlerin argümanları değere mi yoksa referansa mı göre iletilir? Değişebilirler mi? Immutable? Kalici? Peki ya nesneler? Sınıflar? Prototipler? Kalıtım?
Bunlar önemsiz sorular değildir ve Sass veya Less kodunu anlamak istersem cevaplarını bilmek zorundayım. JavaScript için bu yanıtları zaten biliyorum, bu yüzden bu dahili düzeydeki tüm DSL'leri (React'teki satır içi stiller gibi) zaten anladığım anlamına gelir, bu nedenle React'i kullanırsam, o zaman bu cevaplara yalnızca bir dizi cevap bilmeliyim (ve benzeri) (örneğin, kullandığımda) sorular. Sass ve Gidon o zaman bu cevapların üç setini bilmek ve bunların anlamlarını anlamak zorundayım.
Bir yolun ya da diğerinin her zaman daha iyi olduğunu söylemek değildir, ancak karışıma başka bir dil eklerseniz, ilk bakışta açıkça görülmeyecek bir fiyat ödersiniz ve bu fiyat karmaşıklıktır.
Umarım başlangıçta biraz ne demek istediğimi açıklığa kavuşturdum.
Bağlanma verileri
İki yönlü ciltleme
Bu gerçekten ilginç bir konudur ve aslında bir tercih meselesidir. İki yönlü her zaman tek yönlüden daha iyi değildir. Bu, uygulamanızda değişken durumu nasıl modellemek istediğinizle ilgili bir soru. İki yönlü bağları her zaman işlevsel programlama ilkelerine aykırı bir fikir olarak görmüştüm, ancak işlevsel programlama çalışan tek paradigma değil, bazı insanlar bu tür davranışları tercih ediyor ve her iki yaklaşım da uygulamada oldukça iyi çalışıyor gibi görünüyor. React'te devletin modellenmesi ile ilgili tasarım kararlarının ayrıntılarıyla ilgileniyorsanız, o zaman Pete Hunt (söz konusu olanla bağlantılı) ve Tom Occhino ve Jordan Walke'nin konularını çok iyi anlatan konuşmasını izleyin . benim fikrim.
Güncelleme: Ayrıca Pete Hunt'tan başka bir konuşmaya bakın: Tahmin edilebilir olun, doğru değil: fonksiyonel DOM programlama .
Güncelleme 2: Pek çok geliştiricinin, çift yönlü veri akışına veya iki yönlü bağlantıya karşı savunduğunu , hatta bazılarının buna anti-kalıp dediğini kaydettiğini belirtmek gerekir . Örneğin, MVC modelini (büyük Facebook ve Instagram uygulamaları için ölçeklendirmenin zor olduğu kanıtlanan) kesinlikle tek yönlü bir veri akışı lehine engelleyen Flux uygulama mimarisini düşünün (bkz. Hacker Way: Facebook'ta Web Uygulama Geliştirme'yi Yeniden Düşünmek) . Tom Occhino, Jing Chen ve Pete Hunt, iyi bir tanıtım için). Ayrıca, AngularJS'ye karşı çok fazla eleştiri (iki yönlü veri bağlama için bilinen MVC modeline gevşek olarak dayalı en popüler Web çerçevesi) bu iki yönlü veri akışına karşı argümanlar içerir, bkz:
Güncelleme 3: Yukarıda tartışılan konuların bazılarını güzel bir şekilde açıklayan ilginç bir makale de ReactJS'in Akısını Yeniden Yapmaktır - RefluxJS'in yazarı olan Mikael Brassman (Flux tarafından üretilen tek yönlü veri akışı uygulama mimarisi için basit bir kütüphane) olan ReactJS ile MVC'yi kullanmamaktır .
Güncelleme 4: Ember.js şu anda iki yönlü veri bağlantısından uzaklaşıyor ve gelecekteki sürümlerinde varsayılan olarak tek yönlü olacak. Bakınız: Ember'in Geleceği, 15 Kasım 2014 tarihinde Toronto'daki Embergarten Sempozyumu'ndan Stefan Penner tarafından konuşuldu.
Güncelleme 5: Ayrıca bkz: Ember 2.0'a Giden Yol RFC - Tom Dale'in çekme talebinde ilginç tartışma :
“Orijinal şablon katmanını tasarladığımızda, tüm veri bağlarını iki yönlü yapmanın çok zararlı olmadığını düşündük: iki yönlü bir bağ kurmazsanız, fiilen tek yönlü bir bağlanma var!
O zamandan beri (React'teki arkadaşlarımızdan bazılarının yardımı ile) bileşenlerin, doğru mutasyonlar için korunmak zorunda kalmadan çocuklarına veri dağıtmak istediğini fark ettik.
Ek olarak, bileşenler arasındaki iletişim genellikle en doğal olarak olaylar veya geri aramalar olarak ifade edilir . Bu Ember'de mümkündür, ancak iki yönlü veri bağlantılarının baskınlığı çoğu zaman insanları iki yönlü bağlantıların bir iletişim kanalı olarak kullanma yolunda ilerler . Deneyimli Ember geliştiricileri (genellikle) bu hatayı yapmazlar, ancak bunu yapmak çok kolaydır. ” [Vurgu]
Yerli ve VM
Yerel tarayıcı desteği ("daha hızlı olduğu garantili" okuyun)
Şimdi nihayet bir fikir meselesi olmayan bir şey.
Aslında burası tam tersi. Elbette "native" kodu C ++ dilinde yazılabilir, ancak JavaScript motorlarının ne yazdığını düşünüyorsunuz?
Aslına bakılırsa, JavaScript motorları bugün kullandıkları optimizasyonlarda gerçekten şaşırtıcı - ve sadece V8 değil, ayrıca SpiderMonkey ve hatta Chakra bugünlerde parlıyor. Ayrıca, JIT derleyicileriyle kodun olabildiğince doğal olmadığını, statik olarak derlenmiş herhangi bir kodda yapılması imkansız olan çalışma zamanı optimizasyon fırsatlarının olduğunu unutmayın.
İnsanlar JavaScript'in yavaş olduğunu düşündüklerinde, genellikle DOM'a erişen JavaScript anlamına gelir. DOM yavaştır. Yereldir, C ++ dilinde yazılmıştır ve uygulamak zorunda olduğu karmaşıklık nedeniyle cehennem kadar yavaştır.
Konsolunu aç ve yaz:
console.dir(document.createElement('div'));
div
DOM'a bile bağlı olmayan boş bir öğenin ne kadar özelliği uygulamak zorunda olduğunu görün. Bunlar sadece "kendi özellikleri" olan birinci seviye özelliklerdir. prototip zincirinden devralınmamış:
hizala, beklemede, onpolumechange, ontupupdate, onspend, onsubmit, onstall, onshow, onsel, onsekek, onsekek, onscroll, onresize, onreset, onepecec, onpetec, onousec onmouseenter, onmousedown, onloadstart, onloadedmetadata, onloadeddata, onloadup, onkeyup, onkeypress, onkeydown, oninvalid, ondput, onfocus, ondd, ond, ond, ond, ond, ond, ond, ond, ond, ond, ond, ond, ond, ond açık, açık, açık, açık, açık, açık, açık, açık, açık, açık, açık, açık yazım, isContentEditable,firstElementChild, children, nextElementSibling, öncekiElementSibling, onwheel, onwebkitfullscreenerror, onwebkitfullscreenchange, onelebaşlat, onearch, onpaste, oncut, oncopy, onEt ,Hafta, onFotHaftaHaftaHafta, clientHeight, clientWidth, clientTop, clientLeft, offsetParent, offsetHeight, offsetWidth, offsetTop, offsetLeft, localName, önek, namespaceURI, kimliği, stil, öznitelikler, tagName, parentElement, textContent, baseURI, ownerDocument, childContent, baseURI, ownerDocument, nextCibre, baseURI, ownerDocument, nextCibell, lastCild, firstSildSirenCh parentNode, nodeType, nodeValue, nodeNameoncopy, onbeforepaste, onbeforecut, onset öncesi, webkitShadowRoot, veri kümesi, classList, className, outerHTML, innerHTML, scrollHeight, scrollWidth, scrollTop, scrollLeft, clientHeight, clientWidth, clientTop, scrollLeft, clientHeight, clientWidth namespaceURI, kimliği, stil, nitelikler, tagName, parentElement, textContent, baseURI, ownerDocument, nextSibling, öncekiSibling, lastChild, firstChild, childNodes, parentNode, nodeType, nodeValue, nodeNameoncopy, onbeforepaste, onbeforecut, onset öncesi, webkitShadowRoot, veri kümesi, classList, className, outerHTML, innerHTML, scrollHeight, scrollWidth, scrollTop, scrollLeft, clientHeight, clientWidth, clientTop, scrollLeft, clientHeight, clientWidth namespaceURI, kimliği, stil, nitelikler, tagName, parentElement, textContent, baseURI, ownerDocument, nextSibling, öncekiSibling, lastChild, firstChild, childNodes, parentNode, nodeType, nodeValue, nodeNameparentElement, textContent, baseURI, ownerDocument, nextSibling, öncekiSibling, lastChild, firstChild, childNodes, parentNode, nodeType, nodeValue, nodeNameparentElement, textContent, baseURI, ownerDocument, nextSibling, öncekiSibling, lastChild, firstChild, childNodes, parentNode, nodeType, nodeValue, nodeName
Birçoğu aslında iç içe geçmiş nesnelerdir - div
tarayıcınızda boş bir yerin ikinci düzey (kendi) özelliklerini görmek için bu kemanı görün .
Her div düğümündeki ciddiyetle onvolumechange özelliği mi demek istedim ? Bu bir hata mı? Hayır, sadece HTML özelliklerinin Bölüm 6.1.6.2'de yer alan "içerik işleyicileri ve IDL öznitelikleri" olarak tüm HTML öğeleri tarafından desteklenmesi gereken "işleyicilerden birinin eski bir DOM Düzey 0 geleneksel etkinlik modeli sürümüdür. W3C tarafından - etrafında değil.
Bu arada, bunlar div
React’te sahte bir DOM’un ilk seviye özellikleridir :
sahne, _owner, _lifeCycleState, _pendingProps, _pendingCallbacks, _pendingOwner
Oldukça bir fark, değil mi? Aslında bu, JSON'a ( LIVE DEMO ) göre seri hale getirilmiş nesnenin tamamıdır , çünkü hey , onu doçent referanslar içermediğinden JSON'a seri hale getirebilirsiniz - yerel DOM dünyasında düşünülemez bir şey ( sadece bir istisna atacağı yer) ):
{
"props": {},
"_owner": null,
"_lifeCycleState": "UNMOUNTED",
"_pendingProps": null,
"_pendingCallbacks": null,
"_pendingOwner": null
}
Bu, React'in yerel tarayıcı DOM'sinden daha hızlı olmasının ana nedenidir - çünkü bu karışıklığı uygulamak zorunda değildir .
Bkz Steven Lüscher tarafından bu sunum C ++ ile yazılmış yerli DOM veya JavaScript tamamen yazılmış sahte DOM: Daha hızlı ne olduğunu görmek için. Çok adil ve eğlenceli bir sunum.
Güncelleme: Gelecekteki sürümlerde Ember.js , performansı arttırmak için React'ten büyük ölçüde ilham alan sanal bir DOM kullanacak. Bakınız: Ember'in Geleceği, 15 Kasım 2014 tarihinde Toronto'daki Embergarten Sempozyumu'ndan Stefan Penner tarafından konuşuldu.
Özetlemek gerekirse, şablonlar, veri bağlama veya özel öğeler gibi Web Bileşenleri'nin özellikleri React'e göre çok fazla avantaja sahip olacak, ancak belge nesnesi modelinin kendisi önemli ölçüde basitleştirilinceye kadar performans bunlardan biri olmayacak.
Güncelleme
Bu cevapları gönderdikten iki ay sonra, burada alakalı bir haber vardı. Gibi ben sadece Twitter'da yazdım , en son sürümüdür Atom JavaScript GitHub'dan tarafından yazılan metin editörü Facebook'un rağmen iyi performans elde etmek React kullanır Vikipedi göre bunun tam kontrole sahip yüzden "Atom Krom dayalı ve C ++ ile yazılmış" yerel C ++ DOM uygulaması (bkz . Atom Çekirdeği ) ve kendi Web tarayıcısıyla birlikte gönderildiği için Web Bileşenleri'ni destekleyeceği garantilidir. Bu, Web uygulamalarında genellikle bulunmayan başka bir optimizasyon türü kullanmış olabilecek gerçek bir dünya projesinin sadece son zamanlardaki bir örneğidir ve yine de Atom’a rağmen en iyi performansı elde etmek için JavaScript’te yazılmış olan React’i kullanmayı seçmiştir. Başlamak için React ile inşa edilmedi, bu yüzden bunu yapmak önemsiz bir değişiklik değildi.
Güncelleme 2
Orada Todd Parker tarafından ilginç bir karşılaştırma kullanılarak WebPagetest performansını karşılaştırmak için TodoMVC Eğik, omurga yazılmış örnekler, Ember, Polimer, CanJS, YUI, Nakavt, tepki ve Shoestring. Bu, şu ana kadar gördüğüm en objektif karşılaştırma. Burada önemli olan, ilgili örneklerin tümünün bu çerçevelerdeki uzmanlar tarafından yazıldığı, hepsinin GitHub'da mevcut olduğu ve kodun bazılarının daha hızlı çalışacak şekilde optimize edilebileceğini düşünen herkes tarafından geliştirilebileceği.
Güncelleme 3
Gelecekteki sürümlerde Ember.js , burada tartışılan bir dizi React özelliğini içerecektir (sanal DOM ve tek yönlü veri bağlama da dahil olmak üzere, sadece birkaçını belirtmek için). Bakınız: Ember 2.0'a Giden Yol (RFC) Tom Dale tarafından yapılan çekme isteğinde ilginç tartışma (Başlangıç Tarihi: 2014-12-03): "Ember 2.0'da," sanal DOM "ve veri akış modelini benimseyen bir model olacak. React'ten en iyi fikirler, bileşenler arasındaki iletişimi React ve kolaylaştırıyor. "
Ayrıca, Angular.js 2.0 burada tartışılan birçok kavramı uygulamaktadır.
Güncelleme 4
Bu yorumu yanıtlamak için Igwe Kalu’dan birkaç konu üzerinde durmam gerekiyor:
“React sonuçta düz JavaScript ile azaldığında, React'i (JSX veya derleme çıktısı) düz JavaScript ile karşılaştırmak mantıklı değildir. Söz konusu özelliği kolaylık dışında düşünürken herhangi bir özel avantaj sağlamaz. ” ( burada tam yorum )
Yeterince açık olmadıysa, cevabımın bir kısmında, doğrudan yerel DOM üzerinde (tarayıcıda ana bilgisayar nesneleri olarak uygulanan) çalışma performansını karşılaştırarak React'in sahte / sanal DOM'sini (JavaScript'te uygulanmış) karşılaştırıyorum. Ben yapmaya çalışıyorum nokta JavaScript uygulanan sanal DOM olmasıdır edebilirsiniz C ++ uygulanan gerçek DOM daha iyi performans ve değil ki (o zamandan beri Açıkçası çok anlamlı olmaz JavaScript iyi performans gösterebilirler Tepki olan JavaScript ile yazılan). Demek istediğim, "yerel" C ++ kodunun her zaman "yerel olmayan" JavaScript'ten daha hızlı olması garanti edilmez. Bu noktayı göstermek için React'i kullanmak sadece bir örnekti.
Ancak bu yorum ilginç bir konuya değindi. Bir anlamda, herhangi bir nedenle (performans, taşınabilirlik, özellikler gibi) herhangi bir çerçeveye (React, Angular veya jQuery) ihtiyaç duymadığınız doğrudur (çünkü performans, taşınabilirlik, özellikler), çünkü çerçevenin sizin için ne yaptığını her zaman yeniden oluşturabilir ve tekerleği yeniden keşfedebilirsiniz - eğer maliyeti haklı çıkarabilirsin.
- Ama Dave Smith'in güzel de dediği gibi web çerçeve performansını karşılaştırırken noktayı kaçırmak Nasıl : "iki web çerçeveleri karşılaştırırken, soru değil edebilirsiniz soru çerçeve X ile benim app hızlı olacak olacak benim app çerçevesine hızlı olacak X."
Gelen benim 2011 cevap: jQuery kullanmamaya bazı ampirik teknik nedenler nelerdir ben jQuery gibi bir kütüphane olmadan taşınabilir DOM-manipülasyon kod yazmak imkansız olmadığını, ama insanlar nadiren bunu yapmasını, benzer bir sorunu açıklar.
Programlama dilleri, kütüphaneler veya çerçeveler kullanılırken, insanlar mükemmel ama uygunsuz olanları yapmanın en uygun ya da deyimsel yollarını kullanma eğilimindedir. İyi çerçevelerin gerçek değeri, başka türlü yapılması zor olan şeyleri kolaylaştırmaktır - ve sır, doğru şeyleri uygun hale getirmektir . Sonuç, emrinizde hala en basit lambda matematiği veya en ilkel Turing makinesi formuyla aynı güce sahip olmakla birlikte, bazı kavramların göreceli ifadesi, bu kavramların daha kolay veya hiç ifade edilme eğiliminde olduğu anlamına gelir. doğru çözümler sadece mümkün değil aynı zamanda geniş çapta uygulanmaktadır.
Güncelleme 5
Tepki + Performans =? Temmuz 2015’ten Paul Lewis’in makalesi, React’in, özellikle mobil cihazlarda önem arz eden, Flickr resimlerinin sonsuz bir listesi için elle yazılmış, vanilya JavaScript’inden daha yavaş olduğu bir örneği göstermektedir. Bu örnek, herkesin her zaman belirli kullanım durumları ve belirli hedef platformlar ve cihazlar için performansı test etmesi gerektiğini gösterir.
Kevin Lozandier'e dikkatimi çektiğiniz için teşekkür ederim .