---
title: "DevTools — Docs zenit Zig UI"
description: "Traquez les problèmes de layout, de hit-testing, de rendu et de performance avec un overlay d’une ligne, un panneau autonome et une Console structurée et…"
url: https://zenit.z.express/fr/docs/advanced/devtools
language: fr
alternate_en: https://zenit.z.express/docs/advanced/devtools.md
alternate_zh: https://zenit.z.express/zh/docs/advanced/devtools.md
alternate_es: https://zenit.z.express/es/docs/advanced/devtools.md
alternate_ja: https://zenit.z.express/ja/docs/advanced/devtools.md
alternate_ko: https://zenit.z.express/ko/docs/advanced/devtools.md
alternate_de: https://zenit.z.express/de/docs/advanced/devtools.md
project: zenit v0.1.0-alpha (Zig 0.15.2, macOS)
source: https://github.com/version-next/zenit
---

# DevTools

Traquez les problèmes de layout, de hit-testing, de rendu et de performance avec un overlay d’une ligne, un panneau autonome et une Console structurée et bornée.

## Inspecteur dans la fenêtre

En développement, attachez l’overlay à votre racine. Au survol, il entoure le rect du nœud d’un cadre en pointillés et affiche sa taille et le nom du composant. L’overlay est pass-through — il n’intercepte ni les clics ni le défilement — et le survol ne déclenche que des mises à jour au niveau du dessin, jamais de relayout.

`main.zig`

```zig
fn mountUi(cx: *ui.Cx, scope: *ui.Scope) anyerror!*ui.Node {
    const root = try mountProductUi(cx, scope);

    // Development only: hover highlight with size + component name.
    _ = try ui.devtools.overlay.attach(cx, scope, root, .{});
    return root;
}
```

L’état de l’overlay vit sur le `scope` que vous passez ; quand ce Scope est libéré, l’overlay disparaît avec lui. Utilisez-le dans la fenêtre du produit pour savoir « qui occupe cet espace ? » ; utilisez le panneau pour un diagnostic complet. Les deux lisent l’état réel de Node / Cx — aucun modèle miroir à maintenir pour le débogage.

## Diagnostic par symptôme

| Symptôme | À vérifier d’abord |
| --- | --- |
| Contenu mal aligné | Rect, padding, gap et direction du parent (Elements → Layout) |
| Les zones vides sont cliquables | La taille et le `hit_behavior` du nœud touché |
| Le texte a changé, pas l’écran | Avez-vous modifié des champs de TextProps sans appeler `setText` / `setTextContent` ? Ces API comparent et marquent elles-mêmes sizing / render dirty |
| Le layout ignore une nouvelle largeur | Affecter `node.style` directement ne marque rien comme dirty ; utilisez `node.setStyle(alloc, .width, v)`, qui choisit le bon niveau de dirty pour chaque champ |
| Ralentit avec le temps | Mounts répétés, Effects non libérés avec leur Scope, allocations à chaque frame (Performance → Summary / Rebuild) |

## Le panneau DevTools

