Slide 1

Slide 1 text

Symfony UX et le frontend, cette épopée

Slide 2

Slide 2 text

Sommaire 01 - UX ? DX ? Et l’UI ? 02 - En théorie, c’est pratiquement pratique 03 - Chougner, c’est bien parfois 01

Slide 3

Slide 3 text

User or Developer experience

Slide 4

Slide 4 text

Du PHP dans du JS

Slide 5

Slide 5 text

PHPception UX répond à un(e) besoin / envie: Faire du frontend en tant que dev back aisément UX implémente ce besoin via une API PHP optionnelle exposée au frontend via Twig Traduction niaise: Je veux faire du React sans JSX via PHP

Slide 6

Slide 6 text

La théorie, c’pratique UX est une initiative, voyez cela comme un coffre à jouet, débrouillez-vous avec ce que l’on vous offre Au fond, le tout n’est qu’une décoration “++” de Stimulus / Turbo Une classe, un composant, simple, basique … Enfin, oui et non.

Slide 7

Slide 7 text

Sandwich time Classe PHP (#[As*Component])* Template Twig Contrôleur Stimulus Contrôleur personnalisé Couche UX / Twig / Sf Couche Stimulus Librairies externes *Oui, les composants anonymes existent, c’pas le débat

Slide 8

Slide 8 text

En pratique

Slide 9

Slide 9 text

Tout cramer

Slide 10

Slide 10 text

Migrer, en secret Migration d’un dashboard de rédaction pour LEP, backend en Symfony / JS maison / UX JS complexe et découpé en “modules” (aka “composants React” sans React) Objectif : Intégrer une recherche via moteur de recherche avec failover sur la DB (Postgres)

Slide 11

Slide 11 text

On est mal chef Formulaire de recherche Résumé d’une publication Filtres Filtres Filtres Datepicker Pagination Pagination rapide Indicateurs Limite Icon Résumé d’une publication Icon Résumé d’une publication Icon Résumé d’une publication Icon Actions Actions Actions Actions

Slide 12

Slide 12 text

Houdini (version 2024) Formulaire de recherche Résumé d’une publication Filtres Filtres Filtres Datepicker LiveComponent TwigComponent / Template Pagination Pagination rapide Indicateurs Limite Icon Résumé d’une publication Icon Résumé d’une publication Icon Résumé d’une publication Icon Actions Actions Actions Actions

Slide 13

Slide 13 text

Hold on, wait a minute Communication inter-composants, suivi d’état, morphing, “sous-events”, what the hell?! Si la recherche “filtre”, les filtres doivent aussi réduire le scope, idem pour la limite, le tout combiné si possible. Comment fait-on communiquer tout ça sans imploser en plein vol ?

Slide 14

Slide 14 text

Le doute m’habite Formulaire de recherche Résumé d’une publication Filtres Filtres Filtres Datepicker Trigger Pagination Pagination rapide Indicateurs Limite Icon Résumé d’une publication Icon Résumé d’une publication Icon Résumé d’une publication Icon Receiver Actions Actions Actions Actions

Slide 15

Slide 15 text

Douter, c’est tester

Slide 16

Slide 16 text

ExperimentationHub Première ébauche avec X composants s’écoutant entre eux Performances aux fraises, zéro stabilité, découpage trop fin Gestion des ids catastrophique (f*** conventions), morphing en carafe data-skip-morph to the rescue, enfin … Si X composant s’écoutent, privilégier (si possible) les composants nested Si le composant Y dépend de X et que Z update Y, quid de X ?

Slide 17

Slide 17 text

Are you listening? La recherche coordonne le tout (enfin, les filtres aussi) Emission d’un event “search” qui est écouté par un seul composant Si un composant enfant effectue une MAJ via un event, on recalcule tout Emission vers composant spécifique Si le composant ne déclenche pas un nouveau rendu, on est mal X petits composants qui hérite des données du composant maître Reste la solution du debouncing mais perte de précision

Slide 18

Slide 18 text

Moment doléances

Slide 19

Slide 19 text

Are you listening? Un composant peut émettre un event écouté par X composants Aucun moyen natif de prioriser les composants déclenchés Si un composant n’a pas terminé son rendu, quid de l’état ? Une solution serait d’avoir une option priority Laisser faire et vérifier l’état dans le controller Stimulus via on() Si X composants à rendre à nouveau, coucou /_batch Si sous-émission, attention aux rendu cumulés

Slide 20

Slide 20 text

What’s a component? Un composant contient des données envoyées à la vue Serialization peu intuitive (serializer, hydrator, prière ?) Méthode ou LiveProp, il faut choisir LiveProp sur types scalaires / DTO Par convention, privilégier les hydrators pour les objets

Slide 21

Slide 21 text

Matrioshka powar Un composant représente une section atomique d’un template Attributs ou LiveProp, là réside la question Rendu en cascade si attributs partagés Utiliser mount ou postMount pour les données complexes Eviter de modifier les données via LiveListener Se méfier de la satanerie diabolique updateFromParent

Slide 22

Slide 22 text

Time to test Plusieurs composants dans un même template ? Oh boy LiveComponent + composants imbriqués, librairie E2E TwigComponent, bridge PHPUnit suffisant Si tests simples, trait InteractsWithLiveComponents Cypress ou Playwright (Panther trop lent) Bien penser aux mocks / spies d’appels réseaux et prier

Slide 23

Slide 23 text

What about… speed? Chaque rendu déclenche un appel kernel, résolution des attributs / metadata, etc Limiter les appels cumulés sur un seul template Defer / Lazy, tout dépend du contexte Si composants caché, lazy est ton ami Désactiver le morphing si composants enfants / complexes En pratique, UX est lent, adaptez-vous

Slide 24

Slide 24 text

Fini de râler ?

Slide 25

Slide 25 text

It depends, a lot… Symfony UX est une bonne idée mais la mise en pratique reste ardue Si votre application vit très bien sans, passez votre chemin Doliprane (ou Efferalgan), 3 fois par jour, la documentation et du café / thé Si vous êtes sur une refonte, réfléchissez bien et faites un POC, ça coûte rien (enfin …)

Slide 26

Slide 26 text

Des bisous