Pro dan Kontra Reaksi Facebook vs Komponen Web (Polimer)

521

Apa manfaat utama Reaksi Facebook atas spesifikasi Komponen Web yang akan datang dan sebaliknya (atau mungkin perbandingan apel dengan apel yang lebih banyak dengan perpustakaan Polimer Google )?

Menurut ceramah JSConf EU ini dan beranda React, manfaat utama React adalah:

  • Decoupling dan peningkatan kohesi menggunakan model komponen
  • Abstraksi, Komposisi, dan Ekspresivitas
  • Virtual DOM & Synthetic events (yang pada dasarnya berarti mereka sepenuhnya mengimplementasikan ulang DOM dan sistem acara)
    • Mengaktifkan konten acara HTML5 modern di IE 8
    • Render sisi server
    • Testabilitas
    • Binding ke SVG, VML, dan <canvas>

Hampir semua yang disebutkan diintegrasikan ke dalam browser secara asli melalui Komponen Web kecuali konsep DOM virtual ini (jelas). Saya dapat melihat bagaimana DOM virtual dan acara sintetik dapat bermanfaat hari ini untuk mendukung browser lama, tetapi tidak membuang banyak kode browser asli seperti menembak diri sendiri dalam jangka panjang? Sejauh browser modern yang bersangkutan, bukankah itu banyak overhead / reinventing yang tidak perlu?

Berikut adalah beberapa hal yang saya pikir Bereaksi hilang bahwa Komponen Web akan mengurusnya untuk Anda. Koreksi saya jika saya salah.

  • Dukungan browser asli (baca "dijamin lebih cepat")
  • Tulis skrip dalam bahasa skrip, gaya penulisan dalam bahasa gaya, tulis markup dalam bahasa markup.
  • Enkapsulasi gaya menggunakan Shadow DOM
    • Bereaksi sebaliknya memiliki ini , yang membutuhkan penulisan CSS dalam JavaScript. Tidak cantik.
  • Ikatan dua arah
CletusW
sumber
12
Wrt. mengikat dua arah. Fitur ini bermasalah pada skala. Dalam kasus sepele itu bekerja dengan baik, tetapi dalam kasus dunia nyata Anda biasanya menemukan bahwa untuk menjaga kode dapat dikelola Anda memerlukan viewmodel untuk mengikat, alih-alih mengikat terhadap model yang sebenarnya, yang kemudian membuat ikatan dua arah jauh lebih berguna daripada itu awalnya tampak. Saya pikir itu mungkin keuntungan dari Bereaksi bahwa itu tidak memberikan pengikatan dua arah karena memaksa arsitektur aliran data yang tepat.
Joeri Sebrechts
8
Saya telah melihat React, Angular dan Knockout. Saya menemukan Knockout yang 'terbersih' dalam hal pemisahan ui templating, data, dan binding. Saya ingin suka bereaksi, tetapi mencoba membuat Combobox sederhana, saya sadar saya menulis lebih banyak kode dan mencampur logika rendering dengan templat html .. jauh lebih daripada yang saya lakukan dengan menggunakan sesuatu seperti html / jina2. Menurut saya perpustakaan / apis ini menggerakkan kita ke belakang, bukan ke depan. Hal terbaik tentang Bereaksi adalah manipulasi dom virtual, tetapi saya bisa melihat bahwa datang ke kerangka kerja mapan lainnya lebih cepat daripada nanti.
mike01010
41
Saya sangat terkejut (dan juga senang!) Bahwa pertanyaan ini tidak ditutup sebagai "berdasarkan pendapat".
iconoclast
4
Tidak mungkin menulis "skrip dalam bahasa scripting" dan "markup dalam bahasa markup" jika Anda melakukan templating dalam bentuk apa pun. Sudut, polimer, dll. Menggunakan template DSL yang tertanam dalam HTML. Bereaksi menggunakan DSL template yang tertanam di JS (JSX). Masalah dengan menanamkan DSL dalam HTML adalah bagaimana membangun ruang lingkup untuk mendapatkan nilai dari JS. Ini mengarah ke sistem $ scope Angular yang kompleks. Di JSX, di sisi lain, ruang lingkup variabel dalam template hanya ruang lingkup JS - Saya merasa jauh lebih membingungkan.
Andy
3
Saat ini komponen Bereaksi (kecuali ditulis dengan buruk) akan lebih cepat daripada yang sama dalam kerangka kerja DOM-terikat. V-dom dan sihir yang berbeda adalah USP dari reaksi. Maksud saya adalah - Mengapa browser tidak membuat perbedaan seperti itu di set fitur asli mereka. Apa yang menghentikan mereka, dan jika tidak ada (menghentikan mereka) maka pemimpin Bereaksi mungkin akan berumur pendek.
fasttrainofthoughts

Jawaban:

664

Pembaruan:  jawaban ini tampaknya cukup populer sehingga saya mengambil sedikit waktu untuk membersihkannya sedikit, menambahkan beberapa info baru dan mengklarifikasi beberapa hal yang saya pikir tidak cukup jelas. Berikan komentar jika Anda merasa ada hal lain yang perlu diklarifikasi atau diperbarui.

Sebagian besar kekhawatiran Anda benar-benar masalah pendapat dan preferensi pribadi, tetapi saya akan mencoba menjawab secara objektif yang saya bisa:

Native vs. Compiled

Tulis JavaScript dalam vanilla JavaScript, tulis CSS dalam CSS, tulis HTML dalam HTML.

Kembali pada hari ada perdebatan panas apakah seseorang harus menulis  Majelis asli dengan tangan atau menggunakan bahasa tingkat yang lebih tinggi seperti C untuk membuat kompiler menghasilkan kode Majelis untuk Anda. Bahkan sebelum itu orang menolak untuk mempercayai perakit dan lebih suka menulis kode mesin asli dengan tangan ( dan saya tidak bercanda ).

Sementara itu, hari ini ada banyak orang yang menulis HTML di Haml atau Jade , CSS di Sass atau Kurang dan JavaScript dalam CoffeeScript atau TypeScript . Itu disana. Berhasil. Beberapa orang lebih menyukainya, beberapa tidak.