Pour les vues complètes Elements, Components, Console et Performance, utilisez `ui.devtools.mountPanel(cx, target, opts)`. Le panneau a son propre Cx et observe un Cx target distinct ; en général, on le place dans sa propre fenêtre avec [MultiWindowApp](https://zenit.z.express/fr/docs/advanced/multi-window) pour qu’il ne masque jamais l’UI du produit. Le target doit rester vivant tant que le panneau est utilisé.

`main.zig`

```zig
const std = @import("std");
const ui = @import("ui");
const zenit_app = @import("zenit_app");

// mountProductUi: your app's ordinary mount function (see above).
var g_target_cx: ?*ui.Cx = null;

fn mountDevTools(cx: *ui.Cx, scope: *ui.Scope) anyerror!*ui.Node {
    _ = scope;
    const target = g_target_cx orelse return error.TargetNotReady;
    return ui.devtools.mountPanel(cx, target, .{ .title = "My App DevTools" });
}

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();

    var application = zenit_app.MultiWindowApp.init(gpa.allocator(), .{});
    defer application.deinit();

    const product = try application.createWindowWith(.{
        .window = .{ .width = 900, .height = 640, .title = "My App" },
    }, mountProductUi);
    g_target_cx = product.cx;

    const tools = try application.createWindowWith(.{
        .window = .{ .width = 760, .height = 560, .title = "DevTools" },
    }, mountDevTools);
    _ = ui.devtools.setViewMode(tools.cx, "performance"); // optional start tab

    try application.run();
}
```

C’est ainsi qu’est structuré `zig build devtools-probe` dans le dépôt. `ui.devtools` expose aussi `setViewMode`, `setTreeFilter`, `setConsoleFilter` et consorts, pour que les sondes et les tests E2E pilotent le panneau par programme.

[![Zenit DevTools Elements panel with a box selected and its layout details](https://zenit.z.express/media/devtools-elements.png?v=1c99ec3edc)](https://zenit.z.express/media/devtools-elements.png?v=1c99ec3edc)

L’arbre d’UI en direct à gauche ; sélectionnez un nœud et l’onglet Layout à droite affiche son rect calculé, son padding, son sizing et ses propriétés flex. Le curseur en forme de main est le curseur virtuel du harness.

### Quatre vues, six onglets de détail

| Vue | Répond à |
| --- | --- |
| **Elements** | Quelle est la vraie hiérarchie des nœuds — tag / id / text, layout et zone de hit ? |
| **Components** | Quels nœuds forment les frontières de composant, et où sont leur état et leur Scope propriétaire ? |
| **Console** | Quels logs structurés le Cx target a-t-il capturés, et quelque chose a-t-il été évincé ou perdu ? |
| **Performance** | Le target est-il en rendu ou inactif ? Que coûtent layout / render / cache / interaction ? |

Une ligne Elements / Components sélectionnée, passez de **Layout, Style, State, Events, Render à Trace**. Certaines valeurs de Style sont modifiables en direct ; Render / Trace montrent pourquoi un nœud est devenu dirty et ses événements récents. La recherche dans l’arbre porte sur les tags, les `#id` et les noms de composant. Avec `ui.devtools.source_link` configuré, les lignes de composant peuvent ouvrir leur définition dans votre éditeur.

## Journalisation Console

Chaque `ui.Cx` possède une Console thread-safe et bornée. Un seul appel peut écrire dans le terminal et conserver un événement structuré pour DevTools et le harness E2E ; l’historique capturé avant l’ouverture du panneau s’affiche aussi.

`logging.zig`

```zig
const log = cx.console();

log.info("application ready", .{});
log.scoped("network").warn("retry {d}", .{attempt});

// Plain level methods don't record a call site; writeAt does.
log.writeAt(.err, @src(), "save failed: {s}", .{@errorName(err)});
```

Les niveaux sont `debug`, `log`, `info`, `warn` et `err`. Les équivalents de la console du navigateur sont aussi là : `group` / `groupEnd`, `count`, `time` / `timeEnd`, `assert`, `trace`, `inspect` et `table`.

| Zone du panneau | Rôle |
| --- | --- |
| **Clear** | Vide le stockage Console du target lui-même, pas seulement la vue. |
| **Filter** | Correspondance insensible à la casse sur message et scope ; se combine avec le filtre de niveau. |
| **Levels** | Activez Debug / Log / Info / Warn / Error dans n’importe quelle combinaison. |
| **Liste des logs** | Niveau, scope, message, indentation de group et emplacement source facultatif ; le suivi automatique se met en pause dès que vous quittez le bas. |
| **Barre d’état** | shown / captured / evicted / dropped — distingue filtrage, éviction et perte. |

[![Zenit DevTools Console with debug, info, warn and error entries](https://zenit.z.express/media/devtools-console.png?v=1411f611cd)](https://zenit.z.express/media/devtools-console.png?v=1411f611cd)

Les logs sont arrivés dans le stockage borné du Cx target avant l’ouverture du panneau ; scope, niveau et emplacement source sont conservés.

[![Zenit DevTools Console filtered to the network scope](https://zenit.z.express/media/devtools-console-filter.png?v=acfa3d9446)](https://zenit.z.express/media/devtools-console-filter.png?v=acfa3d9446)

Filter et Levels se combinent localement dans DevTools ; rien n’est retiré du stockage du target.

[Video](https://zenit.z.express/media/devtools-console.mp4?v=05e8c163e3)

Une vraie app à deux fenêtres : le curseur virtuel passe d’Elements à Console, active Filter et tape network. Enregistré directement depuis le Metal drawable de la fenêtre DevTools.

Les méthodes de niveau simples n’enregistrent pas le site d’appel. Pour cliquer sur une ligne de log et arriver dans votre éditeur, utilisez `writeAt(level, @src(), …)` et définissez la racine des sources et la commande d’éditeur avec `ui.devtools.source_link.configure` (par défaut : `code --goto`).

### Configurer la capture

`main.zig`

```zig
const app = try zenit_app.App.init(allocator, .{
    .console = .{
        .terminal_level = .info, // null disables the terminal sink
        .capture_level = .debug, // null disables in-memory capture
        .max_entries = 10_000,
        .max_bytes = 8 * 1024 * 1024,
        .max_entry_bytes = 64 * 1024,
    },
});
```

Sans `console` explicite, `zenit_app` choisit des valeurs par défaut selon le mode de build :

| Mode de build | Terminal | Capture |
| --- | --- | --- |
| `Debug` | `.debug` | `.debug` |
| `ReleaseSafe` | `.info` | `.info` |
| `ReleaseFast / ReleaseSmall` | `.warn` | `null` (désactivée) |

> WARNING
> 
> **Les builds Release ne capturent pas par défaut.** En ReleaseFast / ReleaseSmall, DevTools ne voit aucun historique. Si un build de production en a besoin, définissez `capture_level` explicitement — et tenez tokens, mots de passe et données personnelles hors de vos logs.

La Console reprend la partie capture et consultation de la console du navigateur ; ce n’est pas un REPL Zig / JavaScript. Les groups sont pour l’instant indentés mais non repliables, et `table` se rabat sur du texte. L’API complète, les règles de threads et de durée de vie et des exemples de harness se trouvent dans `docs/CONSOLE.md` du dépôt.

## Performance : inactif ou bloqué

La vue Performance ne se fige pas sur « les N dernières frames rendues ». Elle observe le target en continu par buckets de 100 ms de temps réel — 64 au total, soit une fenêtre glissante d’environ 6.4 s — et calcule les FPS comme la moyenne des 10 derniers buckets (environ 1 s). Quand le target ne produit aucune frame pendant plus de 0.7 s, l’affichage indique `FPS: 0 — idle (not rendering)` : le framework saute délibérément des frames pour économiser l’énergie, il n’est pas bloqué à 0 FPS.

100MS BUCKETS

Une fois les frames arrêtées, le graphique continue d’avancer en enregistrant des zéros ; l’affichage baisse à mesure qu’arrivent des buckets vides et passe à idle après 0.7 s — il ne fait jamais passer une valeur périmée pour actuelle.

[![Zenit DevTools Performance showing FPS 0 idle (not rendering) with timing metrics](https://zenit.z.express/media/devtools-performance.png?v=41f18a12a0)](https://zenit.z.express/media/devtools-performance.png?v=41f18a12a0)

Le target statique a cessé de rendre ; DevTools se rafraîchit à environ 10 Hz pour que le graphique avance, et les métriques layout, render, cache, focus et interaction restent lisibles.

| Affichage | Signification |
| --- | --- |
| FPS + graphique glissant | Buckets de temps réel ; un bucket sans frame enregistre 0 et s’affiche comme une ligne de base neutre, jamais comme une valeur périmée |
| Timing | Temps CPU réel de la dernière frame du target : layout, génération des commandes de rendu, etc. |
| Summary / Interaction | Hit registry, mouse-hit, redraw streak, focus et rebuilds d’interaction |
| Cache / Rebuild | Hits / misses du retained cache, rebuilds full / partial |

## Points d’entrée des tests

```sh
zig build test-headless
zig build test-ui
zig build test-render
zig build hello-button
```

> WARNING
> 
> **N’exécutez pas zig test sur des fichiers internes.** Les modules zenit s’importent entre répertoires : utilisez donc les steps de test définis dans `build.zig`, sans quoi vous risquez `import of file outside module path`. La liste complète est dans [Commandes](https://zenit.z.express/fr/docs/reference/commands) ; pour les tests en fenêtre réelle, voir [Harness E2E](https://zenit.z.express/fr/docs/advanced/e2e).

## Avant la publication

-   **Désactivez l’UI de débogage.** Retirez l’overlay d’inspection, ou conditionnez-le à une configuration de debug.
    
-   **Vérifiez la saisie dans une vraie fenêtre.** Clavier, IME, presse-papiers et VoiceOver.
    
-   **Passez les contrôles de build.** Les steps de test headless, UI et render.
    
-   **Vérifiez la politique de Console.** Le niveau terminal et la capture en Release sont ceux voulus, et les logs ne contiennent aucune donnée sensible.
    
-   **Figez les versions.** Verrouillez la révision de zenit et notez la version de Zig ciblée.
