LiveView en çok Svelte ile uyumlu
(blog.sequin.io)- Sequin ekibi, hem React SPA hem de saf Phoenix LiveView kullandıktan sonra, LiveView ile Svelte’i LiveSvelte aracılığıyla birleştirmenin en üretken yaklaşım olduğuna karar verdi
- LiveView, sunucu durumu ve DOM artımlı güncellemeleri ile SPA olmadan zengin arayüzler oluşturabilir; ancak istemci durumunun gerektiği anlarda JS modülleri, hook’lar ve LiveView durumu birbirine karışır, sınırlar bulanıklaşır
- Saf LiveView’deki LiveView, LiveComponent, Component yapıları; yaşam döngüsü, props aktarımı ve iletişim biçimleri bakımından farklı olduğundan, yeniden düzenleme ve durumun nereye yerleştirileceği React’e kıyasla daha zahmetlidir
- LiveSvelte, Elixir’in props’u aşağı göndermesi ve Svelte’in
live.pushEventile olayları yukarı iletmesi sayesinde net bir çift yönlü sınır sağlar - Bu kombinasyonda routing, iş mantığı ve veri hazırlama sunucuda tutulurken; UI durumu, animasyonlar ve koşullu rendering Svelte’e bırakılarak SPA karmaşıklığı azaltılabilir
LiveView’ün sunduğu geliştirme modeli
- Geleneksel sunucu tarafı rendering uygulamalarında sunucu durum tutmaz ve her istemci isteğinde sayfayı render eder
- SPA’larda sayfanın oluşturulmasını istemci üstlenir; veriler backend API üzerinden okunup yazılır ve React’in
useStatebenzeri yöntemleriyle istemci durumu yönetilir - LiveView, sayfa rendering’ini sunucunun yapmaya devam etmesini sağlarken durumu korur; frontend aksiyonlarını işledikten sonra DOM’u SPA gibi artımlı olarak günceller
- SPA karmaşıklığı, istemci JS uygulamasının fiilen bir frontend mikroservisi gibi davranmasından büyür
- Frontend’e özgü gereksinimler yüzünden backend route’ları ve controller’ları artar
- Tek bir istek
onMount, API çağrısı, yanıt ayrıştırma, router, kimlik doğrulama plug’ı, controller, domain fonksiyonu ve yanıt hazırlama katmanlarından geçebilir
- LiveView’ün avantajı, frontend mikroservisi olmadan da zengin bir istemci deneyimi oluşturabilmesidir
- Tablo rendering fonksiyonunun yakınında veritabanı sorgulanabilir
- Yeni bir satır geldiğinde tabloya push edilir ve LiveView istemciyi günceller
- Her istekte tüm durumu yeniden kuran geleneksel sunucu rendering yaklaşımına kıyasla, stateful frontend framework’lerine daha yakın etkileşimler oluşturulabilir
Saf LiveView’de karşılaşılan sürtünmeler
-
İstemci tarafı durumundan kaçınılamaz
- LiveView, sunucu ile kullanıcı arasındaki gidiş-dönüş gecikmesini önleyemez
- Animasyon, tooltip, DOM öğelerini gösterme/gizleme, form alanını devre dışı bırakma gibi işler bazen istemcide ele alınmalıdır
- Birbirine bağımlı iki dropdown bulunan bir formda, iyi bir UX için ilk dropdown seçilir seçilmez ikinci dropdown hemen devre dışı bırakılmalı; sunucu yeni listeyi doldurduktan sonra yeniden etkinleştirilmelidir
- Bu davranışı yalnızca LiveView ile uygulamak için birden çok kavram birlikte gerekir
- İlk dropdown değiştiğinde ikinci dropdown’ı devre dışı bırakmak için LiveView’ün JS module yapısı kullanılır
- İkinci dropdown’a event listener kaydetmek ve backend’den yeniden etkinleştirme aksiyonu göndermek için hook kullanılır
- Koşullu olarak yeniden etkinleştirmek gerekiyorsa LiveView durumu da devreye girebilir
- JS, hook ve LiveView durumu birlikte kullanıldığında DOM durumunun bir kısmı LiveView dışında bulunur ve tutarlı bir pattern oluşturmak zorlaşır
-
React’ten farklı durum sınırları
- React, çoğu geçişi durum ve aksiyon gibi temel kavramlarla ele alır; DOM durumu ile bileşen durumu arasındaki sınır nispeten nettir
- İstemci aksiyonu ile istemci durumu arasında gecikme olmadığı için React, aksiyonları ve geçişleri durum paradigmasıyla ele alabilir
- LiveView’ün durumu sunucu tarafında olduğundan, istemci aksiyonu ile sunucu durumu arasındaki gecikme hesaba katılmalıdır
- Girdi alanı örneğinde React, karakter girilmeden önce durum yolundan geçer ve bileşen her tuş girişinde yeniden render edilir
- LiveView ise kullanıcının önce girdi alanını değiştirdiği, kısa bir süre sonra sunucu durumunun bundan haberdar olup tepki verdiği modele daha yakındır
- Gecikme neredeyse yoksa React gibi görünür; ancak gecikme arttıkça iki model arasındaki fark belirginleşir
Üç bileşen türünün yarattığı karmaşıklık
- LiveView’de LiveViews, LiveComponents, Components adlı üç bileşen türü vardır
- LiveViews ve LiveComponents, React’in stateful bileşenlerine; Components ise fonksiyonel bileşenlere daha yakındır
- LiveView her zaman en üst seviye ebeveyn bileşendir; altında LiveComponents ve Components render edilir
- React’te
useStatehook’unu ekleyip kaldırarak stateful bileşen ile fonksiyonel bileşen arasında kolayca gidip gelinebilir- İkisi de props’u aynı şekilde alır
- Durum hariç özellik setleri aynıdır
- DOM olaylarını kaydetme ve yanıtlama biçimleri de aynıdır
- LiveView’de üç bileşen türü arasındaki farklar büyük olduğundan, LiveView’ü LiveComponent’e refactor etmek zahmetlidir
- LiveViews ile LiveComponents’ın rendering ve props aktarım söz dizimi farklıdır
- Yaşam döngüleri farklıdır
- İletişim seçenekleri farklıdır; LiveViews için
send, LiveComponents içinsend_updatekullanılır - LiveComponents süreç olmadığı için LiveViews gibi sistemin diğer bölümleriyle etkileşime giremez
LiveComponent’in kısıtları
- LiveView bir Elixir süreci olduğundan
pid, durum ve inbox’a sahiptir; Elixir/OTP sistemindeki diğer süreçler gibi davranabilir - LiveView’de pub/sub kullanarak sistem genelindeki değişikliklere abone olunabilir
- LiveComponent kendi başına bir süreç değil, LiveView’ün çağırdığı bir modüldür
- Ebeveyn LiveView süreci alt bileşenlerin durumunu tuttuğundan, LiveView alt LiveComponents’a mesaj yönlendirmeyi de ele almak zorundadır
- LiveComponents’ın bağımsız durum yönetimi ve aksiyon işleme yeteneğine sahip olması için her birinin süreç olması gerekir; ancak mevcut model böyle değildir
- Gerçek geliştirmede LiveComponent’e event veya aksiyon göndermek istendiğinde iyi bir yöntem yoktur;
send_update’in aksiyon iletimi için mi yoksa durum patch’i için mi kullanılacağı belirsizleşir- Durum patch’i için kullanılırsa
updateclause’unda mount ile update’i nasıl ayırmak gerektiği de düşünülmelidir
- Durum patch’i için kullanılırsa
LiveSvelte’in oluşturduğu sınır
- LiveSvelte, LiveView içinde Svelte bileşenleri render etmeyi sağlar
- LiveView’ün
renderiçinde Elixir veri yapılarını frontend’e yönelik plain map olarak encode edip Svelte bileşeninin props’u olarak aktarmak mümkündür - Svelte bileşeni props’u
export letile alır ve LiveSvelte’in sağladığıliveprop’u üzerinden LiveView ile iletişim kurar - Svelte tarafında
live.pushEventile sunucuya event gönderilebilir- Örnekte Svelte’in reactive block’u,
formdeğiştiğinde sunucuya"form_updated"event’ini gönderir - LiveView,
handle_event("form_updated", ...)içinde frontend parametrelerini decode eder ve changeset’i günceller - Changeset doğrulama hataları yeniden
errorsprop’u üzerinden frontend’e iletilir
- Örnekte Svelte’in reactive block’u,
- Veri Elixir’den props olarak Svelte’e iner; Svelte’ten ise websocket event’i olarak LiveView’e çıkar
- LiveView süreci, props’u istediği an güncelleyerek Svelte bileşeninin yeniden render edilmesini sağlayabilir
LiveView ve Svelte kombinasyonunun temel özellikleri
- Bu kombinasyonun özü, stateful backend süreci ile stateful frontend bileşeninin birlikte çalışmasıdır
- Kombinasyonu üç özellik destekler
- Backend, frontend bileşeninin props’unu kontrol eder
- Hem frontend hem backend durum tutar
- İki tarafın da birbirine mesaj başlatabildiği özel bir çift yönlü iletişim kanalı vardır
- İlk özellik LiveView’ün rendering biçimi sayesinde mümkündür
- Sunucu yeniden rendering sonucu otomatik olarak istemciye push edilir ve uygulanır
- Sunucu, bir JS ebeveyn bileşeni gibi bileşen props’unu güncelleyebilir
- İkinci özellik LiveView’ün bir Elixir süreci olmasından gelir
- Elixir süreçleri, durumu kapsüllemenin bir yoludur
- Üçüncü özellik LiveView’ün sunduğu sürekli websocket bağlantısı ile mümkündür
SPA’dan farkları
- Tarayıcı routing’inin tamamı backend’de gerçekleştiği için yapı basitleşir
- Tipik SPA’larda tarayıcı route’ları ve API route’ları olmak üzere iki tür route tutulmalıdır
- Backend durum sahibidir; mevcut route’u ve üzerinde çalışılan kaynağı bilir
- Her aksiyon, durumu baştan yeniden oluşturmak yerine backend’in kendi durum değişikliği olarak işlenebilir
- Frontend ile backend arasındaki iletişim özel ve bağlıdır
- Tek bir bileşeni desteklemek için RPC çağrılarıyla sunucunun public route’ları artırılmaz
- İstemcide
pushEventgörüldüğünde ilgili handler’ın birlikte çalışan Elixir modülünün içinde olduğu anlaşılır
- Özellikler ağırlıklı olarak iki dosyaya ayrılır
- Backend modülü, veritabanı sorgulama gibi backend fonksiyonlarını çağırır
- Frontend, bileşen ve stilleri getirir
- Frontend-backend gidiş dönüşü API modülü, router ve controller stack’inden geçmez
- İletişim adımları da azalır
- Backend, yalnızca props güncellemesiyle frontend değişikliğini bildirebilir
- Frontend; süresi dolmuş token, timeout veya hata işleme handler’ları olmadan
pushEventgönderebilir - Websocket açıksa sunucu çalışıyor demektir; kapalıysa LiveView genel bir “disconnected” banner’ı gösterir
Sorumluluk ayrımı ve kod yapısı
- Bu yapıda frontend mikroservisi ortadan kaldırılmış gibi çalışılır
- İş mantığı backend’de tutulur
- Verinin nasıl yükleneceği
- Hangi verinin getirileceği
- Sıralama ve filtreleme biçimi
- Doğrulayıcılar
- Svelte frontend kodu sadeleşir
- Koşullu rendering için
if/endblokları - Animasyonlar
- Sunucuya gönderilen basit
pushEventfonksiyonu
- Koşullu rendering için
- Tipik bir SPA frontend’inde sunucu verisi işleme, gösterim için veri hazırlama ve sunucuya gönderilecek veri hazırlama amacıyla çok sayıda
map,reduce,filtermantığı oluşabilir - LiveSvelte uygulamasında bu işlemler sunucu tarafında yapılabilir
- LiveView, veriyi Svelte bileşeninin ihtiyaç duyduğu biçimde hazırlar
- Karmaşıklık sunucu dili, sunucu veri yapıları ve sunucu test suite’i içinde kalır
- LiveView ve Svelte bileşeni, gevşek bağlı iki unsurdan ziyade tek bir özelliğin iki yarısı gibidir
- LiveView yalnızca ilgili Svelte bileşenini render eder
- O Svelte bileşeni yalnızca ilgili LiveView tarafından render edilir
Saf LiveView’e göre değişenler
- LiveSvelte yaklaşımı frontend’in durumunu ve durum geçişlerini kabul eder
- Frontend ile backend arasındaki sınır katmanı netleşir
- Svelte’in olgun bileşen paradigmasından yararlanılabilir
- Yalnızca saf LiveView ile erişmesi zor olan JavaScript framework ekosistemi de kullanılabilir
- Svelte animasyon primitives sağlar
- Daha fazla sorumluluğu frontend’e taşıyarak garip bir ara bölgede kalma hissi azalır
Svelte’in seçilme nedeni ve LiveView’ün konumu
- LiveSvelte’in seçilme nedeni, React tarafında benzer olgunlukta bir LiveView kütüphanesinin olmamasıydı
- Svelte, temel durum ve reaktivite konusunda hafif ve hızlı bir frontend framework’ü olarak görülür
- LiveView durum yönetiminin büyük kısmını üstlendiği için Svelte tarafındaki durum yönetimi basit kalır
- Svelte’in template özellikleri de React’e tercih edilir
- Ternary operator yerine
if/elsekullanılabilir - Koşullu attribute ayarı kullanılabilir
- Ternary operator yerine
- Svelte 5’in runes, Svelte’i öğrenmesi ve akıl yürütmesi daha kolay hale getirmesi bekleniyor
- LiveView; frontend bileşenlerini render eden, artımlı güncellemeler yapan, stateful backend sürecini koruyan ve websocket API sağlayan bir backend-for-frontend olarak en iyi halini gösterir
1 yorum
Hacker News görüşleri
Çok oyunculu oyunlarda sık kullanılan kalıp, temelde aynı kodu hem istemci hem de sunucu tarafında çalıştırmaktır.
İstemci kodu, sunucu durumunu tahmin edip önce çalışır; sunucu durumu geldiğinde de istemci durumunun üzerine yazılır.
Oyunlarda istemci kendi girdisinin sonucunu oldukça iyi tahmin edebilir ama diğer oyuncuların girdilerini bilemez; bu yüzden “tahmin” sözcüğü yerli yerine oturur.
Ancak bu yöntem, bir dropdown'ı etkinleştirme/devre dışı bırakma ya da loading spinner gösterme gibi, resmi sunucu durumunu beklerken anında tepki vermek için de kullanılabilir.
Parçacık sistemleri veya ragdoll gibi sunucuda hiç çalıştırılması gerekmeyen pek çok istemci durumu da var; sürekli bir sunucu bağlantısı varsa reaktif paradigma içinde bunun olmaması için bir neden görünmüyor.
https://generals.io/ klonu ve LiveSvelte ile yapıldı.
Aslında bir masa oyunu sayılır ve saniyede 2 tick olduğu için tahmin özelliğine gerek yok; ama sunucu güncellemesinden önce oyun durumunu göstermeye yarayan iyimser güncellemeler kullanılıyor.
Sunucuyla senkron dışına çıkarsa sunucu oyun durumunun üzerine yazar.
Oyun mantığının tamamı Elixir içinde; tahmini doğru yapmak için sunucu ile istemcinin mantığı paylaşması gerekir.
Yoksa mantığı iki kez yazarsınız ki bu felakete giden yoldur.
Araştırmadım ama olası bir çözüm, tüm oyun mantığını gleam(https://gleam.run/) ile yazmak.
Gleam, Elixir ile uyumlu ve JavaScript'e de derlenebiliyor; teoride aynı kodu sunucu ve istemcide çalıştırabilirsiniz.
Gerçi “o zaman hepsini js ile yazsanıza” demek de oldukça haklı bir söz olur; ben de muhtemelen katılırım.
Yine de elde edilen avantaj BEAM ve gerçek zamanlı dağıtık sistemler için iyi özellikleri kullanabilmek; frontend hariç tutulursa bu, çok oyunculu oyunlara cuk oturuyor.
Biri ölüp cesedi havaya uçtuğunda ya da komik bir pozda sıkıştığında başka hiç kimse bunu görmüyor; replay'de de her istemci farklı render ettiği için tekrar izlenemiyor.
Gerçek zamanlı kayıtla yakalamazsanız sonsuza dek kayboluyor.
Overwatch gibi ara sıra gülünçleşen oyunlarda bunu kimsenin birlikte görememesi üzücü.
https://arstechnica.com/gaming/2019/10/explaining-how-fighti... harika bir açıklama; ilgili tartışmalar https://news.ycombinator.com/item?id=34399790 ve https://news.ycombinator.com/item?id=26289933 adreslerinde.
MMO'larda olduğu gibi sunucu kalıcılığı devreye girince, giriş/çıkış darboğazlarını da birlikte düşünmek gerekiyor.
https://prdeving.wordpress.com/2023/09/29/mmo-architecture-s... bu açıdan ilginç bir yazı; tartışması da https://news.ycombinator.com/item?id=37702632 adresinde.
Örneğin canlı/interaktif bir form, sayfadaki türetilmiş verileri güncelleyip her şey iyi çalışmış gibi görünebilir; ama daha sonra bir sunucu hatası veya ağ sorunu yüzünden hepsi geri alınırsa sıkıntı olur.
Daha da kötüsü, kullanıcı bunu bilmeden sayfayı kapatabilir ya da başka yere gidebilir.
LiveView + Svelte kombinasyonunu seviyorum.
ElixirConf 2022'de ikisini birleştirmenin yolunu sunmuştum, ama live_svelte katkıcıları bunu gerçekten kullanılabilir hale getirdi.
Zengin kullanıcı deneyimine sahip uygulamaların her zaman istemci tarafı duruma ihtiyaç duyduğunu düşünüyorum.
Özellikle New York'ta yaşıyorsanız, hareket halindeyken ağ bağlantısı garanti değil.
Yazıda ele alınmayan güçlü bir özellik de Phoenix'in pubsub'ını kullanarak başka sunucularda gerçekleşen sunucu tarafı durum değişikliklerini tüm istemcilere reaktif biçimde push edebilmek.
Orta ve üzeri trafiği karşılamak için birden fazla web sunucusu çalıştırmak oldukça yaygın.
LiveView benzeri bir kullanıcı deneyimi isterken kararsız ağlara da dayanmak istiyorsanız, Triplit[1]'e Svelte 5 binding'leri ekledim.
İstemci tarafında sorgular yazıp websocket üzerinden sunucuyla senkronize edebilirsiniz.
Elixir geliştiricileri için pek cazip olmayabilir; ama merkezde Svelte varsa Triplit iyi bir seçenek.
[1] https://www.triplit.dev/docs/frameworks/svelte
Yeni satırlar geldiğinde onları doğrudan tabloya itip LiveView’ın istemciyi güncellemesine bırakmak, bu satırların etkileşimli olduğu iş uygulamalarında kaçınılması gereken bir yöntemdir
Algısal gecikme yüzünden kullanıcının yanlış öğeye tıklaması, yanlış müşteriye e-posta göndermesi veya yanlış işlemi iade etmesi kolaylaşır
Tercih edilen kullanıcı deneyimi, “Veri değişti. Yenilemek için buraya tıklayın” gibi sabit bir bannerdır
Acele gerekiyorsa yeni satırları yalnızca ekleme şeklinde render etmeli ve kaydırma konumunun değişmemesini sağlamalısınız
BeaconCMS’de Svelte ve LiveView birlikte kullanılıyor
İstemcide UI üzerinde daha ayrıntılı kontrol gerektiren iyi kullanım alanları kesinlikle var, ancak ekibin her şeyde Svelte + LiveView’ı baştan sona benimsemesi konusunda dikkatli olmak gerekir
Phoenix’te de LiveView her zaman yanıt değildir; bazen normal render edilen sayfalar yeterlidir
Her şeyi ya hep ya hiç şeklinde seçmemek gerekir
Yazıda söylendiği gibi “LiveView tarzı”nın dışına çıkmayı haklı çıkaran iyi kullanım alanları var
Gidiş-dönüş süresi 1.000 ms ise başka seçenekleri de düşünmek gerekir; ancak maliyet gibi nedenlerle coğrafi olarak yakın sunucu bulunduramayan ekipler de olduğundan, istemci tarafı durum yönetimi çözüm olabilir
İstemci durumunu yönetmek yerine hem istemci hem de sunucu tarafı durumu mu yönetilecek?
Başka bir API oluşturmak zorunda kalmamak avantaj olsa da, bu bir iyileştirme gibi görünmüyor
Her zaman istemcinin izlemesi gereken durum ile sunucunun izlemesi gereken durum vardır; bunun üzerine yalnızca bellekte bulunması yeterli olan geçici durum ile oturumlar arasında korunması gereken durum da biner
Bunu yönetmenin yolları neredeyse sonsuzdur ve JavaScript’te “ne yaparsan yap doğru cevap yok” gibi bir durum olduğundan ya framework’ün belirlediği yolu kullanırsınız ya da geçici çözümlerle, yani kaosla ilerlersiniz
En son yazdığım karmaşık tek sayfa uygulamada, istemcinin sayfayı her yüklediğinde senkronizasyon yapmasını sağladım
Tüm yerel durumlara veya varlıklara tarih tabanlı bir hash eklenmişti; sunucudaki değerle farklıysa sunucu güncellenmiş sürümü gönderiyordu
Basit bir değişken de olsa, devasa bir JSON nesnesi de olsa, tüm bir görüntü/ses blob’u da olsa aynıydı
İstemci sunucu durumu değişikliği gerektiren bir şey yaptığında, bu durum güncellemesini WebSocket üzerinden gönderiyordu ve uygulamanın %99’u WebSocket tabanlıydı
Özel bir framework veya pattern kullanmadım; kod yazarken “bunu sunucu izlemeli” diye düşünürsem yeni durumu sunucuya mesaj olarak gönderiyor, sayfa yüklenirken senkronize edilip edilmeyeceğine sunucunun karar vermesini sağlıyordum
Bu tür durum yönetiminde bunun neredeyse en basit mekanizma olduğunu düşünüyorum
WebSocket, durum yönetiminde gerçekten çok yardımcı oluyor
Gerçek uygulamalar hem istemci hem de sunucu tarafında duruma ihtiyaç duyar
Sunucu istemciye güvenemeyeceği için yetkili duruma sahip olmalıdır; ancak istemci de gidiş-dönüş olmadan kullanıcı etkileşimlerine yanıt verip yeniden render edebilmelidir
Her şeyi böyle yapmayın; yalnızca anlamlı olduğunda kullanın
Ayrıca hoşuma giden bir diğer nokta, Heex yerine Svelte’i şablon dili gibi kullanabilmek
Gerekmiyorsa yapmanın bir nedeni yoktur; gerekli hale gelmesinin nedeni de performans ve kullanıcı deneyimidir
Web uygulamasında kullanıcı etkileşimi çoksa istemci JavaScript’i gerekir ve çok sayıda deney nedeniyle her istekte bundle değişiyorsa, istemciye gönderilen JavaScript miktarını azaltmak için mantığı sunucu ile istemci arasında bölmek istersiniz
Aksi halde uygulamanın karşılaşabileceği tüm olasılıkları içeren MB’larca JavaScript bundle’ınız olur
Photoshop’un web sürümü gibi kullanıcının ilk yükleme süresini anlayışla karşıladığı uygulamalarda bu kabul edilebilir; ancak Stripe veya Gmail gibi anında yüklenmesi beklenen uygulamalarda sayfanın ilk gecikmesini azaltmak istersiniz
Her şeyi sunucuya da taşıyabilirsiniz; ancak GitHub’ın yaşadığı gibi, anında tepki vermesi gereken kullanıcı eylemleri sunucu gidiş-dönüşü gerektirdiğinde sayfa etkileşimi kötüleşir
O zaman ışık hızı ve sunucu dağıtımı sorun haline gelir
async import gibi yöntemlerle bundle’ı geç yükleyebilirsiniz; ancak geç yüklenen JavaScript kendi verisini almak için tekrar istek gönderdiğinde şelale sorunu ortaya çıkar
Bu sorunların hepsiyle karşılaşınca, sonunda istemci ile sunucu arasında mantık/durum paylaşımı gibi karmaşık bir problemi kolayca ele alan bir çözüm aramaya başlarsınız
Bu yaklaşımda “sunucunun kullanıcıya ne kadar yakın olabileceğinin bir sınırı var” ifadesinin tam anlamıyla ışık hızı sınırı bulunur
Sonraki adım, sunucuyu WebAssembly’ye derleyip istemciye göndermektir
Böylece gerçek sunucu yanıtını beklerken iyimser biçimde yanıtı render edebilirsiniz
Kulağa biraz çılgınca geliyor, ama gerçek bir projede bunu başardık ve sihir gibiydi
Sunucuyu istemcide çalıştırmak bunu çözmez; sonunda kalıcılığın ağ gecikmesi aynen kalır
Nihayetinde kazanması gereken sunucu durumu da bu kalıcılıktır
Pek çok aşırı mühendislik zaten pek neden olmadan da gerçekten uygulanıyor
LiveSvelte’i ben yaptım; merak ettiğiniz bir şey olursa söyleyin
Genel olarak, uygulamaları hep böyle bir modelle geliştirmek istemiştim.
Olay odaklı, sunucuyla çift yönlü gerçek zamanlı güncellemeler, sıralı olaylar, yerel/uzak durum gibi bir yaklaşım.
LiveView’u bilmiyordum ve Erlang ailesinden bir dil de hiç kullanmadım ama kesinlikle bir şeyleri doğru yakalıyor gibi görünüyor.
Geleneksel istek-yanıt modeli, tutarlılık ve bayat veri sorunlarını sık sık ince biçimlerde ortaya çıkarıyor.
Geçtiğimiz 10 yıl fonksiyonel programlama kavramlarını ana akım dillere entegre etme dönemiyse, önümüzdeki 10 yılın durumlu, mesaj odaklı programlamayı ana akım full-stack’e entegre etme yönünde olmasını isterim.
Bu arada ilk üçünü ben yaptım ya da yapılmasına yardımcı oldum.
Kılavuzu takip edip biraz kurcalarsanız, yaklaşık iki saat içinde tarayıcıda çalışan temel bir Phoenix sohbet uygulamasını ayağa kaldırabilirsiniz.
İyi bir çözüm.
Kendi uygulamamda LiveView ile birlikte yeniden kullanılabilir Stimulus controller’ları kullanıyorum ve bu da sorunsuz çalışıyor.
Genel olarak LiveView ile geliştirme yapmak keyifli ama gerçek senaryolarda daha fazla kullandıkça Hotwire gibi durumsuz HTTP framework’lerinin avantajlarını da daha çok hissediyorum.
Daha performanslı ve yeniden bağlanmaya daha dayanıklı hissettiriyor; ayrıca kararlılık için kullanıcıya yakın daha fazla sunucu yerleştirme ihtiyacı da azalıyor.
Ama Stimulus, istemcide durumu tutmak için zarif bir yol sunmuyor.
“Stimulus uygulamasının durumu DOM’un nitelikleri olarak bulunur” gibi bir yaklaşımı var; bu da vanilla JS ya da jQuery’den daha iyi değil.
Gerçek bir projede Stimulus kullanmış değilim, dolayısıyla değerler ve değişiklik callback’leri ilk düşündüğümden daha iyi bir deneyim sunuyor olabilir.
Bu kombinasyonun karmaşıklık seviyesi tam yerinde; Svelte ise LiveView ile birlikte kullanıldığında, en başta sorun olmayan pek çok şeyi de ele alıyormuş gibi hissettiriyor.
Gerekli olan şey vanilla JS ya da onun üzerinde ince bir katman; tam teşekküllü bir framework değil.
Zaten çok fazla JavaScript kullanmaya gerek kalmıyor.
Prodüksiyondaki uygulamanın JS’i 200 satırı geçmiyor ve birkaç Stimulus controller’ını da kaldırabilirim gibi görünüyor.
LiveView o kadar iyi.
Stimulus-LiveView hook adaptörünü de oldukça hacky bir şekilde yaptım; böylece Stimulus controller’ı LiveView sürecine doğrudan olay gönderebiliyor.
Ayrıca LiveView, fly.io tarzı Kool-Aid’i fazla içmediyseniz, coğrafi olarak dağıtılmış sunucuları mutlaka gerektirmez.
Bağlantı kopmalarını da harika yönetiyor.
Kesintisiz güncellemeleri desteklemek için ayrıca hiçbir şey yapmadım.
İstemcinin WebSocket bağlantısını kaybedip yeni sürüme yeniden bağlanması ve durumu geri yüklemesi tamamen varsayılan olarak otomatik işleniyor.
Daha ne istenir?
Şirketimiz LiveView ile Alpine’ı birlikte kullanarak büyük fayda gördü; özellikle istemcide
eval’e izin veremediğimiz için CSP modu kullanıyoruz.LiveSvelte’i ilk gördüğümde çok yeni ve yeterince doğrulanmamış görünüyordu; ayrıca sıkı CSP ortamlarında çözülmemiş etkileri de vardı.
Şimdi oldukça kullanışlı hale gelmiş gibi görünmesine sevindim.
Bizim kalıbımız kabaca LiveAlpine olarak adlandırılabilir.
Bileşenin HTML’e ihtiyacı varsa HTML Component kullanıyoruz; sunucu tarafı durumu varsa Live Component kullanıyoruz.
İstemci tarafı davranış ya da durum gerekiyorsa Alpine component’i de tanımlıyoruz.
Sunucuda istemci event’i almak ya da HTTP isteği yapmak gerekiyorsa Phoenix Hook da tanımlıyoruz.