LiveView Paling Cocok dengan Svelte
(blog.sequin.io)- Tim Sequin mencoba baik React SPA maupun Phoenix LiveView murni, lalu menyimpulkan bahwa pendekatan paling produktif adalah menggabungkan LiveView dan Svelte dengan LiveSvelte
- LiveView dapat membuat UI kaya tanpa SPA melalui status server dan pembaruan DOM inkremental, tetapi saat status klien dibutuhkan, modul JS, hook, dan status LiveView mulai bercampur sehingga batasnya menjadi kabur
- Dalam LiveView murni, LiveView, LiveComponent, dan Component memiliki siklus hidup, cara meneruskan props, dan metode komunikasi yang berbeda, sehingga refactoring dan penempatan status lebih merepotkan dibanding React
- LiveSvelte menyediakan batas dua arah yang jelas: Elixir menurunkan props dan Svelte mengirim event ke atas melalui
live.pushEvent - Dalam kombinasi ini, routing, logika bisnis, dan persiapan data tetap di server, sementara status UI, animasi, dan conditional rendering ditangani oleh Svelte sehingga kompleksitas SPA bisa dikurangi
Model pengembangan yang disediakan LiveView
- Aplikasi server-rendering tradisional membuat server tidak menyimpan status, dan merender halaman untuk setiap permintaan klien
- SPA menyerahkan penyusunan halaman ke klien, membaca dan menulis data melalui API backend, serta mengelola status klien dengan pendekatan seperti
useStatedi React - LiveView tetap membuat server menangani rendering halaman sambil mempertahankan status, lalu memproses aksi frontend dan memperbarui DOM secara inkremental seperti SPA
- Kompleksitas SPA membesar karena aplikasi JS di klien pada praktiknya bertindak seperti sebuah microservice frontend
- Route dan controller backend bertambah karena kebutuhan khusus frontend
- Satu permintaan bisa melewati
onMount, pemanggilan API, parsing respons, router, auth plug, controller, fungsi domain, dan lapisan persiapan respons
- Keunggulan LiveView adalah dapat menghadirkan pengalaman klien yang kaya tanpa microservice frontend
- Query database bisa dilakukan dekat dengan fungsi rendering tabel
- Saat baris baru masuk, baris itu bisa di-push ke tabel dan LiveView akan memperbarui klien
- Ini memungkinkan interaksi yang lebih dekat ke framework frontend stateful dibanding pendekatan server-rendering lama yang membangun ulang seluruh status pada tiap request
Gesekan yang ditemui di LiveView murni
-
Status sisi klien tidak bisa benar-benar dihindari
- LiveView tidak bisa menghindari latensi bolak-balik antara server dan pengguna
- Animasi, tooltip, tampil/sembunyi DOM, atau menonaktifkan field formulir kadang harus ditangani di klien
- Pada formulir dengan dua dropdown yang saling bergantung, UX yang baik mengharuskan dropdown kedua langsung dinonaktifkan setelah pilihan di dropdown pertama berubah, lalu diaktifkan kembali setelah server mengisi daftar baru
- Untuk menerapkan perilaku ini hanya dengan LiveView, beberapa konsep perlu dipakai bersama
- JS module milik LiveView dipakai untuk menonaktifkan dropdown kedua saat dropdown pertama berubah
- hook dipakai untuk mendaftarkan event listener pada dropdown kedua dan menerima aksi pengaktifan kembali dari backend
- Jika pengaktifan kembali bersifat kondisional, status LiveView juga bisa ikut terlibat
- Saat JS, hook, dan status LiveView dipakai bersama, sebagian status DOM berada di luar LiveView sehingga sulit menemukan pola yang konsisten
-
Batas status yang berbeda dari React
- React menangani sebagian besar transisi dengan konsep inti status dan aksi, sehingga batas antara status DOM dan status komponen relatif jelas
- Karena tidak ada latensi antara aksi klien dan status klien, React bisa memperlakukan aksi dan transisi dengan paradigma status
- Status LiveView berada di sisi server, jadi latensi antara aksi klien dan status server harus diperhitungkan
- Pada contoh field input, React melewati jalur status sebelum karakter diketik, dan komponen dirender ulang pada setiap penekanan tombol
- LiveView lebih dekat ke model di mana pengguna lebih dulu mengubah field input, lalu beberapa saat kemudian status server mengetahuinya dan bereaksi
- Jika latensi nyaris nol, perilakunya terlihat seperti React, tetapi makin besar latensinya makin jelas perbedaan kedua model tersebut
Kompleksitas yang diciptakan oleh tiga jenis komponen
- LiveView memiliki tiga jenis komponen: LiveViews, LiveComponents, dan Components
- LiveViews dan LiveComponents lebih mirip komponen stateful di React, sedangkan Components lebih mirip komponen fungsional
- LiveView selalu menjadi komponen induk tingkat atas, dan di bawahnya dirender LiveComponents serta Components
- Di React, cukup menambah atau menghapus hook
useStateuntuk berpindah dengan mudah antara komponen stateful dan komponen fungsional- Keduanya menerima props dengan cara yang sama
- Selain status, set fitur keduanya sama
- Pendaftaran event DOM dan cara meresponsnya juga sama
- Di LiveView, perbedaan antar tiga jenis komponen ini cukup besar sehingga merefaktor LiveView menjadi LiveComponent terasa merepotkan
- LiveViews dan LiveComponents memakai sintaks rendering dan penerusan props yang berbeda
- Siklus hidupnya berbeda
- Opsi komunikasinya berbeda: LiveViews memakai
send, sedangkan LiveComponents memakaisend_update - LiveComponents bukan proses, jadi tidak bisa berinteraksi dengan bagian lain sistem seperti LiveViews
Batasan LiveComponent
- LiveView adalah sebuah proses Elixir, sehingga memiliki
pid, status, inbox, dan bisa bertindak seperti proses lain dalam sistem Elixir/OTP - Di LiveView, pub/sub bisa dipakai untuk berlangganan perubahan di seluruh sistem
- LiveComponent bukan proses tersendiri, melainkan modul yang dipanggil oleh LiveView
- Karena proses LiveView induk memegang status komponen turunannya, LiveView juga harus menangani routing pesan untuk child LiveComponents
- Agar LiveComponents memiliki kemampuan mandiri untuk mengelola status dan menangani aksi, masing-masing harus berupa proses, tetapi model saat ini bukan seperti itu
- Dalam pengembangan nyata, sering kali tidak ada cara yang baik untuk mengirim event atau aksi ke LiveComponent, dan menjadi tidak jelas apakah
send_updateseharusnya dipakai untuk mengirim aksi atau menambal status- Jika dipakai untuk menambal status, maka perlu dipikirkan juga bagaimana membedakan mount dan update di dalam klausa
update
- Jika dipakai untuk menambal status, maka perlu dipikirkan juga bagaimana membedakan mount dan update di dalam klausa
Batas yang dibentuk LiveSvelte
- LiveSvelte memungkinkan komponen Svelte dirender di dalam LiveView
- Di dalam
renderLiveView, struktur data Elixir bisa di-encode menjadi plain map untuk frontend lalu diteruskan sebagai props ke komponen Svelte - Komponen Svelte menerima props dengan
export let, dan berkomunikasi dengan LiveView melalui propliveyang disediakan LiveSvelte - Di sisi Svelte, event bisa dikirim ke server melalui
live.pushEvent- Dalam contoh, reactive block Svelte mengirim event
"form_updated"ke server saatformberubah - LiveView mendekode parameter frontend di
handle_event("form_updated", ...)lalu memperbarui changeset - Error validasi changeset lalu dikirim kembali ke frontend melalui prop
errors
- Dalam contoh, reactive block Svelte mengirim event
- Data diturunkan dari Elixir ke Svelte sebagai props, dan dari Svelte dinaikkan ke LiveView sebagai event websocket
- Proses LiveView dapat memperbarui props kapan saja untuk memicu render ulang komponen Svelte
Sifat inti kombinasi LiveView dan Svelte
- Inti dari kombinasi ini adalah proses backend stateful dan komponen frontend stateful bekerja bersama
- Ada tiga sifat yang menopang kombinasi ini
- Backend mengendalikan props komponen frontend
- Frontend dan backend sama-sama memiliki status
- Keduanya memiliki saluran komunikasi dua arah privat yang memungkinkan masing-masing pihak memulai pesan
- Sifat pertama dimungkinkan oleh cara rendering LiveView
- Hasil render ulang server otomatis di-push ke klien dan diterapkan
- Server dapat memperbarui props komponen seperti komponen induk JS
- Sifat kedua berasal dari fakta bahwa LiveView adalah proses Elixir
- Proses Elixir adalah cara untuk mengenkapsulasi status
- Sifat ketiga dimungkinkan oleh koneksi websocket berkelanjutan yang disediakan LiveView
Perbedaannya dengan SPA
- Routing di browser seluruhnya dilakukan di backend sehingga strukturnya lebih sederhana
- Pada SPA biasa, perlu memelihara dua jenis route: route browser dan route API
- Backend memiliki status dan mengetahui route saat ini serta resource yang sedang dikerjakan
- Setiap aksi bisa diproses sebagai perubahan status backend sendiri, alih-alih membangun ulang seluruh status dari awal
- Komunikasi frontend dan backend bersifat privat dan saling terikat
- Tidak perlu menambah route publik server untuk pemanggilan RPC yang hanya mendukung satu komponen
- Saat melihat
pushEventdi klien, kita tahu handler terkait berada di modul Elixir yang berkolaborasi dengannya
- Fitur biasanya terbagi terutama ke dalam dua file
- Modul backend memanggil fungsi backend seperti query database
- Frontend mengimpor komponen dan style
- Alur bolak-balik frontend/backend tidak melewati modul API, router, atau stack controller
- Prosedur komunikasinya juga berkurang
- Backend cukup memberi tahu perubahan frontend melalui pembaruan props
- Frontend bisa mengirim
pushEventtanpa token kedaluwarsa, timeout, atau handler penanganan gangguan - Jika websocket terbuka, berarti server berjalan; jika tertutup, LiveView menampilkan banner global “disconnected”
Pemisahan tanggung jawab dan struktur kode
- Dalam struktur ini, efeknya seperti microservice frontend dihilangkan
- Logika bisnis ditempatkan di backend
- Cara memuat data
- Data apa yang harus dimuat
- Cara pengurutan dan pemfilteran
- Validator
- Kode frontend Svelte menjadi lebih sederhana
- Blok
if/enduntuk conditional rendering - Animasi
- Fungsi
pushEventsederhana untuk mengirim ke server
- Blok
- Pada frontend SPA biasa, sering muncul banyak logika
map,reduce, danfilteruntuk memproses data server, menyiapkan data untuk ditampilkan, dan menyiapkan data untuk dikirim kembali ke server - Di aplikasi LiveSvelte, pemrosesan seperti ini bisa dilakukan di sisi server
- LiveView menyiapkan data dalam bentuk yang dibutuhkan komponen Svelte
- Kompleksitas tetap berada di bahasa server, struktur data server, dan suite pengujian server
- LiveView dan komponen Svelte bukan dua elemen yang hanya terhubung longgar, melainkan lebih seperti dua bagian dari satu fitur
- LiveView hanya merender komponen Svelte tersebut
- Komponen Svelte itu juga hanya dirender oleh LiveView tersebut
Yang berubah dibanding LiveView murni
- Pendekatan LiveSvelte menerima keberadaan status frontend dan transisi status
- Lapisan batas antara frontend dan backend menjadi lebih jelas
- Paradigma komponen matang milik Svelte bisa dimanfaatkan
- Ekosistem framework JavaScript yang sulit dijangkau dengan LiveView murni juga bisa digunakan
- Svelte menyediakan primitive animasi
- Dengan memindahkan lebih banyak tanggung jawab ke frontend, rasa serba tanggung di area tengah yang canggung berkurang
Alasan memilih Svelte dan posisi LiveView
- Alasan memilih LiveSvelte adalah karena belum ada library LiveView untuk React yang punya tingkat kematangan serupa
- Svelte dinilai sebagai framework frontend yang ringan dan cepat dalam hal status dasar dan reaktivitas
- Karena LiveView menangani porsi besar manajemen status, pengelolaan status di sisi Svelte tetap sederhana
- Fitur template Svelte juga lebih disukai daripada React
- Bisa memakai
if/elsealih-alih operator ternary - Bisa memakai pengaturan atribut kondisional
- Bisa memakai
- runes di Svelte 5 diharapkan membuat Svelte lebih mudah dipelajari dan lebih mudah dipahami
- LiveView paling bersinar sebagai backend-for-frontend yang merender komponen frontend, melakukan pembaruan inkremental, mempertahankan proses backend stateful, dan menyediakan API websocket
1 komentar
Komentar Hacker News
Pola yang sering dipakai di game multipemain pada dasarnya adalah menjalankan kode yang sama di sisi klien dan server
Kode klien berjalan lebih dulu dengan memprediksi state server, lalu ketika state server tiba, state klien ditimpa
Dalam game, klien bisa menebak hasil inputnya sendiri dengan cukup baik tetapi tidak tahu input pemain lain, jadi istilah “prediksi” memang cocok
Namun cara ini juga bisa dipakai untuk memberi respons langsung sambil menunggu state server resmi, seperti mengaktifkan/menonaktifkan dropdown atau menampilkan loading spinner
Ada juga banyak state klien yang tidak perlu dijalankan di server sama sekali, seperti sistem partikel atau ragdoll, dan jika ada koneksi server yang terus-menerus, tampaknya tidak ada alasan ini tidak bisa dilakukan dalam paradigma reaktif
Itu adalah klon dari https://generals.io/ dan dibuat dengan LiveSvelte
Pada dasarnya ini board game dan hanya 2 tick per detik, jadi fitur prediksi tidak diperlukan, tetapi saya memakai optimistic update yang menampilkan state game terlebih dahulu sebelum update dari server
Jika tidak sinkron dengan server, server akan menimpa state game
Semua logika game ada di Elixir, dan untuk melakukan prediksi dengan benar, server dan klien harus berbagi logika
Kalau tidak, logikanya harus ditulis dua kali, dan itu jalan menuju bencana
Saya belum menyelidikinya, tetapi solusi yang mungkin adalah menulis semua logika game dengan gleam(https://gleam.run/)
Gleam kompatibel dengan Elixir dan juga bisa dikompilasi ke JavaScript, jadi secara teori kode yang sama bisa dijalankan di server dan klien
Namun jika ada yang berkata “ya tulis saja semuanya dengan js”, itu juga cukup benar, dan saya mungkin akan setuju
Meski begitu, keuntungan yang didapat adalah bisa memakai BEAM dan fitur-fitur yang bagus untuk sistem terdistribusi real-time, yang sangat cocok untuk game multipemain kecuali bagian frontend-nya
Ketika seseorang mati lalu mayatnya terpental atau tersangkut dalam pose lucu, tidak ada orang lain yang bisa melihatnya, dan di replay pun tiap klien merendernya berbeda sehingga tidak bisa ditonton ulang
Jika tidak tertangkap lewat rekaman real-time, momen itu hilang selamanya
Untuk game yang kadang konyol seperti Overwatch, sayang sekali tidak ada yang bisa melihatnya bersama
https://arstechnica.com/gaming/2019/10/explaining-how-fighti... adalah penjelasan yang bagus, dan diskusi terkait ada di https://news.ycombinator.com/item?id=34399790 serta https://news.ycombinator.com/item?id=26289933
Jika ada persistensi server seperti MMO, bottleneck I/O juga harus ikut dipertimbangkan
https://prdeving.wordpress.com/2023/09/29/mmo-architecture-s... adalah tulisan yang menarik dari sudut pandang itu, dan diskusinya ada di https://news.ycombinator.com/item?id=37702632
Misalnya, sebuah form live/interaktif mungkin tampak berjalan baik sambil memperbarui data turunan di halaman, tetapi akan merepotkan jika nanti semuanya dikembalikan karena error server atau masalah jaringan
Lebih buruk lagi, pengguna bisa saja menutup halaman atau berpindah tanpa mengetahui hal itu
Saya suka kombinasi LiveView + Svelte
Saya mempresentasikan cara menggabungkan keduanya di ElixirConf 2022, tetapi para kontributor live_svelte-lah yang membuatnya benar-benar bisa dipakai
Menurut saya, aplikasi dengan pengalaman pengguna yang kaya selalu membutuhkan state di sisi klien
Terutama jika tinggal di New York, koneksi jaringan saat bepergian bukan sesuatu yang bisa dianggap pasti
Salah satu fitur kuat yang tidak dibahas dalam tulisan ini adalah bahwa dengan pubsub Phoenix, perubahan state sisi server yang terjadi di server lain juga bisa didorong secara reaktif ke semua klien
Untuk menangani trafik menengah ke atas, cukup umum menjalankan beberapa web server
Jika ingin pengalaman pengguna seperti LiveView tetapi tetap tahan terhadap jaringan yang tidak stabil, saya menambahkan binding Svelte 5 ke Triplit[1]
Anda bisa menulis query di sisi klien dan menyinkronkannya dengan server melalui websocket
Bagi developer Elixir mungkin tidak terlalu menarik, tetapi jika Svelte menjadi pusatnya, Triplit adalah pilihan yang bagus
[1] https://www.triplit.dev/docs/frameworks/svelte
Saat baris baru masuk, pendekatan yang sekadar mendorongnya ke tabel dan membiarkan LiveView memperbarui klien sebaiknya dihindari pada aplikasi bisnis yang baris-barisnya bisa diinteraksikan
Karena latensi kognitif, pengguna mudah mengklik item yang salah, mengirim email ke pelanggan yang salah, atau mengembalikan dana untuk transaksi yang salah
Pengalaman pengguna yang lebih disukai adalah banner tetap seperti “Data telah berubah. Klik di sini untuk memuat ulang”
Jika mendesak, baris baru harus dirender hanya sebagai tambahan dan posisi scroll tidak boleh berubah
Di BeaconCMS, Svelte dan LiveView dipakai bersama
Jelas ada use case yang baik ketika UI di klien perlu dikendalikan lebih halus, tetapi tim sebaiknya berhati-hati untuk mengadopsi Svelte + LiveView secara menyeluruh untuk segala hal
Di Phoenix pun LiveView tidak selalu menjadi jawaban, dan kadang halaman render biasa sudah cukup
Jangan memilih semuanya sebagai serba ada atau tidak sama sekali
Seperti yang dikatakan tulisan itu, ada use case yang baik untuk keluar dari “cara LiveView”
Jika waktu round trip 1.000 ms, memang perlu mempertimbangkan hal lain, tetapi ada juga tim yang tidak bisa menempatkan server yang dekat secara geografis karena alasan seperti biaya, sehingga manajemen state di sisi klien bisa menjadi solusi
Maksudnya, alih-alih mengelola state klien, akan mengelola state di klien dan server sekaligus?
Walau ada kelebihan karena tidak perlu membuat API lain, itu tidak terlihat seperti perbaikan
Selalu ada state yang harus dilacak klien dan state yang harus dilacak server, lalu di atasnya ada state sementara yang cukup berada di memori dan state yang harus dipertahankan antar-sesi
Cara mengelolanya nyaris tak terbatas, dan di JavaScript, karena “apa pun yang dilakukan tidak ada jawaban benar”, akhirnya orang memakai cara yang ditentukan framework atau solusi tambal sulam, alias kekacauan
Pada aplikasi single-page kompleks terakhir yang pernah saya kerjakan, klien dibuat melakukan sinkronisasi setiap kali halaman dimuat
Semua state atau aset lokal diberi hash berbasis tanggal, dan jika berbeda dari nilai di server, server mengirimkan versi yang diperbarui
Itu berlaku sama saja baik untuk variabel sederhana, objek JSON besar, maupun seluruh blob gambar/audio
Jika klien melakukan sesuatu yang membutuhkan perubahan state server, ia mengirim pembaruan state itu lewat WebSocket, dan 99% aplikasi berbasis WebSocket
Tidak memakai framework atau pola khusus; saat menulis kode lalu merasa “ini harus dilacak server”, state baru dikirim sebagai pesan ke server, dan server yang memutuskan apakah perlu disinkronkan saat halaman dimuat
Untuk jenis manajemen state seperti ini, menurut saya mekanisme ini hampir yang paling sederhana
WebSocket benar-benar sangat membantu dalam manajemen state
Aplikasi nyata membutuhkan state di klien maupun server
Server tidak bisa mempercayai klien, jadi harus memiliki state otoritatif, tetapi klien juga harus bisa merender ulang sebagai respons terhadap interaksi pengguna tanpa round trip
Jangan lakukan semuanya begitu; gunakan hanya saat masuk akal
Hal lain yang saya suka adalah bisa memakai Svelte sebagai bahasa template alih-alih Heex
Jika tidak diperlukan, tidak ada alasan melakukannya; alasan hal itu menjadi perlu adalah performa dan pengalaman pengguna
Jika aplikasi web memiliki banyak interaksi pengguna sehingga membutuhkan JavaScript klien, dan banyak eksperimen sehingga bundle berbeda pada tiap request, orang akan ingin membagi logika antara server dan klien untuk mengurangi jumlah JavaScript yang dikirim ke klien
Kalau tidak, aplikasi akan memiliki bundle JavaScript berukuran MB yang berisi semua kemungkinan kasus yang mungkin ditemui aplikasi
Untuk aplikasi seperti versi web Photoshop, yang penggunanya memahami waktu muat awal, itu mungkin tidak masalah; tetapi pada aplikasi seperti Stripe atau Gmail yang diharapkan langsung dimuat, orang ingin mengurangi jeda awal halaman
Semuanya juga bisa dipindahkan ke server, tetapi seperti yang dialami GitHub, interaktivitas halaman memburuk ketika tindakan pengguna yang harus merespons seketika membutuhkan round trip ke server
Maka kecepatan cahaya dan distribusi server menjadi masalah
Bundle juga bisa dimuat tertunda dengan async import dan semacamnya, tetapi JavaScript yang dimuat tertunda kemudian mengirim request lagi untuk mengambil datanya sendiri, sehingga muncul masalah waterfall
Saat semua masalah ini ditemui, pada akhirnya orang akan mencari solusi yang memudahkan masalah rumit berupa berbagi logika/state antara klien dan server
Pendekatan ini punya batas kecepatan cahaya secara harfiah, yaitu “ada batas seberapa dekat server bisa berada dari pengguna”
Langkah berikutnya adalah mengompilasi server ke WebAssembly dan mengirimkannya ke klien
Dengan begitu, respons dapat dirender secara optimistis sambil menunggu respons server yang sebenarnya
Kedengarannya agak gila, tetapi saya pernah melakukannya di proyek nyata dan rasanya seperti sihir
Menjalankan server di klien pun tidak menyelesaikannya, dan pada akhirnya latensi jaringan untuk persistensi tetap ada
State server yang pada akhirnya harus menang juga adalah persistensi itu
Banyak overengineering memang sering diimplementasikan meski tanpa alasan khusus
Saya membuat LiveSvelte, jadi kalau ada yang ingin ditanyakan silakan beri tahu
Secara umum, saya selalu ingin membuat aplikasi dengan model seperti ini
Berorientasi event, pembaruan real-time dua arah dengan server, event yang berurutan, serta state lokal/remote
Saya tidak tahu LiveView dan belum pernah memakai bahasa keluarga Erlang, tetapi jelas rasanya mereka menangkap sesuatu yang penting
Model request-response tradisional secara halus dan cukup sering menimbulkan masalah konsistensi dan data usang
Jika 10 tahun terakhir adalah masa mengintegrasikan konsep pemrograman fungsional ke bahasa arus utama, saya berharap 10 tahun berikutnya mengarah pada pengintegrasian pemrograman berorientasi pesan yang memiliki state ke full-stack arus utama
Sebagai catatan, tiga yang pertama saya buat atau saya bantu pembuatannya
Jika mengikuti panduan sambil sedikit mencoba-coba, dalam kira-kira dua jam Anda seharusnya bisa menjalankan aplikasi chat Phoenix dasar di browser
Ini solusi yang bagus
Di aplikasi saya, saya memakai controller Stimulus yang reusable bersama LiveView, dan ini juga berjalan mulus
Secara keseluruhan, pengembangan dengan LiveView itu menyenangkan, tetapi semakin sering saya memakainya dalam skenario nyata, semakin terasa juga keunggulan framework HTTP stateless seperti Hotwire
Rasanya lebih berkinerja, lebih tangguh saat reconnect, dan mengurangi kebutuhan menempatkan lebih banyak server dekat dengan pengguna demi stabilitas
Namun Stimulus tidak menyediakan cara elegan untuk mempertahankan state di klien
Pendekatannya seperti “state aplikasi Stimulus berada sebagai atribut di DOM”, jadi tidak lebih baik dari vanilla JS atau jQuery
Saya memang belum pernah memakai Stimulus di proyek nyata, jadi ada kemungkinan value dan callback perubahannya memberikan pengalaman yang lebih baik daripada dugaan awal
Kombinasi ini punya tingkat kompleksitas yang pas, sementara Svelte saat dipakai bersama LiveView terasa menangani banyak hal yang sejak awal bukan masalah
Yang dibutuhkan adalah vanilla JS atau lapisan tipis di atasnya, bukan framework penuh
Toh tidak perlu banyak memakai JavaScript
JS di aplikasi produksi saya tidak sampai 200 baris, dan beberapa controller Stimulus sepertinya juga bisa dihapus
LiveView sebagus itu
Saya juga membuat adapter hook Stimulus-LiveView yang sangat hacky, sehingga controller Stimulus bisa mengirim event langsung ke proses LiveView
Dan LiveView, kecuali kalau terlalu banyak menenggak Kool-Aid ala fly.io, tidak benar-benar membutuhkan server yang terdistribusi secara geografis
Putus koneksi juga ditangani dengan sangat baik
Saya juga tidak melakukan apa pun secara khusus untuk mendukung update tanpa downtime
Seluruh proses ketika klien kehilangan koneksi WebSocket, reconnect ke versi baru, lalu memulihkan state ditangani otomatis secara default
Mau minta apa lagi?
Perusahaan kami mendapat manfaat besar dengan memakai LiveView bersama Alpine, khususnya karena kami tidak bisa mengizinkan
evaldi klien sehingga memakai mode CSPSaat pertama melihat LiveSvelte, itu tampak sangat baru dan belum terlalu teruji, dan masih ada dampak yang belum terselesaikan di lingkungan CSP yang ketat
Sekarang saya senang melihatnya tampak cukup berguna
Pola kami kira-kira bisa disebut LiveAlpine
Jika komponen membutuhkan HTML, kami memakai HTML Component; jika ada state sisi server, kami memakai Live Component
Jika membutuhkan perilaku atau state sisi klien, kami juga mendefinisikan komponen Alpine
Jika perlu menerima event klien di server atau melakukan request HTTP, kami juga mendefinisikan Phoenix Hook