Intinya adalah bahwa tidak ada yang salah secara fundamental dalam tidak menulis JavaScript dalam JavaScript vanilla, CSS dalam CSS, dan HTML dalam HTML. Ini benar-benar masalah preferensi.

DSL Internal vs. Eksternal

 Enkapsulasi gaya menggunakan Shadow DOM React memiliki ini, yang membutuhkan penulisan CSS dalam JavaScript. Tidak cantik.

Cantik atau tidak, tentu ekspresif. JavaScript adalah bahasa yang sangat kuat, jauh lebih kuat daripada CSS (bahkan termasuk salah satu dari preprosesor CSS). Ini tergantung pada apakah Anda lebih suka DSL internal atau eksternal untuk hal-hal semacam itu. Sekali lagi, masalah preferensi.

(Catatan: Saya berbicara tentang gaya sebaris di Bereaksi yang direferensikan dalam pertanyaan asli.)

Jenis DSL - penjelasan

Pembaruan: Membaca jawaban saya beberapa saat setelah menulisnya, saya pikir saya perlu menjelaskan apa yang saya maksud di sini. DSL adalah bahasa khusus domain dan dapat berupa internal (menggunakan sintaks dari bahasa host seperti JavaScript - seperti misalnya Bereaksi tanpa JSX, atau seperti gaya inline dalam Bereaksi yang disebutkan di atas) atau bisa juga eksternal (menggunakan sintaks berbeda daripada bahasa host - seperti dalam contoh ini akan inlining CSS (DSL eksternal) di dalam JavaScript).

Ini dapat membingungkan karena beberapa literatur menggunakan istilah yang berbeda dari "internal" dan "eksternal" untuk menggambarkan jenis-jenis DSL. Terkadang "tertanam" digunakan alih-alih "internal" tetapi kata "tertanam" dapat memiliki arti yang berbeda - misalnya Lua digambarkan sebagai "Lua: bahasa yang disematkan yang dapat diperluas" di mana tertanam tidak ada hubungannya dengan DSL (internal) yang tertanam (dalam) yang merasakannya justru sebaliknya - DSL eksternal) tetapi itu berarti bahwa itu tertanam dalam arti yang sama bahwa, katakanlah, SQLite adalah database tertanam. Bahkan ada eLua di mana "e" adalah singkatan dari "embedded" dalam arti ketiga - yang dimaksudkan untuk embedded system! Itu sebabnya saya tidak suka menggunakan istilah "DSL yang disematkan" karena hal-hal seperti eLua dapat menjadi "DSL" yang "tertanam" dalam dua pengertian yang berbeda dan sama sekali tidak menjadi "DSL yang disematkan"!

Untuk membuat keadaan menjadi lebih buruk, beberapa proyek bahkan menimbulkan lebih banyak kebingungan. Misalnya. Template seterika dijelaskan sebagai "bebas DSL", padahal sebenarnya ini hanyalah contoh sempurna dari DSL internal dengan sintaksis seperti:map.where('href').is('/').insert('newurl');

Yang telah dikatakan, ketika saya menulis "JavaScript adalah bahasa yang sangat kuat, jauh lebih kuat daripada CSS (bahkan termasuk salah satu preprosesor CSS). Itu tergantung pada apakah Anda lebih suka DSL internal atau eksternal untuk hal-hal semacam itu. Sekali lagi, masalah preferensi. " Saya berbicara tentang dua skenario itu:

Satu:

/** @jsx React.DOM */
var colored = {
  color: myColor
};
React.renderComponent(<div style={colored}>Hello World!</div>, mountNode);

Dua:

// SASS:
.colored {
  color: $my-color;
}
// HTML:
<div class="colored">Hello World!</div>

Contoh pertama menggunakan apa yang dijelaskan dalam pertanyaan sebagai: "menulis CSS dalam JavaScript. Tidak cantik." Contoh kedua menggunakan Sass. Meskipun saya setuju bahwa menggunakan JavaScript untuk menulis CSS mungkin tidak cukup (untuk beberapa definisi "cantik") tetapi ada satu keuntungan melakukannya.

Saya dapat memiliki variabel dan fungsi di Sass, tetapi apakah cakupannya secara leksikal atau dinamis? Apakah mereka diketik secara statis atau dinamis? Kuat atau lemah? Bagaimana dengan tipe numerik? Ketik pemaksaan? Nilai-nilai mana yang benar dan mana yang salah? Bisakah saya memiliki fungsi tingkat tinggi? Pengulangan? Panggilan ekor? Penutupan leksikal? Apakah mereka dievaluasi dalam urutan normal atau urutan aplikatif? Apakah ada evaluasi malas atau bersemangat? Apakah argumen untuk fungsi dilewatkan oleh nilai atau dengan referensi? Apakah mereka bisa berubah? Abadi? Gigih? Bagaimana dengan benda? Kelas? Prototipe? Warisan?

Itu bukan pertanyaan sepele, namun saya harus tahu jawaban mereka jika saya ingin mengerti kode Sass atau Less. Saya sudah tahu jawaban-jawaban untuk JavaScript sehingga itu berarti bahwa saya sudah mengerti setiap DSL internal (seperti gaya inline dalam Bereaksi) pada tingkat-tingkat itu jadi jika saya menggunakan Bereaksi maka saya harus tahu hanya satu set jawaban untuk itu (dan banyak yang serupa ) pertanyaan, sedangkan ketika saya gunakan untuk mis. Sass dan Setang kemudian saya harus tahu tiga set jawaban itu dan memahami implikasinya.

Ini bukan untuk mengatakan bahwa salah satu cara atau yang lain selalu lebih baik tetapi setiap kali Anda memperkenalkan bahasa lain ke campuran maka Anda membayar harga yang mungkin tidak begitu jelas pada pandangan pertama, dan harga ini adalah kompleksitas.

Saya harap saya mengklarifikasi apa yang awalnya saya maksudkan sedikit.

Pengikatan data

Ikatan dua arah

