LiveView se marie le mieux avec Svelte
(blog.sequin.io)- Après avoir utilisé à la fois une SPA React et Phoenix LiveView pur, l’équipe de Sequin a conclu que l’approche la plus productive consistait à combiner LiveView et Svelte avec LiveSvelte
- LiveView permet de créer des interfaces riches sans SPA grâce à l’état côté serveur et aux mises à jour incrémentales du DOM, mais dès qu’un état client devient nécessaire, modules JS, hooks et état LiveView se mélangent et la frontière devient floue
- En LiveView pur, LiveView, LiveComponent et Component ont des cycles de vie, des modes de passage des props et des mécanismes de communication différents, ce qui rend le refactoring et le placement de l’état plus fastidieux qu’avec React
- LiveSvelte fournit une frontière bidirectionnelle claire : Elixir transmet les props vers le bas et Svelte remonte les événements avec
live.pushEvent - Dans cette combinaison, le routage, la logique métier et la préparation des données restent côté serveur, tandis que l’état de l’UI, les animations et le rendu conditionnel sont pris en charge par Svelte, ce qui réduit la complexité d’une SPA
Le modèle de développement proposé par LiveView
- Une application traditionnelle en rendu serveur ne conserve pas d’état côté serveur et rend la page à chaque requête du client
- Dans une SPA, le client se charge de composer la page, lit et écrit les données via une API backend, et gère l’état client avec des mécanismes comme
useStatede React - LiveView continue de confier le rendu de la page au serveur tout en conservant l’état, puis traite les actions frontend et met à jour le DOM de façon incrémentale comme une SPA
- La complexité d’une SPA augmente parce que l’application JavaScript côté client agit en pratique comme un microservice frontend
- Les besoins propres au frontend multiplient les routes et contrôleurs backend
- Une requête peut traverser
onMount, un appel d’API, le parsing de la réponse, le routeur, les plugs d’authentification, le contrôleur, les fonctions métier et la couche de préparation de la réponse
- L’avantage de LiveView est de permettre une expérience client riche sans microservice frontend
- Il est possible d’interroger la base de données à proximité de la fonction qui rend un tableau
- Lorsqu’une nouvelle ligne arrive, on peut la pousser dans le tableau et LiveView met à jour le client
- On obtient des interactions plus proches d’un framework frontend stateful que du rendu serveur classique où tout l’état est reconstruit à chaque requête
Les frictions rencontrées avec LiveView pur
-
L’état côté client reste inévitable
- LiveView ne peut pas éviter la latence d’aller-retour entre le serveur et l’utilisateur
- Pour les animations, infobulles, affichage/masquage du DOM ou désactivation de champs de formulaire, un traitement côté client devient parfois nécessaire
- Dans un formulaire avec deux listes déroulantes dépendantes, une bonne UX consiste à désactiver immédiatement la seconde après la sélection dans la première, puis à la réactiver une fois que le serveur a renvoyé la nouvelle liste
- Implémenter ce comportement avec LiveView seul demande de combiner plusieurs concepts
- Quand JS, hooks et état LiveView sont utilisés ensemble, une partie de l’état du DOM se retrouve hors de LiveView, ce qui rend difficile l’adoption d’un schéma cohérent
-
Des frontières d’état différentes de React
- React gère la plupart des transitions avec deux concepts centraux, l’état et les actions, et la frontière entre état du DOM et état du composant y est relativement nette
- Comme il n’y a pas de latence entre action client et état client, React peut traiter actions et transitions dans un paradigme d’état
- L’état de LiveView se situe côté serveur, il faut donc tenir compte de la latence entre action client et état serveur
- Dans l’exemple d’un champ de saisie, React passe par le chemin de l’état avant même que le caractère soit affiché, et le composant se rerend à chaque frappe
- LiveView est plus proche d’un modèle où l’utilisateur modifie d’abord le champ, puis le serveur en prend connaissance un court instant plus tard et réagit ensuite
- Quand la latence est quasi nulle, cela ressemble à React, mais plus elle augmente, plus la différence entre les deux modèles devient évidente
La complexité créée par trois types de composants
- LiveView propose trois types de composants : LiveViews, LiveComponents et Components
- LiveViews et LiveComponents se rapprochent de composants stateful de React, tandis que Components se rapproche de composants fonctionnels
- LiveView est toujours le composant parent de plus haut niveau, sous lequel sont rendus LiveComponents et Components
- Dans React, on peut passer facilement d’un composant stateful à un composant fonctionnel en ajoutant ou retirant le hook
useState- Les deux reçoivent les props de la même manière
- En dehors de l’état, leur ensemble de fonctionnalités est identique
- L’enregistrement des événements DOM et leur traitement fonctionnent aussi de la même façon
- Dans LiveView, les différences entre les trois types de composants sont importantes, ce qui rend fastidieux le refactoring d’un LiveView en LiveComponent
- La syntaxe de rendu et de passage des props diffère entre LiveViews et LiveComponents
- Leur cycle de vie est différent
- Les options de communication diffèrent : on utilise
sendpour les LiveViews etsend_updatepour les LiveComponents - Les LiveComponents ne sont pas des processus et ne peuvent donc pas interagir avec les autres parties du système comme le font les LiveViews
Les limites de LiveComponent
- Un LiveView est un processus Elixir : il possède un
pid, un état et une inbox, et peut se comporter comme les autres processus du système Elixir/OTP - Dans un LiveView, on peut utiliser pub/sub pour s’abonner à des changements à l’échelle du système
- Un LiveComponent n’est pas un processus autonome, mais un module invoqué par LiveView
- Comme le processus parent LiveView conserve l’état des composants enfants, c’est lui qui doit aussi gérer le routage des messages vers les LiveComponents enfants
- Pour que les LiveComponents disposent d’une gestion d’état et d’un traitement d’actions véritablement indépendants, chacun devrait être un processus, ce qui n’est pas le modèle actuel
- En pratique, même lorsqu’on veut envoyer un événement ou une action à un LiveComponent, il n’existe pas de bonne méthode, et il devient ambigu de savoir si
send_updatedoit servir à transmettre une action ou à appliquer un patch d’état- S’il sert à appliquer un patch d’état, il faut aussi réfléchir à la manière de distinguer montage et mise à jour dans la clause
update
- S’il sert à appliquer un patch d’état, il faut aussi réfléchir à la manière de distinguer montage et mise à jour dans la clause
La frontière créée par LiveSvelte
- LiveSvelte permet de rendre des composants Svelte dans LiveView
- Dans le
renderde LiveView, on peut encoder des structures de données Elixir en plain maps pour le frontend, puis les transmettre comme props à un composant Svelte - Le composant Svelte reçoit les props avec
export letet communique avec LiveView via la proplivefournie par LiveSvelte - Côté Svelte, on peut envoyer des événements au serveur avec
live.pushEvent- Dans l’exemple, un bloc réactif de Svelte envoie l’événement
"form_updated"au serveur quandformchange - LiveView décode ensuite les paramètres frontend dans
handle_event("form_updated", ...)et met à jour le changeset - Les erreurs de validation du changeset sont renvoyées au frontend via la prop
errors
- Dans l’exemple, un bloc réactif de Svelte envoie l’événement
- Les données descendent d’Elixir vers Svelte sous forme de props, puis remontent de Svelte vers LiveView via des événements WebSocket
- Le processus LiveView peut à tout moment mettre à jour les props pour provoquer un rerender du composant Svelte
Les propriétés clés de l’association LiveView + Svelte
- Le point central de cette combinaison est qu’un processus backend stateful et un composant frontend stateful fonctionnent ensemble
- Trois propriétés soutiennent cet assemblage
- Le backend contrôle les props du composant frontend
- Le frontend et le backend ont tous deux un état
- Les deux côtés disposent d’un canal privé de communication bidirectionnelle permettant à chacun d’initier des messages
- La première propriété est rendue possible par le mode de rendu de LiveView
- Le résultat du rerender serveur est automatiquement poussé vers le client puis appliqué
- Le serveur peut mettre à jour les props d’un composant comme le ferait un composant parent en JS
- La deuxième propriété découle du fait que LiveView est un processus Elixir
- Un processus Elixir est une manière d’encapsuler l’état
- La troisième propriété est rendue possible par la connexion WebSocket persistante fournie par LiveView
Différences avec une SPA
- Tout le routage navigateur est géré par le backend, ce qui simplifie l’architecture
- Dans une SPA classique, il faut maintenir deux types de routes : les routes navigateur et les routes API
- Le backend conserve l’état et connaît la route actuelle ainsi que la ressource en cours de manipulation
- Chaque action peut être traitée comme une modification de l’état du backend lui-même, au lieu de tout reconstruire depuis zéro
- La communication entre frontend et backend est privée et étroitement couplée
- Elle n’augmente pas le nombre de routes publiques du serveur pour prendre en charge des appels RPC liés à un composant unique
- Lorsqu’on voit un
pushEventcôté client, on sait que le handler correspondant se trouve dans le module Elixir avec lequel il collabore
- La fonctionnalité se répartit généralement dans deux fichiers
- Le module backend appelle des fonctions backend comme les requêtes base de données
- Le frontend importe les composants et les styles
- Les allers-retours frontend/backend ne traversent ni un module API, ni un routeur, ni une pile de contrôleurs
- La procédure de communication est aussi réduite
- Le backend peut signaler des changements au frontend par simple mise à jour des props
- Le frontend peut envoyer un
pushEventsans gérer jetons expirés, timeouts ni handlers de panne - Si le WebSocket est ouvert, le serveur fonctionne ; s’il est fermé, LiveView affiche une bannière globale « disconnected »
Séparation des responsabilités et structure du code
- Avec cette architecture, on a l’impression que le microservice frontend a disparu
- La logique métier reste côté backend
- La manière de charger les données
- Les données à charger
- Les règles de tri et de filtrage
- Les validateurs
- Le code frontend Svelte devient plus simple
- Des blocs
if/endpour le rendu conditionnel - Des animations
- De simples fonctions
pushEventpour parler au serveur
- Des blocs
- Dans un frontend de SPA classique, il peut y avoir beaucoup de logique
map,reduce,filterpour traiter les données serveur, préparer les données d’affichage et préparer les données à renvoyer au serveur - Dans une application LiveSvelte, ces traitements peuvent être effectués côté serveur
- LiveView prépare les données dans le format attendu par le composant Svelte
- La complexité reste dans le langage serveur, les structures de données serveur et la suite de tests serveur
- Le LiveView et le composant Svelte sont moins deux éléments faiblement couplés que deux moitiés d’une même fonctionnalité
- Le LiveView ne rend que ce composant Svelte précis
- Et ce composant Svelte n’est rendu que par ce LiveView précis
Ce qui change par rapport à LiveView pur
- L’approche LiveSvelte assume l’état frontend et les transitions d’état
- La couche frontière entre frontend et backend devient plus claire
- Elle permet de tirer parti du paradigme de composants mature de Svelte
- Elle ouvre aussi l’accès à l’écosystème des frameworks JavaScript, difficile à mobiliser avec LiveView pur seul
- Svelte fournit des primitives d’animation
- En déplaçant davantage de responsabilités vers le frontend, elle réduit l’impression d’être coincé dans une zone intermédiaire maladroite
Pourquoi Svelte et quelle place pour LiveView
- Le choix de LiveSvelte vient du fait qu’il n’existait pas de bibliothèque LiveView d’un niveau de maturité comparable pour React
- Svelte est considéré comme un framework frontend léger et rapide, avec une gestion de l’état et une réactivité natives
- Comme LiveView prend en charge une grande partie de la gestion d’état, l’état côté Svelte reste simple
- Les capacités de template de Svelte sont également préférées à celles de React
- On peut utiliser
if/elseplutôt qu’un opérateur ternaire - On peut définir des attributs conditionnels
- On peut utiliser
- Les runes de Svelte 5 devraient rendre Svelte plus facile à apprendre et à raisonner
- LiveView brille surtout comme backend-for-frontend capable de rendre des composants frontend, d’effectuer des mises à jour incrémentales, de maintenir un processus backend stateful et de fournir une API WebSocket
1 commentaires
Commentaires sur Hacker News
Un schéma souvent utilisé dans les jeux multijoueurs consiste essentiellement à exécuter le même code côté client et côté serveur
Le code client anticipe d’abord l’état du serveur, puis quand l’état serveur arrive, il écrase l’état du client
Dans les jeux, le client peut assez bien deviner le résultat de ses propres entrées, mais il ne connaît pas celles des autres joueurs, donc le terme de « prédiction » est bien adapté
Mais cette approche peut aussi servir à réagir immédiatement, par exemple pour activer/désactiver un menu déroulant ou afficher un spinner de chargement, en attendant l’état serveur faisant autorité
Il existe aussi beaucoup d’états purement client, comme les systèmes de particules ou les ragdolls, qui n’ont pas besoin de tourner sur le serveur, et avec une connexion serveur persistante, rien n’empêche en théorie de l’appliquer aussi dans un paradigme réactif
C’est un clone de https://generals.io/ réalisé avec LiveSvelte
C’est pratiquement un jeu de plateau et ça tourne à 2 ticks par seconde, donc il n’y a pas besoin de prédiction, mais il y a bien des mises à jour optimistes qui affichent l’état du jeu avant la mise à jour du serveur
Si la synchronisation avec le serveur ne correspond pas, le serveur écrase l’état du jeu
Toute la logique du jeu est dans Elixir, et pour faire de la vraie prédiction, le serveur et le client doivent partager la logique
Sinon il faut écrire la logique deux fois, et c’est la voie directe vers la catastrophe
Je n’ai pas étudié le sujet, mais une solution possible serait d’écrire toute la logique du jeu en gleam(https://gleam.run/)
Gleam est compatible avec Elixir et peut aussi être compilé en JavaScript, donc en théorie le même code peut tourner côté serveur et côté client
Cela dit, l’argument « autant tout écrire directement en js » se tient assez bien, et je serais sans doute d’accord
Malgré tout, l’avantage est de pouvoir profiter de BEAM et de ses atouts pour les systèmes distribués en temps réel, ce qui correspond très bien aux jeux multijoueurs, hormis la partie frontend
Quand quelqu’un meurt et que son corps est projeté ou reste coincé dans une pose ridicule, personne d’autre ne le voit, et même dans les replays on ne peut pas le revoir puisque chaque client le rend différemment
Si ce n’est pas capturé dans un enregistrement en temps réel, c’est perdu pour toujours
Dans un jeu parfois aussi absurde qu’Overwatch, c’est dommage que personne ne puisse partager ces moments
https://arstechnica.com/gaming/2019/10/explaining-how-fighti... en donne une excellente explication, et on trouve des discussions associées sur https://news.ycombinator.com/item?id=34399790 et https://news.ycombinator.com/item?id=26289933
Dès qu’on ajoute la persistance serveur, comme dans un MMO, il faut aussi prendre en compte les goulots d’étranglement d’entrée/sortie
https://prdeving.wordpress.com/2023/09/29/mmo-architecture-s... est un billet intéressant sur cet angle, avec une discussion ici : https://news.ycombinator.com/item?id=37702632
Par exemple, un formulaire live/interactif peut sembler bien fonctionner en mettant à jour des données dérivées sur la page, puis tout être annulé plus tard à cause d’une erreur serveur ou d’un problème réseau
Pire encore, l’utilisateur peut fermer la page ou partir ailleurs sans même s’en rendre compte
J’aime beaucoup la combinaison LiveView + Svelte
J’ai présenté à ElixirConf 2022 une façon de les combiner, mais ce sont les contributeurs de live_svelte qui l’ont réellement rendue exploitable en pratique
À mon avis, les applications qui offrent une expérience utilisateur riche ont toujours besoin d’un état côté client
Surtout quand on vit à New York, où disposer d’une connexion réseau en déplacement ne va pas de soi
Une fonctionnalité puissante que l’article ne mentionne pas, c’est qu’avec le pubsub de Phoenix, on peut aussi pousser de manière réactive à tous les clients les changements d’état côté serveur survenus sur d’autres serveurs
Dès qu’on doit gérer un trafic moyen ou élevé, il est assez courant d’avoir plusieurs serveurs web
Si on veut une expérience à la LiveView tout en restant robuste face à un réseau instable, j’ai ajouté des bindings Svelte 5 à Triplit[1]
On peut écrire les requêtes côté client et se synchroniser avec le serveur via WebSocket
Ce n’est peut-être pas très séduisant pour les développeurs Elixir, mais si Svelte est au centre de l’architecture, Triplit est un bon choix
[1] https://www.triplit.dev/docs/frameworks/svelte
Quand de nouvelles lignes arrivent, il vaut mieux éviter de simplement les pousser dans le tableau et laisser LiveView mettre le client à jour dans des applications métier interactives
À cause de la latence cognitive, l’utilisateur peut facilement cliquer sur le mauvais élément, envoyer un e-mail au mauvais client ou rembourser la mauvaise transaction
L’expérience utilisateur préférable est une bannière fixe du type « Les données ont changé. Cliquez ici pour actualiser »
En cas d’urgence, il faut rendre les nouvelles lignes en mode ajout uniquement et faire en sorte que la position de défilement ne change pas
Dans BeaconCMS, Svelte et LiveView sont utilisés ensemble
Il existe clairement de bons cas d’usage où il faut un contrôle plus fin de l’interface côté client, mais il faut être prudent avant que l’équipe adopte Svelte + LiveView partout
Même avec Phoenix, LiveView n’est pas toujours la réponse, et parfois une page rendue de façon classique suffit
Il ne faut pas tout voir en tout ou rien
Comme le dit l’article, il existe de bons cas d’usage pour sortir de la « manière LiveView »
Si le temps d’aller-retour est de 1 000 ms, il faut envisager autre chose, mais pour des équipes qui ne peuvent pas avoir de serveurs géographiquement proches pour des raisons comme le coût, la gestion d’état côté client peut être une solution
Au lieu de gérer l’état client, il faudrait donc gérer à la fois l’état client et l’état serveur ?
Il y a bien l’avantage de ne pas avoir à créer une autre API, mais ça ne ressemble pas vraiment à une amélioration
Il y a toujours un état que le client doit suivre et un état que le serveur doit suivre, avec en plus un chevauchement entre l’état temporaire qui peut rester uniquement en mémoire et l’état qui doit persister d’une session à l’autre
Les façons de gérer cela sont presque infinies, et en JavaScript, comme il n’y a pas de « bonne réponse quoi qu’on fasse », on finit soit par suivre la façon imposée par le framework, soit par bricoler, autrement dit par sombrer dans le chaos
Dans la dernière application monopage complexe sur laquelle j’ai travaillé, on faisait une synchronisation à chaque chargement de page côté client
Tous les états locaux et toutes les ressources avaient un hash basé sur la date, et s’il différait de la valeur côté serveur, le serveur envoyait une version mise à jour
C’était vrai aussi bien pour une simple variable que pour un énorme objet JSON, ou même pour des blobs image/audio complets
Quand le client faisait quelque chose qui nécessitait un changement d’état côté serveur, il envoyait cette mise à jour d’état via WebSocket, et 99 % de l’application reposait sur WebSocket
Nous n’utilisions ni framework ni pattern particuliers ; en écrivant le code, si l’on se disait « ça, c’est au serveur de le suivre », on envoyait le nouvel état au serveur dans un message, et c’était au serveur de décider s’il fallait le synchroniser au chargement de la page
Pour ce type de gestion d’état, j’estime que c’est à peu près le mécanisme le plus simple possible
WebSocket aide énormément pour la gestion d’état
Les applications réelles ont besoin d’état à la fois côté client et côté serveur
Le serveur doit avoir un état faisant autorité, puisqu’il ne peut pas faire confiance au client, mais le client doit aussi pouvoir réagir aux interactions utilisateur et rerendre sans aller-retour
Il ne faut pas tout faire ainsi, seulement quand cela a du sens
Un autre point qui me plaît, c’est qu’on peut utiliser Svelte comme langage de template au lieu de Heex
Il n’y a aucune raison de le faire si ce n’est pas nécessaire, et si cela devient nécessaire, c’est pour des raisons de performance et d’expérience utilisateur
Si une application web comporte beaucoup d’interactions utilisateur nécessitant du JavaScript côté client, et qu’elle fait beaucoup d’expérimentations au point que les bundles changent selon les requêtes, on finit par vouloir répartir la logique entre serveur et client pour réduire la quantité de JavaScript envoyée au client
Sinon, on se retrouve avec un bundle JavaScript de plusieurs Mo qui contient toutes les possibilités que l’application peut rencontrer
Cela peut convenir pour une application comme la version web de Photoshop, où l’utilisateur comprend le temps de chargement initial, mais pour des applications comme Stripe ou Gmail, où l’on s’attend à un chargement immédiat, on veut réduire la latence initiale de la page
On peut tout déplacer vers le serveur, mais comme GitHub l’a constaté, des actions utilisateur qui devraient réagir instantanément se retrouvent à nécessiter un aller-retour serveur, ce qui dégrade l’interactivité de la page
On se heurte alors à la vitesse de la lumière et à la répartition des serveurs
On peut aussi différer le chargement des bundles avec des choses comme
async import, mais cela crée alors un problème de cascade, parce que le JavaScript chargé à la demande envoie encore une autre requête pour récupérer ses donnéesQuand on a rencontré tous ces problèmes, on finit par chercher une solution qui traite facilement le problème complexe du partage de logique et d’état entre client et serveur
Cette approche a une limite de vitesse de la lumière au sens littéral du terme : il existe une limite à la proximité du serveur avec l’utilisateur
L’étape suivante consiste à compiler le serveur en WebAssembly et à l’envoyer au client
On peut alors rendre la réponse de manière optimiste pendant qu’on attend la vraie réponse du serveur
Cela peut sembler complètement fou, mais je l’ai fait sur un vrai projet et c’était magique
Exécuter le serveur côté client ne résout pas cela, et au final, la latence réseau de la persistance reste la même
L’état serveur qu’il faut réellement faire triompher au bout du compte, c’est cette persistance
Beaucoup de surconception finit réellement par être implémentée, même sans raison particulière
J’ai créé LiveSvelte, donc s’il y a des questions, n’hésitez pas
Globalement, j’ai toujours voulu construire des applications selon ce modèle
orienté événements, avec des mises à jour bidirectionnelles en temps réel entre le serveur et le client, des événements ordonnés, et des notions d’état local/distants
Je ne connaissais pas LiveView et je n’avais jamais utilisé de langage de la famille Erlang, mais il semble clairement tenir quelque chose
Le modèle traditionnel requête-réponse provoque souvent, de manière subtile, des problèmes de cohérence et de données obsolètes
Si les dix dernières années ont servi à intégrer les concepts de programmation fonctionnelle dans les langages grand public, j’aimerais que les dix prochaines servent à intégrer la programmation orientée messages avec état dans le full stack grand public
Pour information, j’ai créé ou aidé à créer les trois premiers
En suivant le guide et en expérimentant un peu, on peut lancer en environ deux heures une application de chat Phoenix basique fonctionnant dans le navigateur
C’est une bonne solution
Dans mon application, j’utilise des contrôleurs Stimulus réutilisables avec LiveView, et cela fonctionne aussi de manière fluide
Dans l’ensemble, développer avec LiveView est agréable, mais plus je l’utilise dans des scénarios réels, plus je perçois aussi les avantages des frameworks HTTP sans état comme Hotwire
Cela semble plus performant et plus robuste aux reconnexions, et réduit aussi le besoin de déployer davantage de serveurs près des utilisateurs pour assurer la stabilité
Mais Stimulus ne fournit pas de manière élégante de maintenir l’état côté client
C’est du genre « l’état d’une application Stimulus existe dans les attributs du DOM », donc ce n’est pas vraiment mieux que du JavaScript vanille ou jQuery
Je n’ai pas utilisé Stimulus dans un vrai projet, donc il est possible que les valeurs et les callbacks de changement offrent une meilleure expérience que je ne l’imaginais au départ
Cette combinaison a exactement le bon niveau de complexité, et Svelte, utilisé avec LiveView, donne l’impression de gérer beaucoup de choses qui ne sont pas vraiment des problèmes au départ
Ce qu’il faut, c’est du JavaScript vanille ou une fine couche au-dessus, pas un framework complet
De toute façon, il n’y a pas besoin d’écrire beaucoup de JavaScript
Le JS de mon application en production ne dépasse pas 200 lignes, et je pourrais probablement supprimer quelques contrôleurs Stimulus
LiveView est à ce point bon
J’ai aussi bricolé un adaptateur de hooks Stimulus-LiveView de manière très hacky, pour permettre aux contrôleurs Stimulus d’envoyer directement des événements au processus LiveView
Et LiveView n’exige pas forcément des serveurs géographiquement distribués, à moins d’avoir vraiment trop bu le Kool-Aid façon fly.io
Il gère aussi très bien les coupures de connexion
Je n’ai rien eu à faire de particulier pour prendre en charge les mises à jour sans interruption
Toute la séquence où le client perd sa connexion WebSocket, se reconnecte à la nouvelle version et restaure son état est gérée automatiquement par défaut
Que demander de plus ?
Notre entreprise a tiré de gros avantages de l’usage combiné de LiveView et Alpine, en particulier parce que nous utilisons le mode CSP et ne pouvons pas autoriser
evalcôté clientQuand j’ai vu LiveSvelte pour la première fois, cela paraissait très nouveau et encore peu éprouvé, avec aussi des implications non résolues dans les environnements CSP stricts
Je suis heureux de voir que cela semble maintenant être devenu assez utile
Notre approche pourrait en gros être appelée LiveAlpine
Si un composant a besoin de HTML, nous utilisons un HTML Component, et s’il a un état côté serveur, nous utilisons un Live Component
S’il faut un comportement ou un état côté client, nous définissons aussi un composant Alpine
S’il faut recevoir des événements client côté serveur ou effectuer des requêtes HTTP, nous définissons aussi un Phoenix Hook