Comparaison
Comparez les moteurs en fonction du résultat attendu, des garanties de sécurité et du coût d’exécution.
Quand choisir Vincle#
Vincle transforme le JSX en HTML serveur. React ajoute un modèle de composants et de réconciliation client ; les moteurs de templates classiques proposent d’autres syntaxes ou compromis de typage.
L’échappement est systématique#
L’échappement de Vincle est activé par défaut et dépend de la position. Seul un appel explicite à raw() ou rawUrl() élargit la frontière de confiance.
import { raw } from "@vincle/core";
<div>{userInput}</div> {/* always escaped */}<div>{raw(trustedHtml)}</div> {/* the only escape hatch, and it is greppable */}| Moteur | Résultat |
|---|---|
@vincle/core |
<div><img src=x onerror="alert(1)"></div> |
react-dom/server |
<div><img src=x onerror="…"></div> |
preact-render-to-string |
<div><img src=x onerror="…"></div> |
hono/jsx |
<div><img src=x onerror="…"></div> |
@kitajs/html |
<div><img src=x onerror="alert(1)"></div> |
Les noms d’attributs suivent une liste explicite#
La normalisation repose sur une liste d’attributs connus. Les attributs personnalisés conservent leur nom ; une conversion générale de tous les noms serait incorrecte.
| Moteur | Résultat |
|---|---|
@vincle/core |
<svg viewBox="0 0 24 24" stroke-width="2" clip-path="url(#a)"></svg> |
react-dom/server |
<svg viewBox="0 0 24 24" stroke-width="2" clip-path="url(#a)"></svg> |
hono/jsx |
<svg viewBox="0 0 24 24" stroke-width="2" clip-path="url(#a)"></svg> |
preact-render-to-string |
<svg viewBox="0 0 24 24" strokeWidth="2" clipPath="url(#a)"></svg> |
@kitajs/html |
<svg viewBox="0 0 24 24" strokeWidth="2" clipPath="url(#a)"></svg> |
Performances#
Les résultats dépendent du runtime, de la page et du mode de compilation. Comparez les sorties et les garanties avant de comparer uniquement les chiffres.
| Cas | vs @kitajs/html |
vs preact |
vs react |
vs hono/jsx |
|---|---|---|---|---|
text |
0.60× ± 0.09 | 1.82× ± 0.07 | 6.44× ± 0.62 | 7.78× ± 0.41 |
stack |
0.48× ± 0.01 | 2.67× ± 0.07 | 2.45× ± 0.07 | 4.47× ± 0.09 |
realworld |
0.73× ± 0.01 | 1.83× ± 0.06 | 2.17× ± 0.06 | 3.79× ± 0.08 |
Débit et temps par page#
Les mesures de débit et de temps par page portent sur le même document et le même environnement. Une valeur élevée de débit correspond à davantage de pages par seconde ; un temps inférieur correspond à un rendu plus rapide.
| Moteur | Pages/s | Temps/page |
|---|---|---|
@kitajs/html |
2,503 ± 38 | 0.400 ms |
@vincle/core (parcours de l’arbre) |
1,834 ± 39 | 0.545 ms |
preact-render-to-string |
1,004 ± 30 | 0.996 ms |
react-dom/server |
844 ± 18 | 1.185 ms |
hono/jsx |
484 ± 12 | 2.066 ms |
Lire la colonne kitajs#
La colonne kitajs doit être lue avec sa configuration d’échappement et ses contraintes de compilation. Un benchmark ne représente pas toutes les applications.
| Moteur | Bun / JSC | Node / V8 | |
|---|---|---|---|
@vincle/core (précompilation) |
9.19 µs | 12.44 µs | échappe |
@kitajs/html (safe) |
12.92 µs | 18.06 µs | échappe → Vincle 1,40× / 1,45× plus rapide |
@kitajs/html (default) |
9.21 µs | 11.09 µs | n’échappe pas |
Fonctionnalités et coût d’exécution#
Core ne livre aucun runtime client. Flow ajoute seulement ce que requiert l’adaptateur choisi. La précompilation réduit le travail effectué pendant le rendu tout en gardant les chemins dynamiques.
@vincle/core <div>hello</div>@kitajs/html <div>hello</div>preact <div></div> ← content dropped, no errorhono/jsx throws "No default value"react-dom throws React error #426| Critère | Vincle | Kita | Preact | Hono | React |
|---|---|---|---|---|---|
| Échappe le texte par défaut | oui | non | oui | oui | oui |
Neutralise javascript: dans href |
oui | non | non | non | oui |
Composant retournant une Promise dans l’API de chaînes |
oui | oui | non | non | non |
| API de contexte | Provider + portée d’exécution | aucun | Provider | Provider | Provider |
| Rendu DOM client / hydratation | non | non | oui | oui | oui |
| Dépendances directes du package SSR | 0 | 1 | 0¹ | 0 | 1² |
Reproduire les mesures#
Utilisez les scripts de benchmark du dépôt, conservez les métadonnées d’environnement et vérifiez l’équivalence du HTML avant d’interpréter les résultats.
bun run --filter=@vincle/bench bench:stats -- --runs 8