Retour au blog

Signals en JavaScript: La Proposition TC39 Qui Pourrait Apporter la Reactivite Native au Langage

Salut HaWkers, une proposition qui gagne du terrain au TC39 pourrait fondamentalement changer la facon dont nous construisons des interfaces reactives en JavaScript. Les Signals, une primitive de reactivite deja utilisee par Angular, Vue, Solid et Svelte, est en cours d examen pour inclusion dans la specification officielle d ECMAScript.

Si vous travaillez avec le frontend moderne, cette proposition merite votre attention. Comprenons ce que sont les Signals, comment fonctionne la proposition et ce que cela signifie pour l avenir du developpement web.

Que Sont Les Signals

Les Signals sont des primitives de reactivite qui permettent de creer des valeurs qui notifient automatiquement les dependants lorsqu elles changent. Pensez a eux comme des variables intelligentes qui savent qui les utilise.

Le Concept de Base

L idee fondamentale est simple mais puissante:

// Pseudocode illustratif du concept
const count = signal(0);        // Cree un signal avec valeur initiale 0
const doubled = computed(() => count.value * 2);  // Derive automatiquement

console.log(doubled.value);     // 0
count.value = 5;                // Change le signal
console.log(doubled.value);     // 10 - automatiquement mis a jour

Pourquoi Les Signals Sont Importants

Problemes que les Signals resolvent:

  1. Mises a jour granulaires: Au lieu de re-rendre des composants entiers, seul ce qui depend de la valeur change

  2. Synchronisation automatique: Les valeurs derivees sont toujours coherentes avec leurs sources

  3. Performance previsible: Le systeme sait exactement ce qui doit etre mis a jour

  4. Modele mental plus simple: Moins de concepts que des systemes comme Redux

La Proposition TC39

La proposition de Signals pour JavaScript est developpee de maniere collaborative entre les representants de divers frameworks.

Qui Est Implique

Auteurs de la proposition:

  • Rob Eisenberg (Microsoft/Angular)
  • Daniel Ehrenberg (Bloomberg/Igalia)
  • Contributions des mainteneurs de Vue, Solid, Svelte

Objectif declare:

"Creer une base commune de reactivite qui permet l interoperabilite entre les frameworks et reduit la duplication de code."

Ce Que La Proposition Inclut

La proposition definit deux primitives principales:

Signal.State:

// Signal de base qui stocke une valeur
const counter = new Signal.State(0);

// Lecture de la valeur
console.log(counter.get()); // 0

// Ecriture de la valeur
counter.set(counter.get() + 1);
console.log(counter.get()); // 1

Signal.Computed:

const firstName = new Signal.State("John");
const lastName = new Signal.State("Doe");

// Computed qui derive d autres signals
const fullName = new Signal.Computed(() => {
  return `${firstName.get()} ${lastName.get()}`;
});

console.log(fullName.get()); // "John Doe"

firstName.set("Jane");
console.log(fullName.get()); // "Jane Doe" - automatiquement mis a jour

Ce Qui N Est PAS Dans La Proposition

Important de comprendre les limites:

Non inclus:

  • Systeme d effets (side effects)
  • Batching automatique
  • Integration DOM
  • Planification des mises a jour

Pourquoi?

"La proposition est intentionnellement minimale pour permettre aux frameworks d implementer leurs propres semantiques sur la base commune."

Comment Les Frameworks Utilisent Deja Les Signals

Pour comprendre la proposition, il est utile de voir comment les frameworks existants implementent la reactivite.

Angular Signals

Angular a officiellement adopte les Signals dans les versions recentes:

import { signal, computed, effect } from '@angular/core';

@Component({
  template: `
    <button (click)="increment()">
      Count: {{ count() }}
    </button>
    <p>Double: {{ doubleCount() }}</p>
  `
})
export class CounterComponent {
  count = signal(0);
  doubleCount = computed(() => this.count() * 2);

  increment() {
    this.count.update(value => value + 1);
  }

