DevTools
Finden Sie Layout-, Hit-Testing-, Rendering- und Performance-Probleme mit einem einzeiligen Overlay, einem eigenständigen Panel und einer begrenzten, strukturierten Console.
Inspektor im Fenster
Hängen Sie das Overlay während der Entwicklung an Ihre Wurzel. Beim Hover umrandet es das Rect des Knotens gestrichelt und zeigt Größe und Komponentennamen. Das Overlay ist pass-through – es fängt weder Klicks noch Scrollen ab –, und Hover löst nur Updates auf Paint-Ebene aus, niemals ein Relayout.
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;
}Der Zustand des Overlays hängt am übergebenen scope; wird dieser Scope freigegeben, verschwindet auch das Overlay. Nutzen Sie es im Produktfenster, um zu klären „Wer belegt diesen Platz?“; für die vollständige Diagnose nehmen Sie das Panel. Beide lesen den echten Node-/Cx-Zustand – kein Spiegelmodell, das Sie fürs Debugging pflegen müssten.
Diagnose nach Symptom
hit_behavior des getroffenen KnotenssetText / setTextContent aufzurufen? Diese APIs vergleichen selbst und markieren sizing / render dirtynode.style markiert nichts als dirty; verwenden Sie node.setStyle(alloc, .width, v), das pro Feld die richtige Dirty-Stufe wähltDas DevTools-Panel
Für die vollständigen Ansichten Elements, Components, Console und Performance verwenden Sie ui.devtools.mountPanel(cx, target, opts). Das Panel hat einen eigenen Cx und beobachtet einen separaten Target-Cx; üblicherweise liegt es mit MultiWindowApp in einem eigenen Fenster, damit es die Produkt-UI nie verdeckt. Der Target muss am Leben bleiben, solange das Panel genutzt wird.
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();
}So ist zig build devtools-probe im Repo aufgebaut. ui.devtools bietet außerdem setViewMode, setTreeFilter, setConsoleFilter und weitere Funktionen, mit denen Probes und E2E-Tests das Panel programmatisch steuern.
Vier Ansichten, sechs Detail-Tabs
Bei ausgewählter Elements-/Components-Zeile wechseln Sie zwischen Layout, Style, State, Events, Render und Trace. Einige Style-Werte lassen sich live bearbeiten; Render / Trace zeigen, warum ein Knoten dirty wurde, und seine letzten Events. Die Baumsuche findet Tags, #id und Komponentennamen. Mit konfiguriertem ui.devtools.source_link springen Komponentenzeilen direkt zur Definition in Ihrem Editor.
Console-Logging
Jeder ui.Cx besitzt eine eigene threadsichere, begrenzte Console. Ein Aufruf kann ins Terminal schreiben und zugleich ein strukturiertes Event für DevTools und den E2E-harness behalten; auch vor dem Öffnen des Panels erfasste Einträge werden angezeigt.
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)});Die Level sind debug, log, info, warn und err. Auch die Gegenstücke der Browser-Konsole sind vorhanden: group / groupEnd, count, time / timeEnd, assert, trace, inspect und table.
Die einfachen Level-Methoden zeichnen keine Aufrufstelle auf. Um per Klick auf eine Logzeile im Editor zu landen, verwenden Sie writeAt(level, @src(), …) und setzen Quellwurzel und Editor-Befehl mit ui.devtools.source_link.configure (Standard: code --goto).
Erfassung konfigurieren
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,
},
});Ohne explizites console wählt zenit_app die Standardwerte nach Build-Modus:
Debug.debug.debugReleaseSafe.info.infoReleaseFast / ReleaseSmall.warnnull (aus)Die Console bildet die Erfassungs- und Anzeigeseite der Browser-Konsole nach; sie ist kein Zig-/JavaScript-REPL. Groups werden derzeit nur eingerückt, lassen sich aber nicht interaktiv einklappen, und table wird als Text ausgegeben. Vollständige API, Thread- und Lebensdauerregeln sowie harness-Beispiele stehen in docs/CONSOLE.md im Repo.
Performance: idle oder hängend
Die Performance-Ansicht friert nicht auf „den letzten N gerenderten Frames“ ein. Sie beobachtet den Target fortlaufend in 100-ms-Wanduhr-Buckets – 64 davon, ein rollendes Fenster von etwa 6.4 s – und berechnet die FPS als Mittel der letzten 10 Buckets (etwa 1 s). Liefert der Target länger als 0.7 s keinen Frame, zeigt die Anzeige FPS: 0 — idle (not rendering): Das Framework lässt bewusst Frames aus, um Energie zu sparen, und hängt nicht bei 0 FPS.
Test-Einstiegspunkte
zig build test-headless
zig build test-ui
zig build test-render
zig build hello-buttonVor dem Release
- ✓
Debug-UI abschalten. Entfernen Sie das Inspektor-Overlay oder binden Sie es an eine reine Debug-Konfiguration.
- ✓
Eingabe im echten Fenster prüfen. Tastatur, IME, Zwischenablage und VoiceOver.
- ✓
Build-Gates ausführen. Die Test-Steps für headless, UI und Render.
- ✓
Console-Richtlinie prüfen. Terminal-Level und Erfassung im Release sind wie beabsichtigt, und die Logs enthalten keine sensiblen Daten.
- ✓
Versionen festschreiben. Fixieren Sie die zenit-Revision und halten Sie die Ziel-Zig-Version fest.