Ini adalah subjek yang sangat menarik dan sebenarnya juga masalah preferensi. Dua arah tidak selalu lebih baik dari satu arah. Ini pertanyaan tentang bagaimana Anda ingin memodelkan keadaan yang bisa berubah dalam aplikasi Anda. Saya selalu melihat ikatan dua arah sebagai ide yang agak bertentangan dengan prinsip-prinsip pemrograman fungsional tetapi pemrograman fungsional bukan satu-satunya paradigma yang berfungsi, beberapa orang lebih menyukai perilaku semacam ini dan kedua pendekatan tampaknya bekerja dengan cukup baik dalam praktiknya. Jika Anda tertarik dengan detail keputusan desain yang terkait dengan pemodelan keadaan dalam React, saksikan ceramah oleh Pete Hunt (ditautkan dalam pertanyaan) dan ceramah oleh Tom Occhino dan Jordan Walke  yang menjelaskannya dengan sangat baik di pendapat saya.

Perbarui: Lihat juga pembicaraan lain oleh Pete Hunt: Dapat diprediksi, tidak benar: pemrograman DOM fungsional .

Pembaruan 2: Perlu dicatat bahwa banyak pengembang menentang aliran data dua arah, atau mengikat dua arah, beberapa bahkan menyebutnya sebagai anti-pola. Ambil contoh arsitektur aplikasi Flux yang secara eksplisit menghindari model MVC (yang terbukti sulit untuk skala untuk aplikasi Facebook dan Instagram besar) yang mendukung aliran data searah (lihat Hacker Way: Memikirkan Kembali Pengembangan Aplikasi Web di Facebook talk oleh Tom Occhino, Jing Chen dan Pete Hunt untuk perkenalan yang bagus). Juga, banyak kritik terhadap AngularJS (kerangka kerja Web paling populer yang didasarkan pada model MVC, yang dikenal untuk pengikatan data dua arah) termasuk argumen terhadap aliran data dua arah, lihat:

Pembaruan 3: Artikel menarik lainnya yang menjelaskan beberapa masalah yang didiskusikan di atas adalah Mendekonstruksi Fluks ReactJS - Tidak menggunakan MVC dengan ReactJS oleh Mikael Brassman, penulis RefluxJS (perpustakaan sederhana untuk arsitektur aplikasi aliran data searah yang diilhami oleh Flux).

Pembaruan 4: Ember.js saat ini sedang menjauh dari pengikatan data dua arah dan dalam versi mendatang itu akan menjadi satu arah secara default. Lihat: Pembicaraan Masa Depan Ember oleh Stefan Penner dari Simposium Embergarten di Toronto pada 15 November 2014.

Pembaruan 5: Lihat juga: The Road to Ember 2.0 RFC - diskusi menarik dalam permintaan tarik oleh Tom Dale :

"Ketika kami merancang lapisan templating asli, kami menduga bahwa membuat semua ikatan data dua arah tidak terlalu berbahaya: jika Anda tidak menetapkan ikatan dua arah, itu adalah pengikatan satu arah de facto!

Kami telah menyadari (dengan bantuan dari teman-teman kami di React), bahwa komponen ingin dapat membagikan data kepada anak-anak mereka tanpa harus waspada terhadap mutasi yang tidak patuh.

Selain itu, komunikasi antar komponen seringkali paling alami diungkapkan sebagai peristiwa atau panggilan balik . Ini dimungkinkan dalam Ember, tetapi dominasi pengikatan data dua arah sering membuat orang menggunakan jalur pengikatan dua arah sebagai saluran komunikasi . Pengembang Ember yang berpengalaman tidak (biasanya) melakukan kesalahan ini, tapi itu mudah dilakukan. " [Penekanan ditambahkan]

Asli vs VM

Dukungan browser asli (baca "dijamin lebih cepat")

Sekarang akhirnya sesuatu yang bukan masalah pendapat.

Sebenarnya di sini justru sebaliknya. Tentu saja "asli" kode dapat ditulis dalam C ++ tetapi apa yang Anda pikirkan mesin JavaScript ditulis?

Sebenarnya mesin JavaScript benar-benar luar biasa dalam optimasi yang mereka gunakan saat ini - dan tidak hanya V8 lagi, juga SpiderMonkey dan bahkan Chakra bersinar hari ini. Dan perlu diingat bahwa dengan kompiler JIT kode tidak hanya sebagai asli seperti yang mungkin tetapi ada juga peluang optimasi waktu berjalan yang tidak mungkin dilakukan dalam kode yang dikompilasi secara statis.

Ketika orang-orang berpikir bahwa JavaScript lambat, mereka biasanya berarti JavaScript yang mengakses DOM. DOM lambat. Ini asli, ditulis dalam C ++ dan masih sangat lambat karena kompleksitas yang harus diimplementasikan.

Buka konsol Anda dan tulis:

console.dir(document.createElement('div'));

dan lihat berapa banyak properti yang divharus diimplementasikan oleh elemen kosong yang bahkan tidak melekat pada DOM. Ini hanya  properti tingkat pertama yang "properti sendiri" yaitu. tidak diwarisi dari rantai prototipe:

