2 points par GN⁺ 2024-12-21 | 1 commentaires | Partager sur WhatsApp
  • Clay est une bibliothèque de mise en page automatique d’UI, de style Flexbox et écrite en C, qui vise à permettre la construction déclarative d’interfaces même dans des moteurs personnalisés ou des environnements bas niveau
  • Elle est fournie sous forme d’un unique fichier d’en-tête, utilisable en C/C++, et met en avant environ 2 000 lignes de code C99 ainsi qu’une compilation .wasm de 15 Ko
  • Elle n’a aucune dépendance, y compris à la bibliothèque standard du C, et peut être utilisée séparément des modes de rendu comme Raylib, WebGL Canvas ou HTML
  • Elle est assez rapide pour recalculer toute l’UI à chaque frame, et fonctionne avec 3,5 Mo de mémoire par défaut, une allocation statique et de la réutilisation, sans malloc/free
  • On peut mêler les boucles, conditions et fonctions du code C à la hiérarchie de l’UI, et vérifier en temps réel l’état de la mise en page grâce aux outils de débogage intégrés

En-tête unique C99 et modèle mémoire

  • Clay est une bibliothèque de mise en page automatique de style Flexbox basée sur le C
    • Elle utilise une syntaxe déclarative
    • Elle met en avant des performances de l’ordre de la microseconde
    • La page web actuelle elle-même est mise en page avec Clay
  • Elle est fournie sous forme d’un unique fichier d’en-tête
    • Elle peut être utilisée en C/C++
    • Elle s’inclut avec #include clay.h
    • Elle se compose d’environ 2 000 lignes de code C99
    • Elle n’a aucune dépendance, y compris à la bibliothèque standard du C
    • Compilée en .wasm, elle pèse 15 Ko
  • Ses performances et son mode d’utilisation de la mémoire sont pensés pour les mises à jour d’UI en temps réel
    • Elle est assez rapide pour recalculer toute l’UI à chaque frame
    • L’utilisation mémoire par défaut est de 3,5 Mo
    • Elle utilise l’allocation statique et la réutilisation
    • Elle n’utilise pas malloc ni free
    • Elle permet de simplifier la conception d’animations et d’UI réactives sans techniques classiques d’évitement des coûts de performance

UI déclarative et séparation du renderer

  • La syntaxe déclarative vise à structurer de manière lisible des hiérarchies imbriquées d’éléments d’UI
    • Les éléments d’UI peuvent être mêlés aux boucles, conditions et fonctions du C
    • Il est possible de créer une bibliothèque de composants réutilisables à partir d’éléments d’UI de base comme le texte, les images et les rectangles
  • Clay est indépendant du renderer et de la plateforme
    • Clay gère la mise en page, tandis que le rendu peut être effectué avec Raylib, WebGL Canvas, HTML, etc.
    • La sortie est un tableau ordonné de commandes de rendu primitives comme RECTANGLE, TEXT et IMAGE
    • On peut écrire son propre renderer en quelques centaines de lignes de code, ou utiliser les exemples fournis
    • Un renderer HTML est également fourni, et la page actuelle en est un exemple
  • Elle inclut des outils de débogage intégrés
    • Elle fournit un outil de débogage de style Chrome Inspector
    • Il permet de voir en temps réel la hiérarchie de mise en page et les paramètres
    • Sur la page, on peut appuyer sur la touche d pour essayer l’outil de débogage

