<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>seb</title>
    <link>https://blogz.zaclys.com/seb/</link>
    <description></description>
    <pubDate>Sat, 02 May 2026 09:46:11 +0200</pubDate>
    <item>
      <title>SolidJS 2.0 est async first : qu&#39;est ce que ça signifie ?</title>
      <link>https://blogz.zaclys.com/seb/solidjs-2-0-est-async-first-quest-ce-que-ca-signifie</link>
      <description>&lt;![CDATA[SolidJS 2.0 is Async First&#xA;&#xA;La première version beta de SolidJS 2.0 est sortie la semaine dernière. Ryan Carniato a fait un stream pour expliquer en quoi on passait d&#39;une version sync first à une version async first. Il a notamment présenté plusieurs exemples qui démontrent la simplicité de l&#39;utilisation des expressions asynchrones dans SolidJS 2.0. On va voir ici un cas d&#39;utilisation possible sur la récupération d&#39;une liste paginée.&#xA;&#xA;!--more--&#xA;&#xA;Spécificités de l&#39;asynchronisme&#xA;&#xA;Quand on récupère une donnée de manière synchrone, on n&#39;a pas de question à se poser, la donnée est disponible et on l&#39;utilise. Pour une donnée asynchrone par contre il y a plusieurs problèmes :&#xA;&#xA;avant de récupérer la donnée pour la première fois, la donnée n&#39;est pas initialisée&#xA;il y a un temps d&#39;attente avant de récupérer la donnée pendant lequel on peut vouloir afficher un indicateur visuel à l&#39;utilisateur&#xA;quand on met à jour la donnée (par exemple passage de la première à la deuxième page d&#39;une liste) on va en général vouloir continuer d&#39;afficher les données de la première page tant que les données de la deuxième page ne sont pas disponibles mais aussi afficher un indicateur pour dire qu&#39;on est en train de récupérer les données suivantes&#xA;&#xA;Il y a également une problématique de cohérence, si un résultat d&#39;une opération asynchrone dépend d&#39;une donnée synchrone (liée à une saisie par l&#39;utilisateur par exemple) on veut en général n&#39;afficher la nouvelle valeur de la donnée synchrone que lorsque le calcul de la donnée asynchrone est terminé pour avoir une incohérence entre les deux.&#xA;&#xA;Comment cela est géré jusqu&#39;à présent&#xA;&#xA;Jusqu&#39;à présent, le fonctionnement spécifique de l&#39;asynchronisme faisait que l&#39;on avait un traitement différent entre la donnée synchrone et la donnée asynchrone. On a vu par exemple émerger Tanstack Query pour cela. L&#39;arrivée du hook  use en React a également permis de simplifier la gestion des données asynchrones.&#xA;&#xA;Au niveau de SolidJS 1.0 on a createSignal pour les données synchrones et createResource pour les données asynchrones.&#xA;&#xA;La gestion des données asynchrones se simplifie au cours du temps grâce à de nouvelles primitives mais on a quand même un code spécifique, c&#39;est en cela que l&#39;on n&#39;est pas async first.&#xA;&#xA;Le changement de paradigme&#xA;&#xA;L&#39;idée avec Solid 2.0 c&#39;est d&#39;avoir un paradigme qui traite les données synchrones et asynchrones de la même manière. L&#39;idée derrière cela c&#39;est de se dire que si j&#39;ai du code qui fonctionne avec des données synchrones, le même code fonctionne aussi avec des données asynchrones.&#xA;&#xA;Dans un des exemple de Ryan on a un code de ce type&#xA;&#xA;function App() {&#xA;  const [value, setValue] = createSignal(1);&#xA;  const increment = () =  setValue((prev) =  prev + 1);&#xA;  const result = createMemo(() =  compute(value()));&#xA;&#xA;  return (&#xA;    div&#xA;      button type=&#34;button&#34; onClick={increment}{latest(value)}/button&#xA;      p class={[{ pending: isPending(result) }]}Result for {value()} = {result().toFixed(3)}/p&#xA;    /div&#xA;  );&#xA;}&#xA;Ce code fonctionne de la même manière que la fonction compute soit une fonction synchrone ou asynchrone. Dans les deux cas, la fonction createMemo va retourner un type Accessornumber.&#xA;&#xA;Un point important à noter est que la valeur value ne sera mise à jour que lorsque la propriété dérivée result aura pu être calculée et donc quand compute aura retourné un résultat. L&#39;idée c&#39;est d&#39;avoir une consistance entre toutes les données pour éviter d&#39;afficher un résultat qui ne correspond pas à la valeur courante.&#xA;&#xA;Pour traiter les besoins spécifiques à l&#39;asynchrone Solid va fournir plusieurs éléments&#xA;&#xA;on a un composant Loading qui correspond au Suspense de React ou de Solid 1.0 qui va afficher un fallback lorsque la donnée n&#39;est pas encore initialisée (au premier appel). Ce fallback ne sera par contre pas affiché quand on récupérera une nouvelle valeur&#xA;le helper isPending va permettre de savoir si un refetch est en cours, dans notre exemple on pourrait faire isPending(result) pour savoir si on est en cours de calcul&#xA;le helper latest(value) va permettre d&#39;avoir accès à la nouvelle valeur de value avant d&#39;avoir la réponse de result, cela permet d&#39;afficher cette valeur dès que l&#39;on clique au niveau du bouton&#xA;&#xA;Cas d&#39;usage : liste paginée&#xA;&#xA;A partir de ce nouveau mode de fonctionnement on peut très facilement implémenter une liste paginée avec le code suivant&#xA;&#xA;const App = () =  {&#xA;  const [page, setPage] = createSignal(1);&#xA;  const result = createMemo(() =  getResults(page()));&#xA;&#xA;  return (&#xA;    div&#xA;      h1Demo/h1&#xA;      button disabled={latest(page) === 1} onClick={() = setPage(prev =  prev - 1)}  Previous/button&#xA;      Page {latest(page)}&#xA;      button onClick={() = setPage(prev =  prev + 1)}  Next/button&#xA;      h2Result /h2&#xA;        Loading fallback=&#34;Loading...&#34;&#xA;          div class={[{loading: isPending(result)}]}&#xA;            For each={result()}&#xA;              {(value) =  p{value()}/p}&#xA;            /For&#xA;            p{result().length} items/p&#xA;          /div&#xA;        /Loading&#xA;    /div&#xA;  );&#xA;};&#xA;On a automatiquement un loader au premier chargement de la liste puis la classe loading qui sera appliqué à chaque changement de page.&#xA;&#xA;Conclusion&#xA;&#xA;Cet exemple simple présente les apports du nouveau paradigme &#34;Async First&#34; de SolidJS 2.0. On pourra voir par la suite que cela amène d&#39;autres avantages, notamment la possibilité d&#39;initialiser les signaux avec une fonction réactive.&#xA;&#xA;Par rapport à Solid 1.0, on simplifie l&#39;API du framework puisque l&#39;on utilise systématiquement createSignal plutôt que d&#39;utiliser une autre API createResource pour les données asynchrones.&#xA;&#xA;L&#39;intégration de Solid 2.0 avec SolidStart n&#39;est pas encore disponible mais cela veut également dire que createAsync va disparaître et que l&#39;on pourra utiliser createMemo pour appeler une server function.&#xA;&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://zzz.zaclys.com/download.php?z=3&amp;doc_id=8465401" alt="SolidJS 2.0 is Async First"></p>

<p>La première version beta de SolidJS 2.0 est sortie la semaine dernière. Ryan Carniato a fait un stream pour expliquer en quoi on passait d&#39;une version sync first à une version async first. Il a notamment présenté plusieurs exemples qui démontrent la simplicité de l&#39;utilisation des expressions asynchrones dans SolidJS 2.0. On va voir ici un cas d&#39;utilisation possible sur la récupération d&#39;une liste paginée.</p>



<h2 id="spécificités-de-l-asynchronisme" id="spécificités-de-l-asynchronisme">Spécificités de l&#39;asynchronisme</h2>

<p>Quand on récupère une donnée de manière synchrone, on n&#39;a pas de question à se poser, la donnée est disponible et on l&#39;utilise. Pour une donnée asynchrone par contre il y a plusieurs problèmes :</p>
<ul><li>avant de récupérer la donnée pour la première fois, la donnée n&#39;est pas initialisée</li>
<li>il y a un temps d&#39;attente avant de récupérer la donnée pendant lequel on peut vouloir afficher un indicateur visuel à l&#39;utilisateur</li>
<li>quand on met à jour la donnée (par exemple passage de la première à la deuxième page d&#39;une liste) on va en général vouloir continuer d&#39;afficher les données de la première page tant que les données de la deuxième page ne sont pas disponibles mais aussi afficher un indicateur pour dire qu&#39;on est en train de récupérer les données suivantes</li></ul>

<p>Il y a également une problématique de cohérence, si un résultat d&#39;une opération asynchrone dépend d&#39;une donnée synchrone (liée à une saisie par l&#39;utilisateur par exemple) on veut en général n&#39;afficher la nouvelle valeur de la donnée synchrone que lorsque le calcul de la donnée asynchrone est terminé pour avoir une incohérence entre les deux.</p>

<h2 id="comment-cela-est-géré-jusqu-à-présent" id="comment-cela-est-géré-jusqu-à-présent">Comment cela est géré jusqu&#39;à présent</h2>

<p>Jusqu&#39;à présent, le fonctionnement spécifique de l&#39;asynchronisme faisait que l&#39;on avait un traitement différent entre la donnée synchrone et la donnée asynchrone. On a vu par exemple émerger <a href="https://tanstack.com/query/latest" rel="nofollow">Tanstack Query</a> pour cela. L&#39;arrivée du hook  <a href="https://react.dev/reference/react/use" rel="nofollow">use</a> en React a également permis de simplifier la gestion des données asynchrones.</p>

<p>Au niveau de SolidJS 1.0 on a <code>createSignal</code> pour les données synchrones et <code>createResource</code> pour les données asynchrones.</p>

<p>La gestion des données asynchrones se simplifie au cours du temps grâce à de nouvelles primitives mais on a quand même un code spécifique, c&#39;est en cela que l&#39;on n&#39;est pas async first.</p>

<h2 id="le-changement-de-paradigme" id="le-changement-de-paradigme">Le changement de paradigme</h2>

<p>L&#39;idée avec Solid 2.0 c&#39;est d&#39;avoir un paradigme qui traite les données synchrones et asynchrones de la même manière. L&#39;idée derrière cela c&#39;est de se dire que si j&#39;ai du code qui fonctionne avec des données synchrones, le même code fonctionne aussi avec des données asynchrones.</p>

<p>Dans un des exemple de Ryan on a un code de ce type</p>

<pre><code>function App() {
  const [value, setValue] = createSignal(1);
  const increment = () =&gt; setValue((prev) =&gt; prev + 1);
  const result = createMemo(() =&gt; compute(value()));

  return (
    &lt;div&gt;
      &lt;button type=&#34;button&#34; onClick={increment}&gt;{latest(value)}&lt;/button&gt;
      &lt;p class={[{ pending: isPending(result) }]}&gt;Result for {value()} = {result().toFixed(3)}&lt;/p&gt;
    &lt;/div&gt;
  );
}
</code></pre>

<p>Ce code fonctionne de la même manière que la fonction <code>compute</code> soit une fonction synchrone ou asynchrone. Dans les deux cas, la fonction <code>createMemo</code> va retourner un type <code>Accessor&lt;number&gt;</code>.</p>

<p>Un point important à noter est que la valeur <code>value</code> ne sera mise à jour que lorsque la propriété dérivée <code>result</code> aura pu être calculée et donc quand <code>compute</code> aura retourné un résultat. L&#39;idée c&#39;est d&#39;avoir une consistance entre toutes les données pour éviter d&#39;afficher un résultat qui ne correspond pas à la valeur courante.</p>

<p>Pour traiter les besoins spécifiques à l&#39;asynchrone Solid va fournir plusieurs éléments</p>
<ul><li>on a un composant <code>Loading</code> qui correspond au <code>Suspense</code> de React ou de Solid 1.0 qui va afficher un fallback lorsque la donnée n&#39;est pas encore initialisée (au premier appel). Ce fallback ne sera par contre pas affiché quand on récupérera une nouvelle valeur</li>
<li>le helper <code>isPending</code> va permettre de savoir si un refetch est en cours, dans notre exemple on pourrait faire <code>isPending(result)</code> pour savoir si on est en cours de calcul</li>
<li>le helper <code>latest(value)</code> va permettre d&#39;avoir accès à la nouvelle valeur de <code>value</code> avant d&#39;avoir la réponse de <code>result</code>, cela permet d&#39;afficher cette valeur dès que l&#39;on clique au niveau du bouton</li></ul>

<h2 id="cas-d-usage-liste-paginée" id="cas-d-usage-liste-paginée">Cas d&#39;usage : liste paginée</h2>

<p>A partir de ce nouveau mode de fonctionnement on peut très facilement implémenter une liste paginée avec le code suivant</p>

<pre><code>const App = () =&gt; {
  const [page, setPage] = createSignal(1);
  const result = createMemo(() =&gt; getResults(page()));

  return (
    &lt;div&gt;
      &lt;h1&gt;Demo&lt;/h1&gt;
      &lt;button disabled={latest(page) === 1} onClick={() =&gt; setPage(prev =&gt; prev - 1)}&gt;Previous&lt;/button&gt;
      Page {latest(page)}
      &lt;button onClick={() =&gt; setPage(prev =&gt; prev + 1)}&gt;Next&lt;/button&gt;
      &lt;h2&gt;Result &lt;/h2&gt;
        &lt;Loading fallback=&#34;Loading...&#34;&gt;
          &lt;div class={[{loading: isPending(result)}]}&gt;
            &lt;For each={result()}&gt;
              {(value) =&gt; &lt;p&gt;{value()}&lt;/p&gt;}
            &lt;/For&gt;
            &lt;p&gt;{result().length} items&lt;/p&gt;
          &lt;/div&gt;
        &lt;/Loading&gt;
    &lt;/div&gt;
  );
};
</code></pre>

<p>On a automatiquement un loader au premier chargement de la liste puis la classe <code>loading</code> qui sera appliqué à chaque changement de page.</p>

<h2 id="conclusion" id="conclusion">Conclusion</h2>

<p>Cet exemple simple présente les apports du nouveau paradigme “Async First” de SolidJS 2.0. On pourra voir par la suite que cela amène d&#39;autres avantages, notamment la possibilité d&#39;initialiser les signaux avec une fonction réactive.</p>

<p>Par rapport à Solid 1.0, on simplifie l&#39;API du framework puisque l&#39;on utilise systématiquement <code>createSignal</code> plutôt que d&#39;utiliser une autre API <code>createResource</code> pour les données asynchrones.</p>

<p>L&#39;intégration de Solid 2.0 avec SolidStart n&#39;est pas encore disponible mais cela veut également dire que <code>createAsync</code> va disparaître et que l&#39;on pourra utiliser <code>createMemo</code> pour appeler une server function.</p>
]]></content:encoded>
      <guid>https://blogz.zaclys.com/seb/solidjs-2-0-est-async-first-quest-ce-que-ca-signifie</guid>
      <pubDate>Tue, 10 Mar 2026 20:40:12 +0100</pubDate>
    </item>
    <item>
      <title>Comment remplacer pipewire par pulseaudio sur Linux Mint 22</title>
      <link>https://blogz.zaclys.com/seb/comment-remplacer-pipewire-par-pulseaudio-sur-linux-mint-22</link>
      <description>&lt;![CDATA[Au niveau du son, Linux Mint 22 utilise par défaut pipewire. Sur mon portable Dell XPS de 2019, le son &#34;craque&#34; avec pipewire. J&#39;ai essayé de modifier la configuration sans succès et j&#39;ai donc décidé de revenir à pulseaudio. On trouve pas mal de tutos pour remplacer pulseaudio par pipewire mais pas beaucoup pour faire l&#39;inverse.&#xA;&#xA;!--more--&#xA;&#xA;Voici la procédure que j&#39;ai suivie en me basant sur cette page qui présente la procédure inverse.&#xA;&#xA;Tout d&#39;abord on désactive pipewire&#xA;&#xA;systemctl --user --now disable pipewire pipewire-pulse wireplumber pipewire.socket pipewire-pulse.socket&#xA;systemctl --user mask pipewire pipewire-pulse wireplumber&#xA;&#xA;L&#39;icône du son doit alors disparaître de la barre des tâches.&#xA;&#xA;Ensuite on installe et on active pulseaudio&#xA;&#xA;sudo apt install pulseaudio&#xA;systemctl --user --now enable pulseaudio.service pulseaudio.socket&#xA;&#xA;Là on vérifie que l&#39;icône du son est bien revenue et on peut lire un fichier audio ou une vidéo qui auparavant posait problème pour vérifier que le problème est bien résolu.&#xA;&#xA;Ensuite on peut supprimer pipewire&#xA;&#xA;sudo apt remove pipewire pipewire-pulse wireplumber&#xA;sudo apt autoremove&#xA;&#xA;Pour être sûr de la config on peut utiliser la commande suivante&#xA;&#xA;pactl info&#xA;&#xA;qui doit indiquer Nom du serveur : pulseaudio.]]&gt;</description>
      <content:encoded><![CDATA[<p>Au niveau du son, Linux Mint 22 utilise par défaut <a href="https://www.pipewire.org/" rel="nofollow">pipewire</a>. Sur mon portable Dell XPS de 2019, le son “craque” avec pipewire. J&#39;ai essayé de modifier la configuration sans succès et j&#39;ai donc décidé de revenir à pulseaudio. On trouve pas mal de tutos pour remplacer pulseaudio par pipewire mais pas beaucoup pour faire l&#39;inverse.</p>



<p>Voici la procédure que j&#39;ai suivie en me basant sur <a href="https://github.com/orgs/linuxmint/discussions/462" rel="nofollow">cette page</a> qui présente la procédure inverse.</p>

<p>Tout d&#39;abord on désactive pipewire</p>

<pre><code class="language-bash">systemctl --user --now disable pipewire pipewire-pulse wireplumber pipewire.socket pipewire-pulse.socket
systemctl --user mask pipewire pipewire-pulse wireplumber
</code></pre>

<p>L&#39;icône du son doit alors disparaître de la barre des tâches.</p>

<p>Ensuite on installe et on active pulseaudio</p>

<pre><code class="language-bash">sudo apt install pulseaudio
systemctl --user --now enable pulseaudio.service pulseaudio.socket
</code></pre>

<p>Là on vérifie que l&#39;icône du son est bien revenue et on peut lire un fichier audio ou une vidéo qui auparavant posait problème pour vérifier que le problème est bien résolu.</p>

<p>Ensuite on peut supprimer pipewire</p>

<pre><code class="language-bash">sudo apt remove pipewire pipewire-pulse wireplumber
sudo apt autoremove
</code></pre>

<p>Pour être sûr de la config on peut utiliser la commande suivante</p>

<pre><code class="language-bash">pactl info
</code></pre>

<p>qui doit indiquer <code>Nom du serveur : pulseaudio</code>.</p>
]]></content:encoded>
      <guid>https://blogz.zaclys.com/seb/comment-remplacer-pipewire-par-pulseaudio-sur-linux-mint-22</guid>
      <pubDate>Fri, 23 Jan 2026 12:21:41 +0100</pubDate>
    </item>
    <item>
      <title>Quelle stack pour une appli éco-conçue ?</title>
      <link>https://blogz.zaclys.com/seb/quelle-stack-pour-une-appli-eco-concue</link>
      <description>&lt;![CDATA[Eco-conception&#xA;&#xA;Contexte&#xA;&#xA;Durant ma carrière j&#39;ai toujours été intéressé par le sujet de l&#39;éco-conception mais dans aucun de mes postes je n&#39;ai eu la possibilité de passer du temps pour approfondir le sujet et le mettre en place.&#xA;&#xA;Il y a 4 mois j&#39;ai commencé mon premier projet en freelance from scratch. Je me suis posé la question de la stack que je pourrais utiliser pour avoir dès le départ un projet le plus sobre possible.&#xA;&#xA;!--more--&#xA;&#xA;Je développe depuis bientôt 15 ans en javascript puis en typescript, principalement dans l&#39;écosystème React depuis 7 ans. Je ne souhaitais par repartir sur une techno complètement nouvelle donc je voulais trouver quelque chose proche de ce que je connais.&#xA;&#xA;L&#39;appli que je développe est à destination des actionnaires de sociétés d&#39;énergie citoyenne. D&#39;un point de vue technique, pas besoin de SEO, c&#39;est une SPA (Single Page Application) des plus classique.&#xA;&#xA;Les critères que je me suis donné :&#xA;&#xA;limiter l&#39;utilisation du réseau via un bundle le plus petit possible, peu d&#39;assets de petite taille, des appels API efficients&#xA;limiter l&#39;utilisation des ressources sur le serveur via une librairie d&#39;accès à la base de données la plus efficiente possible&#xA;&#xA;Stack retenue&#xA;&#xA;Après quelques recherches et expérimentation j&#39;ai retenu la stack suivante :&#xA;&#xA;SolidStart comme framework fullstack&#xA;Drizzle pour l&#39;accès à la base de données&#xA;Tailwind et DaisyUI pour la partie design&#xA;&#xA;SolidStart&#xA;SolidStart est un framework fullstack basé sur le framework SolidJS. &#xA;&#xA;SolidJS possède deux grands avantages pour moi :&#xA;&#xA;une proximité avec React au niveau de la syntaxe (JSX, composants, ...)&#xA;de très bonnes performances comparées aux autres framework front existants&#xA;&#xA;SolidJS est plus performant que React car par défaut les composants ne se rendent qu&#39;une seule fois. C&#39;est à nous développeur ensuite d&#39;utiliser les signals pour ajouter de la réactivité là où c&#39;est nécessaire.&#xA;&#xA;En plus de cela SolidStart apporte un framework fullstack très productif notamment grâce aux server functions qui permettent un typage fort de bout en bout et une écriture simplifiée des API. La brique de sérialisation &#34;Seroval&#34; est très performante et pour la mise à jour de données les single flight mutation permettent de réduire les allers retours réseau.&#xA;&#xA;Si vous voulez débuter avec SolidStart, je vous conseille de lire cet article sur les bonnes pratiques qui résume bien les points d&#39;attention notamment pour un ex développeur React.&#xA;&#xA;Drizzle&#xA;Pour l&#39;accès aux bases de données j&#39;avais pour habitude d&#39;utiliser un ORM assez classique. En typescript j&#39;ai notamment utilisé MikroORM qui reprend pas mal de concepts d&#39;Hibernate en Java que j&#39;avais utilisé précédemment.&#xA;&#xA;Pour ce projet j&#39;ai décidé de changer pour utiliser Drizzle qui est une surcouche plus fine au dessus de la base de données. L&#39;idée est de s&#39;appuyer plus sur le sql pour diminuer l&#39;overhead de la couche d&#39;accès aux données.&#xA;&#xA;Après plusieurs mois d&#39;utilisation j&#39;avoue être très content de l&#39;outil. Couplé avec SolidStart on arrive à avoir un typage fort de bout en bout qui est très efficace et très pratique.&#xA;&#xA;Tailwind et DaisyUI&#xA;Pour la partie design je préfère en règle générale faire directement du CSS lorsque je travaille avec un UI/UX designer pour pouvoir faire du pixel-perfect. Sur ce projet je n&#39;avais pas ce luxe et j&#39;ai donc cherché une librairie de composants plus ou moins clé en main.&#xA;&#xA;Malgré cela je ne voulais pas quelque chose de trop lourd et au final j&#39;ai fait le choix de DaisyUI qui est une surcouche à Tailwind qui est plutôt légère.&#xA;&#xA;Résultats&#xA;Pour vous donner une idée de la taille de l&#39;application que j&#39;ai développé, elle comporte environ 75 routes et la base de données contient 35 tables. Je dirais que c&#39;est une application de taille moyenne.&#xA;&#xA;Voici quelques métriques en terme de taille de bundle :&#xA;&#xA;Le bundle total de l&#39;app gzippé fait 385 ko dont 153 ko pour la librairie apex-charts qui est utilisée uniquement sur quelques pages qui affichent des graphes&#xA;Pour la plupart des pages de l&#39;app la totalité des données transférées sur le réseau est entre 130 et 200 ko&#xA;le css de l&#39;application fait 20 ko compressé&#xA;&#xA;Si j&#39;active la limitation réseau sur le navigateur pour passer en &#34;Regular 3G&#34;, j&#39;ai un temps de chargement des pages autour de 2,5s et une navigation dans l&#39;application qui est fluide.&#xA;&#xA;Côté serveur je n&#39;ai installé aucun outil de monitoring donc c&#39;est dur de quantifier la charge mais mon appli tourne sans problème sur le plus petit VPS Lite d&#39;Infomaniak.&#xA;&#xA;Conclusion&#xA;Même si l&#39;eco-conception ne s&#39;arrête pas à la taille du bundle client et aux ressources utilisées côté serveur, limiter ces valeurs est une condition nécessaire pour ensuite pouvoir développer une application qui tournera sur n&#39;importe quel terminal client. &#xA;&#xA;Au niveau de  mes choix, j&#39;aurais pu aussi changer de langage et tester par exemple un framework comme Dioxus en Rust mais cela aurait nécessité un apprentissage encore plus en profondeur au détriment de la productivité sans que je sois vraiment capable de mon côté de mesurer les gains obtenus.&#xA;&#xA;Avec le recul de mes 4 premiers mois de développement, les choix que j&#39;ai effectué me paraissent bon pour avoir une application la plus économe en ressources possibles dans l&#39;écosystème typescript. Je trouve que c&#39;est un bon compromis entre sobriété et productivité.&#xA;&#xA;Une fois ces bases mises en place il faut également réfléchir à la façon dont on conçoit l&#39;application pour continuer à avoir une utilisation sobre des ressources par exemple en paginant systématiquement les listes.&#xA;&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://zzz.zaclys.com/download.php?z=2&amp;doc_id=8465209" alt="Eco-conception"></p>

<h2 id="contexte" id="contexte">Contexte</h2>

<p>Durant ma carrière j&#39;ai toujours été intéressé par le sujet de l&#39;éco-conception mais dans aucun de mes postes je n&#39;ai eu la possibilité de passer du temps pour approfondir le sujet et le mettre en place.</p>

<p>Il y a 4 mois j&#39;ai commencé mon premier projet en freelance from scratch. Je me suis posé la question de la stack que je pourrais utiliser pour avoir dès le départ un projet le plus sobre possible.</p>



<p>Je développe depuis bientôt 15 ans en javascript puis en typescript, principalement dans l&#39;écosystème React depuis 7 ans. Je ne souhaitais par repartir sur une techno complètement nouvelle donc je voulais trouver quelque chose proche de ce que je connais.</p>

<p>L&#39;appli que je développe est à destination des actionnaires de sociétés d&#39;énergie citoyenne. D&#39;un point de vue technique, pas besoin de SEO, c&#39;est une SPA (Single Page Application) des plus classique.</p>

<p>Les critères que je me suis donné :</p>
<ul><li>limiter l&#39;utilisation du réseau via un bundle le plus petit possible, peu d&#39;assets de petite taille, des appels API efficients</li>
<li>limiter l&#39;utilisation des ressources sur le serveur via une librairie d&#39;accès à la base de données la plus efficiente possible</li></ul>

<h2 id="stack-retenue" id="stack-retenue">Stack retenue</h2>

<p>Après quelques recherches et expérimentation j&#39;ai retenu la stack suivante :</p>
<ul><li><a href="https://start.solidjs.com/" rel="nofollow">SolidStart</a> comme framework fullstack</li>
<li><a href="https://orm.drizzle.team/" rel="nofollow">Drizzle</a> pour l&#39;accès à la base de données</li>
<li><a href="https://tailwindcss.com/" rel="nofollow">Tailwind</a> et <a href="https://daisyui.com/" rel="nofollow">DaisyUI</a> pour la partie design</li></ul>

<h3 id="solidstart" id="solidstart">SolidStart</h3>

<p>SolidStart est un framework fullstack basé sur le framework <a href="https://www.solidjs.com/" rel="nofollow">SolidJS</a>.</p>

<p>SolidJS possède deux grands avantages pour moi :</p>
<ul><li>une proximité avec React au niveau de la syntaxe (JSX, composants, ...)</li>
<li>de très bonnes performances comparées aux autres framework front existants</li></ul>

<p>SolidJS est plus performant que React car par défaut les composants ne se rendent qu&#39;une seule fois. C&#39;est à nous développeur ensuite d&#39;utiliser les <a href="https://docs.solidjs.com/concepts/signals" rel="nofollow">signals</a> pour ajouter de la réactivité là où c&#39;est nécessaire.</p>

<p>En plus de cela SolidStart apporte un framework fullstack très productif notamment grâce aux <a href="https://docs.solidjs.com/solid-start/building-your-application/data-fetching" rel="nofollow">server functions</a> qui permettent un typage fort de bout en bout et une écriture simplifiée des API. La brique de sérialisation “Seroval” est très performante et pour la mise à jour de données les <a href="https://docs.solidjs.com/solid-start/building-your-application/data-mutation" rel="nofollow">single flight mutation</a> permettent de réduire les allers retours réseau.</p>

<p>Si vous voulez débuter avec SolidStart, je vous conseille de lire <a href="https://www.brenelz.com/posts/solid-js-best-practices/" rel="nofollow">cet article sur les bonnes pratiques</a> qui résume bien les points d&#39;attention notamment pour un ex développeur React.</p>

<h3 id="drizzle" id="drizzle">Drizzle</h3>

<p>Pour l&#39;accès aux bases de données j&#39;avais pour habitude d&#39;utiliser un ORM assez classique. En typescript j&#39;ai notamment utilisé MikroORM qui reprend pas mal de concepts d&#39;Hibernate en Java que j&#39;avais utilisé précédemment.</p>

<p>Pour ce projet j&#39;ai décidé de changer pour utiliser Drizzle qui est une surcouche plus fine au dessus de la base de données. L&#39;idée est de s&#39;appuyer plus sur le sql pour diminuer l&#39;overhead de la couche d&#39;accès aux données.</p>

<p>Après plusieurs mois d&#39;utilisation j&#39;avoue être très content de l&#39;outil. Couplé avec SolidStart on arrive à avoir un typage fort de bout en bout qui est très efficace et très pratique.</p>

<h3 id="tailwind-et-daisyui" id="tailwind-et-daisyui">Tailwind et DaisyUI</h3>

<p>Pour la partie design je préfère en règle générale faire directement du CSS lorsque je travaille avec un UI/UX designer pour pouvoir faire du pixel-perfect. Sur ce projet je n&#39;avais pas ce luxe et j&#39;ai donc cherché une librairie de composants plus ou moins clé en main.</p>

<p>Malgré cela je ne voulais pas quelque chose de trop lourd et au final j&#39;ai fait le choix de DaisyUI qui est une surcouche à Tailwind qui est plutôt légère.</p>

<h2 id="résultats" id="résultats">Résultats</h2>

<p>Pour vous donner une idée de la taille de l&#39;application que j&#39;ai développé, elle comporte environ 75 routes et la base de données contient 35 tables. Je dirais que c&#39;est une application de taille moyenne.</p>

<p>Voici quelques métriques en terme de taille de bundle :</p>
<ul><li>Le bundle total de l&#39;app gzippé fait 385 ko dont 153 ko pour la librairie apex-charts qui est utilisée uniquement sur quelques pages qui affichent des graphes</li>
<li>Pour la plupart des pages de l&#39;app la totalité des données transférées sur le réseau est entre 130 et 200 ko</li>
<li>le css de l&#39;application fait 20 ko compressé</li></ul>

<p>Si j&#39;active la limitation réseau sur le navigateur pour passer en “Regular 3G”, j&#39;ai un temps de chargement des pages autour de 2,5s et une navigation dans l&#39;application qui est fluide.</p>

<p>Côté serveur je n&#39;ai installé aucun outil de monitoring donc c&#39;est dur de quantifier la charge mais mon appli tourne sans problème sur le plus petit <a href="https://www.infomaniak.com/fr/hebergement/vps-lite" rel="nofollow">VPS Lite d&#39;Infomaniak</a>.</p>

<h2 id="conclusion" id="conclusion">Conclusion</h2>

<p>Même si l&#39;eco-conception ne s&#39;arrête pas à la taille du bundle client et aux ressources utilisées côté serveur, limiter ces valeurs est une condition nécessaire pour ensuite pouvoir développer une application qui tournera sur n&#39;importe quel terminal client.</p>

<p>Au niveau de  mes choix, j&#39;aurais pu aussi changer de langage et tester par exemple un framework comme <a href="https://dioxuslabs.com/" rel="nofollow">Dioxus</a> en Rust mais cela aurait nécessité un apprentissage encore plus en profondeur au détriment de la productivité sans que je sois vraiment capable de mon côté de mesurer les gains obtenus.</p>

<p>Avec le recul de mes 4 premiers mois de développement, les choix que j&#39;ai effectué me paraissent bon pour avoir une application la plus économe en ressources possibles dans l&#39;écosystème typescript. Je trouve que c&#39;est un bon compromis entre sobriété et productivité.</p>

<p>Une fois ces bases mises en place il faut également réfléchir à la façon dont on conçoit l&#39;application pour continuer à avoir une utilisation sobre des ressources par exemple en paginant systématiquement les listes.</p>
]]></content:encoded>
      <guid>https://blogz.zaclys.com/seb/quelle-stack-pour-une-appli-eco-concue</guid>
      <pubDate>Tue, 13 Jan 2026 11:23:25 +0100</pubDate>
    </item>
  </channel>
</rss>