menyelaraskan, menunggu, onvolumechange, ontimeupdate, onsuspend, onsubmit, onshow, onselect, onseeking, onseeked, onscroll, onreset, onratet, onratechange, pada progres, bermain, onplay, onpause, onmumewewheel, onmouse, onmouse, onmouse, onmouse, onmouse, onmouse, onmouse, onmouse, onmouse, onmouse, onmouse, onmouse, onmome, onmome, onmome, onmouse). onmouseenter, onmousedown, onloadstart, onloadedmetadata, onloadeddata, onloadup, onkeyupress, onkeydown, oninvalid, oninput, onfokus, onerror, onending, ondtingkatkan, ondurationchange, ondrop, ondragstartterubah, ondrag ondragd ondddakdakadakdakdakakdakakdakakdakakadidakakakakakakakakakakakakakakakakakakakakakakakakakakakakakakakakakakakakakakakakakakakakakimakanakanakanakanakandilemparkan, oncontextmenu, onclose, onclick, onchange, oncanplaythrough, oncanplay, oncancel, onabort, onabort, spellcheck, isContentEditable, contentEditable, outerText, innerText, accessKey, tersembunyi, webkitdropzone, draggable, tabIndex, direktori, jumlah, trans, jumlah, trans, tanda, jumlah, trans, tanda, jumlah, terjemahan,firstElementChild, anak-anak, nextElementSibling, sebelumnyaElementSibling, onwheel, onwebkitfullscreenerror, onwebkitfullscreenchange, onstectstart, onearch, onpaste, oncopy, onbeforepaste, onbeforecut, onbeforecut, onbeforecut, onbeforecut, onbeforecopy, scrollhobe, scrolldalam scrollhttp, penggambaranHal clientHeight, clientWidth, clientTop, clientLeft, offsetParent, offsetHeight, offsetWidth, offsetTop, offsetLeft, localName, awalan, namespaceURI, id, gaya, atribut, tagName, parentElement, textContent, baseURI, pemilikDokumen, anak-anak, pesan terakhir, natal parentNode, nodeType, nodeValue, nodeNameoncopy, onbeforepaste, onbeforecut, onbeforecopy, webkitShadowRoot, dataset, classList, className, outerHTML, innerHTML, scrollTinggi, scrollLebar, scrollTop, scrollLeft, clientHeight, clientLebar, clientTop, clientLeft, offsetTanggal, offsettangguh, offsettangguh ,tempuhtanggal namespaceURI, id, style, atribut, tagName, parentElement, textContent, baseURI, ownerDocument, NextSibling ,Segling sebelumnya, LastChild, firstChild, childNode, parentNode, nodeType, nodeValue, nodeNameoncopy, onbeforepaste, onbeforecut, onbeforecopy, webkitShadowRoot, dataset, classList, className, outerHTML, innerHTML, scrollTinggi, scrollLebar, scrollTop, scrollLeft, clientHeight, clientLebar, clientTop, clientLeft, offsetTanggal, offsettangguh, offsettangguh ,tempuhtanggal namespaceURI, id, style, atribut, tagName, parentElement, textContent, baseURI, ownerDocument, NextSibling ,Segling sebelumnya, LastChild, firstChild, childNode, parentNode, nodeType, nodeValue, nodeNameparentElement, textContent, baseURI, ownerDocument, nextSibling ,Segling sebelumnya, LastChild, firstChild, childNode, parentNode, nodeType, nodeType, nodeValue, nodeNameparentElement, textContent, baseURI, ownerDocument, nextSibling ,Segling sebelumnya, LastChild, firstChild, childNode, parentNode, nodeType, nodeType, nodeValue, nodeName

Banyak dari mereka sebenarnya adalah objek bersarang - untuk melihat properti level kedua (milik) asli yang kosong divdi browser Anda, lihat biola ini .

Maksud saya serius, properti onvolumechange pada setiap node div tunggal? Apakah ini sebuah kesalahan? Tidak, itu hanya versi lama DOM Level 0 versi model acara tradisional dari salah satu penangan acara "yang harus didukung oleh semua elemen HTML , karena atribut konten dan atribut IDL" [penekanan ditambahkan] pada Bagian 6.1.6.2 dari spesifikasi HTML oleh W3C - tidak ada jalan lain.

Sementara itu, ini adalah properti tingkat pertama dari DOM palsu divdi Bereaksi:

alat peraga, _owner, _lifeCycleState, _pendingProps, _pendingCallbacks, _pendingOwner

Cukup berbeda, bukan? Sebenarnya ini adalah seluruh objek yang diserialisasi ke JSON ( LIVE DEMO ), karena hei Anda benar - benar dapat membuat  serial menjadi JSON karena tidak mengandung referensi melingkar - sesuatu yang tidak terpikirkan dalam dunia DOM asli (di mana ia hanya akan melemparkan pengecualian) ):

{
  "props": {},
  "_owner": null,
  "_lifeCycleState": "UNMOUNTED",
  "_pendingProps": null,
  "_pendingCallbacks": null,
  "_pendingOwner": null
}

Ini cukup banyak alasan utama mengapa Bereaksi bisa lebih cepat daripada DOM browser asli - karena tidak harus menerapkan kekacauan ini .

Lihat presentasi ini oleh Steven Luscher untuk melihat apa yang lebih cepat: DOM asli ditulis dalam C ++ atau DOM palsu yang seluruhnya ditulis dalam JavaScript. Ini adalah presentasi yang sangat adil dan menghibur.

Pembaruan: Ember.js dalam versi yang akan datang akan menggunakan DOM virtual yang sangat terinspirasi oleh React untuk meningkatkan kinerja. Lihat: Pembicaraan Masa Depan Ember oleh Stefan Penner dari Simposium Embergarten di Toronto pada 15 November 2014.

Singkatnya: fitur-fitur dari Komponen Web seperti templat, pengikatan data, atau elemen kustom akan memiliki banyak keunggulan dibandingkan Bereaksi tetapi sampai model objek dokumen itu sendiri secara signifikan disederhanakan maka kinerja tidak akan menjadi salah satunya.

Memperbarui

Dua bulan setelah saya memposting jawaban ini ada beberapa berita yang relevan di sini. Seperti yang baru saja saya tulis di Twitter , versi terbaru dari editor teks Atom yang ditulis oleh GitHub di JavaScript menggunakan Facebook's React untuk mendapatkan kinerja yang lebih baik meskipun menurut Wikipedia "Atom didasarkan pada Chromium dan ditulis dalam C ++" sehingga memiliki kontrol penuh terhadap implementasi DOM asli C ++ (lihat Inti dari Atom ) dan dijamin memiliki dukungan untuk Komponen Web karena ia dikirim dengan browser web sendiri. Ini hanyalah contoh yang sangat baru dari proyek dunia nyata yang dapat menggunakan jenis pengoptimalan lain yang biasanya tidak tersedia untuk aplikasi Web, namun ia telah memilih untuk menggunakan React yang ditulis dalam JavaScript, untuk mencapai kinerja terbaik, meskipun Atom tidak dibangun dengan React untuk memulai, jadi melakukan itu bukan perubahan sepele.

Perbarui 2