  constructor() {
    effect(() => {
      console.log(`Count changed to: ${this.count()}`);
    });
  }
}

Vue Reactivity

Vue 3 utilise un systeme similaire appele refs:

import { ref, computed, watchEffect } from 'vue';

const count = ref(0);
const doubled = computed(() => count.value * 2);

watchEffect(() => {
  console.log(`Count is now: ${count.value}`);
});

// Dans le template: {{ count }} et {{ doubled }}

SolidJS Signals

SolidJS a ete pionnier des signals pour le frontend:

import { createSignal, createEffect, createMemo } from 'solid-js';

function Counter() {
  const [count, setCount] = createSignal(0);
  const doubled = createMemo(() => count() * 2);

  createEffect(() => {
    console.log(`Count changed to: ${count()}`);
  });

  return (
    <button onClick={() => setCount(c => c + 1)}>
      Count: {count()} | Doubled: {doubled()}
    </button>
  );
}

Avantages de la Standardisation

Pourquoi inclure les Signals dans le langage au lieu de laisser les choses comme elles sont?

Interoperabilite Entre Frameworks

Actuellement, les signals de differents frameworks sont incompatibles:

Probleme actuel:

  • Un signal Angular ne fonctionne pas dans Vue
  • Les composants de differents frameworks ne partagent pas l etat
  • Les bibliotheques doivent choisir quel systeme supporter

Avec la standardisation:

  • Une base commune permettrait l interoperabilite
  • Les bibliotheques pourraient fonctionner avec n importe quel framework
  • La migration entre frameworks serait plus simple

Reduction de la Taille du Bundle

Chaque framework charge sa propre implementation de reactivite:

Tailles actuelles des implementations:

  • Angular Signals: ~8KB
  • Vue Reactivity: ~12KB
  • SolidJS: ~7KB
  • Preact Signals: ~3KB

Avec une implementation native:

  • Zero KB supplementaire (partie du runtime)
  • Optimisations du moteur possibles
  • Performance potentiellement meilleure

Modele Mental Unifie

Les developpeurs apprennent le concept une fois:

Actuellement:

  • Chaque framework a une nomenclature differente
  • Les APIs varient (get/set vs .value vs fonction)
  • Comportements subtilement differents

Avec un standard:

  • Un concept, une API
  • Documentation centralisee
  • Transfert de connaissances simplifie

Defis et Controverses

La proposition n est pas unanime. Il y a des debats importants dans la communaute.

Le Debat React

React n utilise pas les Signals en interne:

Position de l equipe React:

  • Preferent le modele d immutabilite
  • Les Signals peuvent encourager la mutation
  • Complexite supplementaire pour les cas d utilisation de React

Contre-argument:

  • React pourrait implementer une couche sur les Signals
  • Pas obligatoire a utiliser, juste disponible
  • D autres patterns existent aussi (classes, closures)

Complexite de la Specification

Certains soutiennent que les Signals sont trop opines pour le langage:

Preoccupations:

  • JavaScript n a jamais eu de primitives UI avant
  • Peut encourager des patterns specifiques
  • L implementation du moteur est complexe

Reponse des auteurs:

  • Les Signals sont utiles au-dela de l UI (observables, sync de donnees)
  • La proposition est minimale et extensible
  • Des primitives complexes existent deja (Proxy, WeakMap)

Performance Dans Les Cas Extremes

Les systemes reactifs peuvent avoir un overhead:

Problemes potentiels:

  • Le suivi des dependances a un cout
  • Beaucoup de signals = beaucoup de memoire
  • Cascades de mises a jour

Attenuations proposees:

  • Evaluation paresseuse par defaut
  • Batching des notifications
  • References faibles pour le nettoyage

Exemple Pratique: Implementation d un Formulaire

Voyez comment les Signals natifs pourraient fonctionner dans un scenario reel:

// Avec la proposition, ce serait quelque chose comme:
const form = {
  email: new Signal.State(''),
  password: new Signal.State(''),
  confirmPassword: new Signal.State('')
};