1 commentaires

 
GN⁺ 2024-12-21
Avis sur Hacker News
  • C’est agréable à regarder, et la vidéo YouTube où le développeur l’explique lui-même était excellente : https://www.youtube.com/watch?v=DYWTw19_8r4

    • Des explications aussi claires et intuitives sont rares, et cette vidéo est vraiment très bonne
    • On a l’impression que le développeur redécouvre le concept de bibliothèque GUI
      Sa forme moderne remonte aux GUI pilotées à la souris créées par Xerox dans les années 1970, puis commercialisées avec le Xerox Star ; Jobs s’en est inspiré pour l’Apple Lisa, et Gates pour MS Windows
      Les frameworks GUI définissent l’apparence et le ressenti d’une plateforme, et déterminent à quel point il est facile pour les développeurs de créer des applications, ce qui en fait un élément central de nombreuses concurrences entre plateformes comme les systèmes d’exploitation, les navigateurs ou les moteurs graphiques
  • C’est assez impressionnant de voir ce qu’on peut faire en quelques milliers de lignes
    Cela dit, je préfère CSS Grid à Flex, donc j’ai créé en Nim pur une bibliothèque de layout CSS Grid dont je suis plutôt fier : https://github.com/elcritch/cssgrid
    J’aimerais aussi examiner Clay et comparer les algorithmes de layout ; voir des boîtes redimensionner d’elles-mêmes avec un algorithme qu’on a implémenté soi-même, c’est amusant
    Je me demande aussi s’il serait possible d’exposer une interface C

    • Super. J’ai aussi une implémentation indépendante de CSS Grid, faite en Rust : https://github.com/DioxusLabs/taffy
      Elle prend aussi en charge Flexbox et le layout Block, et les deux licences semblent être de type MIT, donc vous pouvez reprendre ce dont vous avez besoin. Cela dit, ajouter un fichier LICENSE le rendrait plus facile à trouver
      L’objectif est une compatibilité web complète, mais on n’y est pas encore totalement ; un point qui pourrait particulièrement vous intéresser est l’assez grosse suite de tests
      Les tests sont définis sous forme de fragments HTML, puis on lance Chrome via webdriver pour récupérer les assertions correctes, avant de les convertir en tests unitaires en pur code. Si vous voulez, vous pouvez écrire votre propre générateur de tests et réutiliser nos fragments
      Cette infrastructure de test est aussi partiellement partagée avec Yoga, l’implémentation C++ de Flexbox qui fait tourner React Native : https://github.com/facebook/yoga
    • Un calcul exact du layout CSS Grid se rapproche davantage de la résolution d’un système d’équations et de contraintes
      Dans les cas simples, sans cellules qui s’étendent sur plusieurs zones comme avec Flexbox, c’est relativement faisable ; sinon, ce n’est pas trivial et il faut des approches comme un solveur du simplexe ou Cassowary : https://constraints.cs.washington.edu/solvers/cassowary-tochi.pdf
  • Il y a à la fin un bouton pour basculer entre HTML et Canvas, et en général la différence est à peine perceptible, ce qui est impressionnant
    Mais avec la combinaison iOS Safari + Dark Reader, la page HTML passe en mode sombre alors que la page Canvas ne change pas, donc pour moi l’effet wow en prend un coup
    Cela reste quand même agréable à regarder

    • Il y a aussi des problèmes de sélection de texte et de zoom
    • Il est écrit « Il existe aussi un renderer HTML. C’est celui que vous regardez en ce moment ! », mais au moment où je lisais ça, j’étais déjà passé au renderer Canvas
    • Dans Chrome, le renderer HTML est clairement plus rapide, et je me demande pourquoi
      Canvas est largement assez rapide, mais sur des animations ou un scroll « High performance », on sent la différence
  • Il est impossible de sélectionner tout le texte derrière l’animation
    Quelque chose semble voler le focus, et dès qu’on essaie de sélectionner du texte, la sélection est immédiatement annulée

    • C’est probablement parce que tout est réinitialisé à chaque frame pendant la lecture de l’animation
    • Sur mobile, le même phénomène se produit à la fois dans les navigateurs basés sur Chromium et sur Gecko
      Ce qui est intéressant, c’est que Firefox rend cette page bien plus mal : https://imgur.com/a/DNYe2WN
  • C’est une interprétation réjouissante d’un style d’UI que j’aime beaucoup
    La manière de séparer la logique d’UI et le rendu en un ensemble de commandes de dessin est excellente et très polyvalente. Je l’avais d’abord vue dans microui, et grâce à cette séparation, il a été facile d’utiliser la bibliothèque dans le navigateur avec WASM et Canvas2D : https://rxi.github.io/microui_v2_an_implementation_overview.html
    Et l’idée de calculer le layout en WASM puis de rendre en HTML est très bonne aussi ; je ne sais pas pourquoi je n’y avais pas pensé plus tôt

  • Au début, je me demandais s’il y avait vraiment besoin de le faire en C, et si ce ne serait pas plus sûr en Haskell ou en OCaml
    Mais 2000 lignes de C sans dépendances, c’est quand même assez impressionnant

    • Au moins, de cette façon, ça peut être utilisé dans d’autres langages
  • Il y a aussi taffy en Rust, et des bindings C sont en cours : https://crates.io/crates/taffy

  • C’est bien pour un premier jet
    En revanche, c’est dommage que la sortie HTML ne soit composée que d’éléments div, et cela gagnerait beaucoup à prendre un peu plus en compte l’accessibilité
    Autre problème : à plusieurs endroits, si on essaie de sélectionner du texte, un nouveau rendu se déclenche et la sélection est annulée avant même qu’on puisse appuyer sur control-c

  • Pour être franc, je me demande si écrire une page web de cette manière n’est pas un peu excessif, même si l’idée est séduisante
    À l’intérieur de LandingPageDesktop(), on a des appels profondément imbriqués comme CLAY(...), CLAY_TEXT(...) ou LandingPageBlob(...), et voici le code source d’exemple : https://github.com/nicbarker/clay/blob/35d72e5fba6872be48d15ed9d84269a86cd72b4e/examples/clay-official-website/main.c#L50C1-L67C2

  • C’est un travail impressionnant. Dans un navigateur, je pense que le texte sélectionnable est indispensable
    Pour des clients ou des applications qui n’en ont pas besoin, ou qui peuvent le fournir eux-mêmes, cela semble être une solution très compacte et intéressante

    • C’est étrange de voir la sélection de texte et le copier-coller cassés, mais j’ai aussi l’impression que ça pourrait se corriger
      Je me répète, mais j’ai le sentiment que, parmi les évolutions de l’UI de ces dernières années, le recul de l’universalité du presse-papiers, avec le recul de la possibilité de créer des liens et de l’intégration embarquée, est l’une des pertes les plus sous-estimées