Ada perbandingan yang menarik oleh Todd Parker menggunakan WebPagetest untuk membandingkan kinerja contoh-contoh TodoMVC yang ditulis dalam Angular, Backbone, Ember, Polymer, CanJS, YUI, Knockout, React, dan Shoestring. Ini adalah perbandingan paling objektif yang pernah saya lihat sejauh ini. Yang penting di sini adalah bahwa semua contoh masing-masing ditulis oleh para ahli dalam semua kerangka kerja tersebut, semuanya tersedia di GitHub dan dapat ditingkatkan oleh siapa saja yang berpikir bahwa beberapa kode dapat dioptimalkan untuk berjalan lebih cepat.

Perbarui 3

Ember.js dalam versi mendatang akan mencakup sejumlah fitur Bereaksi yang dibahas di sini (termasuk DOM virtual dan pengikatan data searah, untuk menyebutkan beberapa) yang berarti bahwa ide-ide yang berasal dari Bereaksi sudah bermigrasi ke kerangka kerja lain. Lihat: The Road to Ember 2.0 RFC - diskusi menarik dalam permintaan tarik oleh Tom Dale (Tanggal Mulai: 2014-12-03): "Di Ember 2.0, kita akan mengadopsi" virtual DOM "dan model aliran data yang mencakup ide terbaik dari Bereaksi dan menyederhanakan komunikasi antar komponen. "

Selain itu, Angular.js 2.0 menerapkan banyak konsep yang dibahas di sini.

Perbarui 4

Saya harus menguraikan beberapa masalah untuk menjawab komentar ini oleh Igwe Kalu:

"Tidak masuk akal untuk membandingkan React (JSX atau output kompilasi) dengan JavaScript biasa, ketika React pada akhirnya berkurang menjadi JavaScript biasa. [...] Apapun strategi yang digunakan Bereaksi untuk penyisipan DOM dapat diterapkan tanpa menggunakan React. Dikatakan, itu tidak menambahkan manfaat khusus saat mempertimbangkan fitur yang dipermasalahkan selain kenyamanan. " (komentar lengkap di sini )

Dalam hal itu tidak cukup jelas, sebagian dari jawaban saya, saya membandingkan kinerja operasi langsung pada DOM asli (diimplementasikan sebagai objek host di browser) vs DOM palsu / virtual Dire (diterapkan dalam JavaScript). Titik Saya mencoba untuk membuat adalah bahwa DOM maya diimplementasikan dalam JavaScript dapat mengungguli DOM nyata diimplementasikan dalam C ++ dan tidak yang Bereaksi dapat mengungguli JavaScript (yang jelas tidak akan masuk akal karena ini ditulis dalam JavaScript). Maksud saya adalah bahwa kode "asli" C ++ tidak selalu dijamin lebih cepat daripada JavaScript "tidak asli". Menggunakan Bereaksi untuk menggambarkan titik itu hanyalah sebuah contoh.

Namun komentar ini menyentuh masalah yang menarik. Dalam arti tertentu memang benar bahwa Anda tidak memerlukan kerangka kerja apa pun (Bereaksi, Sudut atau jQuery) untuk alasan apa pun (seperti kinerja, portabilitas, fitur) karena Anda selalu dapat membuat ulang apa yang dilakukan kerangka kerja untuk Anda dan menemukan kembali roda - jika Anda dapat membenarkan biayanya, yaitu.

Tapi - seperti Dave Smith baik memasukkannya ke dalam Bagaimana kehilangan titik ketika membandingkan kinerja kerangka web : "Ketika membandingkan dua kerangka web, pertanyaannya adalah tidak bisa aplikasi saya cepat dengan kerangka X. Pertanyaannya adalah akan app saya cepat dengan kerangka X. "

Dalam jawaban 2011 saya untuk: Apa beberapa alasan teknis empiris untuk tidak menggunakan jQuery Saya menjelaskan masalah yang sama, bahwa bukan tidak mungkin untuk menulis kode DOM-manipulasi portabel tanpa perpustakaan seperti jQuery, tetapi orang jarang melakukannya.

Saat menggunakan bahasa pemrograman, perpustakaan atau kerangka kerja, orang cenderung menggunakan cara yang paling nyaman atau idiomatis dalam melakukan sesuatu, bukan yang sempurna tetapi tidak nyaman. Nilai sebenarnya dari kerangka kerja yang baik adalah memudahkan apa yang seharusnya sulit dilakukan - dan rahasianya adalah membuat hal-hal yang benar nyaman. Hasilnya masih memiliki kekuatan yang persis sama yang Anda inginkan sebagai bentuk paling sederhana dari kalkulus lambda atau mesin Turing paling primitif, tetapi ekspresi relatif dari konsep-konsep tertentu berarti bahwa konsep-konsep tersebut cenderung diekspresikan lebih mudah atau sama sekali, dan bahwa solusi yang tepat tidak hanya mungkin tetapi sebenarnya diimplementasikan secara luas.

Perbarui 5

React + Performance =? artikel oleh Paul Lewis dari Juli 2015 menunjukkan contoh di mana React lebih lambat daripada JavaScript vanilla yang ditulis tangan untuk daftar gambar Flickr yang tak terbatas, yang khususnya penting di ponsel. Contoh ini menunjukkan bahwa setiap orang harus selalu menguji kinerja untuk kasus penggunaan khusus dan platform serta perangkat target tertentu.

Terima kasih kepada Kevin Lozandier karena membawanya ke perhatian saya .

rsp
sumber
75
itulah yang saya sebut jawaban yang komprehensif, terima kasih!
Demwunz
14
Sepertinya Atom bergerak menjauh dari Bereaksi. Lihat github.com/atom/atom/issues/3677 .
Juho Vepsäläinen
6
@ash: Jika Anda membaca lebih lanjut di utas, mereka berbicara tentang bagaimana mereka ingin akhirnya benar-benar menjauh dari Bereaksi dan kerangka kerja lainnya, dan hanya roll sendiri menggunakan elemen kustom dan DOM bayangan.
musicfreak
3
Hanya untuk memperjelas kata-kata di atas, pada daftar @ErikAllik, FRP (Functional Reactive Programming) bukanlah bahasa baru melainkan pendekatan yang semakin populer. Faktanya, "Elm didasarkan pada gagasan Pemrograman Fungsional Reaktif" (dari elm-lang.org), dan seperti yang ia sebutkan, ada kerangka kerja FRP untuk Haskell, dll.
Jon Coombs
5
tl; tetap baca - brilian, jawaban terinci!
Mark K Cowan
16