// Validations derivees
const emailValid = new Signal.Computed(() => {
  const email = form.email.get();
  return email.includes('@') && email.includes('.');
});

const passwordsMatch = new Signal.Computed(() => {
  return form.password.get() === form.confirmPassword.get();
});

const formValid = new Signal.Computed(() => {
  return emailValid.get() &&
         form.password.get().length >= 8 &&
         passwordsMatch.get();
});

// Utilisation dans un framework fictif
function renderForm() {
  return html`
    <form>
      <input
        type="email"
        value=${form.email.get()}
        oninput=${e => form.email.set(e.target.value)}
        class=${emailValid.get() ? 'valid' : 'invalid'}
      />

      <input
        type="password"
        value=${form.password.get()}
        oninput=${e => form.password.set(e.target.value)}
      />

      <input
        type="password"
        value=${form.confirmPassword.get()}
        oninput=${e => form.confirmPassword.set(e.target.value)}
        class=${passwordsMatch.get() ? '' : 'error'}
      />

      <button disabled=${!formValid.get()}>
        Submit
      </button>
    </form>
  `;
}

Timeline et Statut Actuel

Ou en est la proposition dans le processus TC39.

Etape Actuelle

Statut: Stage 1 (Proposal)

Cela signifie:

  • Le comite est d accord que le probleme vaut la peine d etre resolu
  • La proposition est activement developpee
  • Des changements significatifs sont encore possibles
  • Pas prete pour l implementation

Prochaines Etapes

Pour Stage 2:

  • Specification initiale complete
  • Semantique bien definie
  • Exemple d implementation

Pour Stage 3:

  • Implementation dans au moins un moteur
  • Retour d experience d utilisation reelle
  • Specification stable

Pour Stage 4:

  • Implementations multiples
  • Tests de conformite
  • Approbation finale

Prediction Conservatrice

Timeline estimee:

  • 2026: Raffinement de la proposition
  • 2027: Possible Stage 2/3
  • 2028+: Implementations dans les navigateurs
  • 2029+: Utilisation en production securisee

Comment Se Preparer

Meme si la proposition prend du temps, vous pouvez vous preparer.

Apprenez Les Signals Maintenant

Utilisez l une des implementations existantes:

// Preact Signals - tres similaire a la proposition
import { signal, computed, effect } from '@preact/signals';

const count = signal(0);
const doubled = computed(() => count.value * 2);

effect(() => {
  console.log(doubled.value);
});

Comprenez Les Fondamentaux

Concepts qui se transferent a n importe quelle implementation:

  • Suivi automatique des dependances
  • Evaluation paresseuse vs eager
  • Batching et planification
  • Nettoyage et cycle de vie

Reflexion Finale

La proposition de Signals au TC39 represente une possible evolution fondamentale de JavaScript pour les applications reactives. Unifier la facon dont les frameworks gerent la reactivite pourrait simplifier l ecosysteme et ameliorer l interoperabilite.

Points cles:

  • Les Signals sont des primitives de reactivite deja prouvees dans les frameworks
  • La proposition TC39 cherche la standardisation, pas le remplacement des frameworks
  • Les avantages incluent l interoperabilite et la reduction de code
  • La timeline est longue - probablement 2028+ pour l utilisation en production
  • Apprendre les signals maintenant vous prepare pour l avenir

Peu importe quand (ou si) la proposition est approuvee, comprendre la reactivite basee sur les signals est deja precieux aujourd hui. Angular, Vue, Solid et d autres frameworks ont deja adopte le pattern, et la tendance continue de croitre.

Si vous voulez explorer davantage les nouveautes de JavaScript moderne, je vous recommande de consulter un autre article: ES2026: Les Nouvelles Features Qui Vont Changer Votre Code ou vous decouvrirez d autres propositions importantes en cours.

Allons-y! 🦅

Commentaires (0)

Cet article n'a pas encore de commentaires. Soyez le premier!

Ajouter des commentaires