Polimer itu luar biasa. Bereaksi luar biasa. Mereka bukan hal yang sama.

Polymer adalah perpustakaan untuk membangun komponen web yang kompatibel dengan mundur.

Bereaksi adalah V dalam MVC. Itu adalah View, dan tidak ada yang lain. Setidaknya tidak dengan sendirinya.

Bereaksi bukan kerangka kerja.

React + Flux + Node + (Gulp or Grunt) lebih sebanding dengan framework, tetapi 3 dari hal-hal itu bukan bagian dari reaksi sama sekali.

Ada banyak teknologi, pola, dan gaya arsitektur yang bereaksi diikuti oleh pengembang, tetapi bereaksi sendiri bukanlah suatu kerangka kerja.

Sangat menyedihkan bahwa tidak ada yang meluangkan waktu untuk mengatakan hal paling sederhana yang mungkin, bahwa mereka tidak boleh dibandingkan. Mereka memiliki beberapa tumpang tindih, tetapi mereka lebih berbeda daripada yang sama.

Keduanya memungkinkan Anda untuk mendefinisikan komponen web, tetapi dengan cara yang berbeda. Selain itu, mereka adalah alat yang sangat berbeda.

Robotsushi
sumber
Bukankah Bereaksi baik M dan V, bukan hanya V, karena ia memegang dan memperbarui status data dan membuat fragmen html melalui komponen?
abelito
1
Ada perpustakaan manajemen keadaan bereaksi seperti fluks atau reduks, tetapi ini tidak dikemas dengan reaksi.
Robotsushi
Oh saya mengerti, kami tidak menganggap data Tampilan sebagai data model .. sampai dikirim ke sisi server. Meskipun Bereaksi memegang status komponen (lihat data), tetap saja lihat data hingga pengiriman. Itu masuk akal.
abelito
15

Orang-orang Bereaksi memiliki penjelasan yang cukup bagus tentang perbandingan antara Bereaksi dan Komponen Web:

Mencoba untuk membandingkan dan membedakan Bereaksi dengan WebComponents pasti menghasilkan kesimpulan yang masuk akal, karena dua perpustakaan dibangun untuk memecahkan masalah yang berbeda. Komponen Web menyediakan enkapsulasi kuat untuk komponen yang dapat digunakan kembali, sementara Bereaksi menyediakan pustaka deklaratif yang menjaga DOM tetap sinkron dengan data Anda. Kedua tujuan tersebut saling melengkapi; insinyur dapat mencampur-dan-mencocokkan teknologi. Sebagai pengembang, Anda bebas menggunakan Bereaksi di komponen Web Anda, atau menggunakan komponen Web di Bereaksi, atau keduanya.

Erik Allik
sumber
14

Jawaban lain dalam satu hal khusus:

Tulis JavaScript dalam vanilla JavaScript, tulis CSS dalam CSS, tulis HTML dalam HTML.

Tidak ada yang mencegah Anda menulis Javascript di, katakanlah, CoffeeScript, TypeScript, ClojureScript atau apa pun. Ini murni masalah preferensi.

HTML adalah DSL terbaik untuk dokumen HTML statis . Tapi itu tidak memberikan apa pun untuk HTML dinamis. Dan di browser, bahasa terbaik untuk membuat HTML dinamis adalah Javascript, bukan HTML murni dengan manipulasi DOM Javascript ad-hoc atau bahasa templat seperti Setang yang bahkan bukan setengah bahasa.

Untuk CSS, jika CSS Anda statis, Anda menulis seperti biasa. Jika perlu dinamis berdasarkan beberapa nilai runtime, ini sama dengan HTML: Javascript adalah cara terbaik untuk membuatnya dinamis.

DjebbZ
sumber
1
Saya menghargai jawabannya, tetapi itu sebenarnya bukan poin saya. Semoga suntingan saya membuat pertanyaan lebih jelas?
CletusW
1
Maaf tidak. Anda masih dapat menulis gaya Anda dalam bahasa gaya apa pun di file terpisah. Dan JSX Bereaksi membuatnya terlihat seperti Anda menggunakan bahasa markup.
DjebbZ
3
"Javascript adalah cara terbaik untuk membuat [CSS] dinamis" - hanya mengatakan itu sebenarnya tidak menjelaskan mengapa.
pilau
1
Nah, jika gaya / kelas perlu diubah sesuai dengan input pengguna atau aturan bisnis, cukup gunakan javascript untuk mengubahnya. Dalam vanilla js, Anda akan memanipulasi properti classList atau style dari simpul DOM. Dengan Bereaksi, Anda dapat mencapai tujuan yang sama dengan memanipulasi DOM Virtual. Apakah ini lebih jelas?
DjebbZ
2
Vjeux, kontributor utama React, baru-baru ini memberikan ceramah di mana ia mendorong konsep "CSS in JS" menggunakan React. Saya pikir ini menarik, Anda mungkin bersedia untuk melihat tentang apa itu: blog.vjeux.com/2014/javascript/react-css-in-js-nationjs.html
DjebbZ
6

Saya belum pernah menggunakan Komponen Web, tetapi sepertinya mereka meminta Anda untuk menambahkan logika mutasi yang dikodekan secara manual ke penangan acara.

cuplikan dari contoh Polimer:

 <script>
   Polymer({
     counterChanged: function() {
       this.$.counterVal.classList.add('highlight');
     },
 ...

Inti dari Bereaksi adalah untuk mengurangi kompleksitas dengan menghilangkan logika mutasi. Alih-alih, Anda secara naif meregenerasi DOM virtual dan biarkan algoritma React yang berbeda mencari tahu apa yang perlu diubah di DOM yang sebenarnya.

limscoder
sumber
5
Tidak yakin dari mana Anda mendapatkan contoh itu, tetapi Polymer juga mencegah mutasi DOM manual demi pengikatan data, termasuk untuk nama kelas .
CletusW
Ini adalah contoh dari tab "buat elemen" di halaman depan polymer-project.org .
limscoder
4
Wow kamu benar! Saya kira mereka hanya ingin contoh penemuan simpul otomatis. Namun, itu mungkin bukan yang terbaik untuk diberikan.
CletusW
6

Saya pikir kelemahan terbesar Bereaksi menurut saya adalah bahwa itu tidak didasarkan pada standar web. Bereaksi adalah alat yang sangat kuat saat ini, tetapi karena ia menghindari begitu banyak apa yang disediakan browser bila memungkinkan, keputusan yang tampaknya masuk akal sekarang kemungkinan tidak akan masuk akal dalam waktu beberapa tahun karena fasilitas bawaan peramban terus berlanjut. memperbaiki. Jadi saya ingin membicarakan hal itu dan bagaimana pengaruhnya terhadap beberapa aspek berbeda dari aplikasi web.

Performa

Orang-orang suka berargumen bahwa keuntungan React adalah bahwa itu sepenuhnya menciptakan kembali seluruh DOM dan model acara, dan DOM standar yang ada adalah berat dan mahal dan apa-tidak, tetapi pada akhirnya saya belum menemukan kinerja dari Bereaksi untuk menjadi lebih baik daripada apa yang bisa saya dapatkan dari aplikasi Backbone atau Polymer yang ditulis dengan baik. Bahkan, dalam sebagian besar pengalaman profesional saya, kinerja React sebenarnya sedikit lebih buruk. Itu bukan untuk mengatakan React lambat ... Hanya saja bukan pilihan kinerja yang berdarah seperti yang kita semua pikirkan sebelum kita mendapatkannya.

Dalam jawaban rsp, ia menunjukkan bahwa model DOM React untuk div jauh lebih ringan daripada div DOM asli, dan itu memang benar. Namun, agar Bereaksi bermanfaat, div 'virtual' tersebut akhirnya harus menjadi div nyata. Jadi dalam pandangan duniaku, ini bukan masalah React div vs asli div. Ini adalah React div + a div asli vs hanya div asli. Overhead dari versi Dact dari DOM adalah non-sepele, dan jika standar pernah menjatuhkan beberapa atribut yang tidak dibutuhkan dan memungkinkan node DOM asli menjadi lebih ringan, tiba-tiba overhead itu akan tampak sangat mahal.

Di salah satu tempat kerja saya sebelumnya, kami memiliki beberapa aplikasi di Polymer, dan beberapa aplikasi di React. Salah satu aplikasi Polimer awal akhirnya ditulis ulang dalam React karena itulah yang menjadi standar perusahaan, dan berdasarkan pengukuran saya mengambil versi Bereaksi dari aplikasi yang sama ini berakhir dengan menggunakan sekitar 30% lebih banyak memori daripada versi Polymer , dan meskipun perbedaannya kecil, versi Polymer diterjemahkan dalam waktu yang lebih singkat juga. Satu hal yang perlu dipertimbangkan di sini adalah bahwa kita berbicara tentang aplikasi yang ditulis oleh orang-orang, dan orang-orang tidak sempurna, jadi mungkin saja implementasi Bereaksi dari aplikasi ini tidak mengambil keuntungan dari semua yang mampu dilakukan oleh React. Tapi saya pikir setidaknya sebagian ada hubungannya dengan overhead Bereaksi menimbulkan memiliki versi DOM sendiri.

Bereaksi ulang menciptakan seluruh DOM menggunakan model sendiri dan kemudian menggunakannya untuk optimasi kinerja utama. Suatu tampilan akan dirender menjadi DOM virtual, dan itu akan diproyeksikan ke DOM nyata. Ketika ada perubahan dan tampilan harus diperbarui, tampilan baru akan dirender kembali menjadi DOM virtual lagi, dan pohon itu berbeda terhadap pohon sebelumnya untuk menentukan node apa yang harus diubah dalam DOM nyata untuk mencerminkan perubahan ini dalam tampilan. Walaupun ini adalah pendekatan yang sangat pintar untuk membuat pembaruan DOM yang efisien, ada kelebihan dalam memelihara semua pohon DOM virtual ini dan membedakannya untuk menentukan apa yang harus diubah di DOM yang sebenarnya. Saat ini, overhead ini sangat diimbangi oleh manfaat kinerja, tetapi karena DOM asli semakin meningkat dari waktu ke waktu, skala akan bergeser ke arah lain. Saya khawatir tentang bagaimana Bereaksi aplikasi mungkin menua, dan jika dalam 3 tahun mereka akan jauh lebih lambat daripada hal-hal yang berhubungan dengan DOM secara langsung. Pendekatan DOM virtual ini sedikit palu godam, dan perpustakaan lain seperti Polymer telah mampu menerapkan pendekatan yang sangat efisien untuk menangani DOM dengan cara yang jauh lebih halus.

Pembaruan untuk kinerja: Salah satu perpustakaan yang saya temui beberapa waktu lalu melakukan apa yang saya pikir merupakan pekerjaan yang lebih baik dalam mengelola pembaruan untuk DOM. Ini perpustakaan Google Incremental Dom, dan saya pikir fakta bahwa ia bekerja dengan dom di tempat dan tidak harus membuat 'salinan virtual' adalah pendekatan yang jauh lebih bersih, dengan overhead memori yang jauh lebih sedikit. Lihat lebih lanjut di sini: http://google.github.io/incremental-dom/#about

Komponen deklaratif vs imperatif

Salah satu hal yang selalu Anda dengar muncul ketika Anda berbicara tentang komponen aplikasi Anda adalah semua manfaat komponen Anda menjadi deklaratif. Di dalam pandangan dunia React, semuanya baik dan deklaratif. Anda menulis JavaScript yang mengembalikan markup dan Bereaksi menempelkan semuanya untuk Anda. Dan itu hebat jika Anda berurusan dengan aplikasi baru yang hanya menggunakan Bereaksi dan tidak ada yang lain. Anda dapat menulis beberapa komponen dan selama Anda berada di bagian Dact milik DOM, itu semudah menempatkan tag itu pada halaman untuk mengkonsumsi komponen Anda.

Tetapi begitu Anda pergi untuk mengambil komponen-komponen itu dan menggunakannya di luar React, banyak hal menjadi lebih berantakan. Karena cara komponen React dibuat menjadi tag benar-benar di luar apa yang disediakan oleh standar web, tidak lain dari React yang tahu cara memberi Anda cara deklaratif untuk mengonsumsi komponen ini. Jika saya ingin meletakkan komponen Bereaksi menjadi tampilan Backbone yang sudah ada yang menggunakan templat Handlebars, Anda harus merender dummy div di templat Anda dengan kelas atau ID yang dapat Anda gunakan sebagai pegangan, kemudian menulis JavaScript penting untuk menemukan div dummy itu dan mount komponen Anda ke dalamnya. Punya aplikasi Express.js yang menggunakan templat sisi server? Ya itu lagu dan tarian yang sama. Halaman JSP? Anda tertawa, tetapi ada banyak aplikasi yang masih menggunakannya. Kecuali jika Anda adalah jenis startup tanpa kode yang ada, Anda Anda harus menulis beberapa pipa ledeng untuk menggunakan kembali komponen Bereaksi Anda di banyak aplikasi. Sementara itu, Polymer mencapai komponen melalui standar Komponen Web, dan dengan menggunakan spesifikasi Elemen Kustom, Polimer dapat membuat komponen yang oleh peramban baru saja tahu cara mengonsumsinya. Saya bisa memasukkan komponen Polimer ke dalam halaman JSP, template Express.js, tampilan ASP.NET, tampilan Backbone ... di dalam komponen React sekalipun. Secara harfiah di mana saja Anda dapat menggunakan HTML, Anda dapat menggunakan komponen Polymer. Orang yang direkayasa untuk digunakan kembali mencari standar web, karena standar adalah kontrak yang membuatnya mudah untuk membuat hal-hal yang kompatibel satu sama lain. YouTube terus mengarang semakin banyak hal dalam Polymer (sumber: Polimer mencapai komponen melalui standar Komponen Web, dan dengan menggunakan spesifikasi Elemen Kustom, Polimer dapat membuat komponen yang oleh peramban baru saja tahu cara mengonsumsinya. Saya bisa memasukkan komponen Polimer ke dalam halaman JSP, template Express.js, tampilan ASP.NET, tampilan Backbone ... di dalam komponen React sekalipun. Secara harfiah di mana saja Anda dapat menggunakan HTML, Anda dapat menggunakan komponen Polymer. Orang yang direkayasa untuk digunakan kembali mencari standar web, karena standar adalah kontrak yang membuatnya mudah untuk membuat hal-hal yang kompatibel satu sama lain. YouTube terus mengarang semakin banyak hal dalam Polymer (sumber: Polimer mencapai komponen melalui standar Komponen Web, dan dengan menggunakan spesifikasi Elemen Kustom, Polimer dapat membuat komponen yang oleh peramban baru saja tahu cara mengonsumsinya. Saya bisa memasukkan komponen Polimer ke dalam halaman JSP, template Express.js, tampilan ASP.NET, tampilan Backbone ... di dalam komponen React sekalipun. Secara harfiah di mana saja Anda dapat menggunakan HTML, Anda dapat menggunakan komponen Polymer. Orang yang direkayasa untuk digunakan kembali mencari standar web, karena standar adalah kontrak yang membuatnya mudah untuk membuat hal-hal yang kompatibel satu sama lain. YouTube terus mengarang semakin banyak hal dalam Polymer (sumber: Saya bisa memasukkan komponen Polimer ke dalam halaman JSP, template Express.js, tampilan ASP.NET, tampilan Backbone ... di dalam komponen React sekalipun. Secara harfiah di mana saja Anda dapat menggunakan HTML, Anda dapat menggunakan komponen Polymer. Orang yang direkayasa untuk digunakan kembali mencari standar web, karena standar adalah kontrak yang membuatnya mudah untuk membuat hal-hal yang kompatibel satu sama lain. YouTube terus mengarang semakin banyak hal dalam Polymer (sumber: Saya bisa memasukkan komponen Polimer ke dalam halaman JSP, template Express.js, tampilan ASP.NET, tampilan Backbone ... di dalam komponen React sekalipun. Secara harfiah di mana saja Anda dapat menggunakan HTML, Anda dapat menggunakan komponen Polymer. Orang yang direkayasa untuk digunakan kembali mencari standar web, karena standar adalah kontrak yang membuatnya mudah untuk membuat hal-hal yang kompatibel satu sama lain. YouTube terus mengarang semakin banyak hal dalam Polymer (sumber:http://react-etc.net/entry/youtube-is-being-rebuilt-on-web-components-and-polymer ), dan saya hanya bisa membayangkan aspek berbasis standar dari Polymer adalah alasan mengapa. Pemutar YouTube yang berada di tengah-tengah laman YouTube dapat diubah menjadi komponen yang mengambil sumber konten sebagai properti, dan tiba-tiba siapa saja yang ingin menyematkan pemutar YouTube ke laman mereka benar-benar dapat menggunakan kode pemain yang persis sama dengan yang digunakan YouTube , dan mereka dapat melakukannya hanya dengan menempelkan tag ke halaman mereka.

Ringkasan

Saya bisa melihat pasti ada beberapa aspek menarik dari Bereaksi sekarang. Jika semua yang Anda gunakan adalah Bereaksi, Anda dapat membangun beberapa widget dan beberapa komponen dan secara deklaratif menggunakannya kembali di semua tempat. Tapi saya pikir React akan jauh lebih baik jika ia akan menggunakan beberapa standar Komponen Web untuk mencapai apa yang dilakukannya, daripada pergi dan membangun browser di dalam browser dan mekanisme kompleks untuk menjaga semuanya tetap sinkron.

Anjing
sumber