Added Profiler control with basic UI
This commit is contained in:
640
examples/profiler_mockup.html
Normal file
640
examples/profiler_mockup.html
Normal file
@@ -0,0 +1,640 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Profiler — UI Mockup</title>
|
||||
<style>
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Base — mirrors DaisyUI dark theme CSS variables */
|
||||
/* ------------------------------------------------------------------ */
|
||||
:root {
|
||||
--hcg-bg-main: #0d1117;
|
||||
--hcg-bg-button: rgba(22, 27, 34, 0.92);
|
||||
--hcg-border: #30363d;
|
||||
--hcg-text-muted: rgba(230, 237, 243, 0.5);
|
||||
--hcg-text-primary: #e6edf3;
|
||||
--hcg-node-bg: #1c2128;
|
||||
--hcg-node-bg-selected: color-mix(in oklab, #1c2128 70%, #f0883e 30%);
|
||||
|
||||
--profiler-danger: #f85149;
|
||||
--profiler-warn: #e3b341;
|
||||
--profiler-ok: #3fb950;
|
||||
--profiler-accent: #58a6ff;
|
||||
--profiler-muted: rgba(230, 237, 243, 0.35);
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--hcg-bg-main);
|
||||
color: var(--hcg-text-primary);
|
||||
font-family: ui-monospace, SFMono-Regular, "SF Mono", Consolas, monospace;
|
||||
font-size: 13px;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Toolbar */
|
||||
/* ------------------------------------------------------------------ */
|
||||
.mf-profiler-toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 8px 14px;
|
||||
background: var(--hcg-node-bg);
|
||||
border-bottom: 1px solid var(--hcg-border);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.mf-profiler-toolbar-title {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: var(--hcg-text-primary);
|
||||
letter-spacing: 0.05em;
|
||||
text-transform: uppercase;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.mf-profiler-btn {
|
||||
padding: 4px 12px;
|
||||
border-radius: 6px;
|
||||
border: 1px solid var(--hcg-border);
|
||||
background: var(--hcg-bg-button);
|
||||
color: var(--hcg-text-primary);
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
font-family: inherit;
|
||||
transition: background 0.15s, border-color 0.15s;
|
||||
}
|
||||
|
||||
.mf-profiler-btn:hover {
|
||||
background: color-mix(in oklab, var(--hcg-node-bg) 80%, var(--profiler-accent) 20%);
|
||||
border-color: var(--profiler-accent);
|
||||
}
|
||||
|
||||
.mf-profiler-btn.active {
|
||||
background: color-mix(in oklab, var(--hcg-node-bg) 60%, var(--profiler-ok) 40%);
|
||||
border-color: var(--profiler-ok);
|
||||
color: var(--profiler-ok);
|
||||
}
|
||||
|
||||
.mf-profiler-btn.danger {
|
||||
border-color: var(--profiler-danger);
|
||||
color: var(--profiler-danger);
|
||||
}
|
||||
|
||||
.mf-profiler-btn.danger:hover {
|
||||
background: color-mix(in oklab, var(--hcg-node-bg) 70%, var(--profiler-danger) 30%);
|
||||
}
|
||||
|
||||
.mf-profiler-overhead {
|
||||
margin-left: auto;
|
||||
color: var(--hcg-text-muted);
|
||||
font-size: 11px;
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.mf-profiler-overhead span b {
|
||||
color: var(--profiler-warn);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Split layout */
|
||||
/* ------------------------------------------------------------------ */
|
||||
.mf-profiler-body {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Trace list (left) */
|
||||
/* ------------------------------------------------------------------ */
|
||||
.mf-profiler-list {
|
||||
width: 380px;
|
||||
flex-shrink: 0;
|
||||
border-right: 1px solid var(--hcg-border);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mf-profiler-list-header {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 80px 110px;
|
||||
padding: 6px 12px;
|
||||
border-bottom: 1px solid var(--hcg-border);
|
||||
color: var(--hcg-text-muted);
|
||||
font-size: 11px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
background: var(--hcg-node-bg);
|
||||
}
|
||||
|
||||
.mf-profiler-list-body {
|
||||
overflow-y: auto;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.mf-profiler-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 80px 110px;
|
||||
padding: 7px 12px;
|
||||
border-bottom: 1px solid rgba(48, 54, 61, 0.5);
|
||||
cursor: pointer;
|
||||
transition: background 0.1s;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.mf-profiler-row:hover {
|
||||
background: color-mix(in oklab, var(--hcg-node-bg) 60%, var(--profiler-accent) 5%);
|
||||
}
|
||||
|
||||
.mf-profiler-row.selected {
|
||||
background: var(--hcg-node-bg-selected);
|
||||
border-left: 2px solid #f0883e;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.mf-profiler-cmd {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
color: var(--hcg-text-primary);
|
||||
}
|
||||
|
||||
.mf-profiler-duration {
|
||||
text-align: right;
|
||||
font-variant-numeric: tabular-nums;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.mf-profiler-duration.fast {
|
||||
color: var(--profiler-ok);
|
||||
}
|
||||
|
||||
.mf-profiler-duration.medium {
|
||||
color: var(--profiler-warn);
|
||||
}
|
||||
|
||||
.mf-profiler-duration.slow {
|
||||
color: var(--profiler-danger);
|
||||
}
|
||||
|
||||
.mf-profiler-ts {
|
||||
text-align: right;
|
||||
color: var(--hcg-text-muted);
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Detail panel (right) — Properties-style */
|
||||
/* ------------------------------------------------------------------ */
|
||||
.mf-profiler-detail {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mf-profiler-detail-header {
|
||||
padding: 8px 14px;
|
||||
border-bottom: 1px solid var(--hcg-border);
|
||||
background: var(--hcg-node-bg);
|
||||
color: var(--hcg-text-muted);
|
||||
font-size: 11px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
}
|
||||
|
||||
.mf-profiler-detail-header b {
|
||||
color: var(--hcg-text-primary);
|
||||
font-size: 13px;
|
||||
text-transform: none;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.mf-profiler-detail-body {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
/* Properties-style cards */
|
||||
.mf-properties-group-card {
|
||||
border: 1px solid var(--hcg-border);
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mf-properties-group-header {
|
||||
padding: 5px 10px;
|
||||
background: var(--hcg-node-bg);
|
||||
color: var(--hcg-text-muted);
|
||||
font-size: 11px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
border-bottom: 1px solid var(--hcg-border);
|
||||
}
|
||||
|
||||
.mf-properties-row {
|
||||
display: grid;
|
||||
grid-template-columns: 140px 1fr;
|
||||
border-bottom: 1px solid rgba(48, 54, 61, 0.4);
|
||||
}
|
||||
|
||||
.mf-properties-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.mf-properties-key {
|
||||
padding: 5px 10px;
|
||||
color: var(--hcg-text-muted);
|
||||
border-right: 1px solid var(--hcg-border);
|
||||
font-size: 12px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.mf-properties-value {
|
||||
padding: 5px 10px;
|
||||
color: var(--hcg-text-primary);
|
||||
font-size: 12px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
/* Span tree */
|
||||
.mf-profiler-span-tree {
|
||||
border: 1px solid var(--hcg-border);
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mf-profiler-span-tree-header {
|
||||
padding: 5px 10px;
|
||||
background: var(--hcg-node-bg);
|
||||
color: var(--hcg-text-muted);
|
||||
font-size: 11px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
border-bottom: 1px solid var(--hcg-border);
|
||||
}
|
||||
|
||||
.mf-profiler-span-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 5px 10px;
|
||||
border-bottom: 1px solid rgba(48, 54, 61, 0.4);
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.mf-profiler-span-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.mf-profiler-span-indent {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.mf-profiler-span-bar-wrap {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.mf-profiler-span-name {
|
||||
min-width: 140px;
|
||||
font-size: 12px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.mf-profiler-span-bar-bg {
|
||||
flex: 1;
|
||||
height: 6px;
|
||||
background: rgba(48, 54, 61, 0.6);
|
||||
border-radius: 3px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mf-profiler-span-bar {
|
||||
height: 100%;
|
||||
border-radius: 3px;
|
||||
background: var(--profiler-accent);
|
||||
transition: width 0.2s;
|
||||
}
|
||||
|
||||
.mf-profiler-span-bar.slow {
|
||||
background: var(--profiler-danger);
|
||||
}
|
||||
|
||||
.mf-profiler-span-bar.medium {
|
||||
background: var(--profiler-warn);
|
||||
}
|
||||
|
||||
.mf-profiler-span-ms {
|
||||
font-variant-numeric: tabular-nums;
|
||||
font-size: 11px;
|
||||
color: var(--hcg-text-muted);
|
||||
min-width: 60px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* Cumulative span badge */
|
||||
.mf-profiler-cumulative-badge {
|
||||
font-size: 10px;
|
||||
padding: 1px 5px;
|
||||
border-radius: 3px;
|
||||
background: rgba(88, 166, 255, 0.15);
|
||||
border: 1px solid rgba(88, 166, 255, 0.3);
|
||||
color: var(--profiler-accent);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* Empty state */
|
||||
.mf-profiler-empty {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
color: var(--hcg-text-muted);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* Scrollbar */
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--hcg-border);
|
||||
border-radius: 3px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- ================================================================== -->
|
||||
<!-- Toolbar -->
|
||||
<!-- ================================================================== -->
|
||||
<div class="mf-profiler-toolbar">
|
||||
<span class="mf-profiler-toolbar-title">Profiler</span>
|
||||
|
||||
<button class="mf-profiler-btn active" onclick="toggleEnabled(this)">● Enabled</button>
|
||||
<button class="mf-profiler-btn danger" onclick="clearTraces()">Clear</button>
|
||||
|
||||
<div class="mf-profiler-overhead">
|
||||
<span>Overhead/span: <b>1.2 µs</b></span>
|
||||
<span>Total overhead: <b>0.04 ms</b></span>
|
||||
<span>Traces: <b id="trace-count">8</b> / 500</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ================================================================== -->
|
||||
<!-- Body: list + detail -->
|
||||
<!-- ================================================================== -->
|
||||
<div class="mf-profiler-body">
|
||||
|
||||
<!-- ---------------------------------------------------------------- -->
|
||||
<!-- Trace list -->
|
||||
<!-- ---------------------------------------------------------------- -->
|
||||
<div class="mf-profiler-list">
|
||||
<div class="mf-profiler-list-header">
|
||||
<span>Command</span>
|
||||
<span style="text-align:right">Duration</span>
|
||||
<span style="text-align:right">Time</span>
|
||||
</div>
|
||||
<div class="mf-profiler-list-body" id="trace-list">
|
||||
|
||||
<div class="mf-profiler-row selected" onclick="selectRow(this, 0)">
|
||||
<span class="mf-profiler-cmd">NavigateCell</span>
|
||||
<span class="mf-profiler-duration slow">173.4 ms</span>
|
||||
<span class="mf-profiler-ts">14:32:07.881</span>
|
||||
</div>
|
||||
|
||||
<div class="mf-profiler-row" onclick="selectRow(this, 1)">
|
||||
<span class="mf-profiler-cmd">NavigateCell</span>
|
||||
<span class="mf-profiler-duration slow">168.1 ms</span>
|
||||
<span class="mf-profiler-ts">14:32:07.712</span>
|
||||
</div>
|
||||
|
||||
<div class="mf-profiler-row" onclick="selectRow(this, 2)">
|
||||
<span class="mf-profiler-cmd">SelectRow</span>
|
||||
<span class="mf-profiler-duration medium">42.7 ms</span>
|
||||
<span class="mf-profiler-ts">14:32:06.501</span>
|
||||
</div>
|
||||
|
||||
<div class="mf-profiler-row" onclick="selectRow(this, 3)">
|
||||
<span class="mf-profiler-cmd">FilterChanged</span>
|
||||
<span class="mf-profiler-duration medium">38.2 ms</span>
|
||||
<span class="mf-profiler-ts">14:32:05.334</span>
|
||||
</div>
|
||||
|
||||
<div class="mf-profiler-row" onclick="selectRow(this, 4)">
|
||||
<span class="mf-profiler-cmd">NavigateCell</span>
|
||||
<span class="mf-profiler-duration fast">12.0 ms</span>
|
||||
<span class="mf-profiler-ts">14:32:04.102</span>
|
||||
</div>
|
||||
|
||||
<div class="mf-profiler-row" onclick="selectRow(this, 5)">
|
||||
<span class="mf-profiler-cmd">SortColumn</span>
|
||||
<span class="mf-profiler-duration fast">8.4 ms</span>
|
||||
<span class="mf-profiler-ts">14:32:03.770</span>
|
||||
</div>
|
||||
|
||||
<div class="mf-profiler-row" onclick="selectRow(this, 6)">
|
||||
<span class="mf-profiler-cmd">SelectRow</span>
|
||||
<span class="mf-profiler-duration fast">5.1 ms</span>
|
||||
<span class="mf-profiler-ts">14:32:02.441</span>
|
||||
</div>
|
||||
|
||||
<div class="mf-profiler-row" onclick="selectRow(this, 7)">
|
||||
<span class="mf-profiler-cmd">NavigateCell</span>
|
||||
<span class="mf-profiler-duration fast">4.8 ms</span>
|
||||
<span class="mf-profiler-ts">14:32:01.003</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ---------------------------------------------------------------- -->
|
||||
<!-- Detail panel -->
|
||||
<!-- ---------------------------------------------------------------- -->
|
||||
<div class="mf-profiler-detail">
|
||||
<div class="mf-profiler-detail-header">
|
||||
Trace detail — <b>NavigateCell</b>
|
||||
</div>
|
||||
|
||||
<div class="mf-profiler-detail-body">
|
||||
|
||||
<!-- Metadata (Properties-style) -->
|
||||
<div class="mf-properties-group-card">
|
||||
<div class="mf-properties-group-header">Metadata</div>
|
||||
<div class="mf-properties-row">
|
||||
<div class="mf-properties-key">command</div>
|
||||
<div class="mf-properties-value">NavigateCell</div>
|
||||
</div>
|
||||
<div class="mf-properties-row">
|
||||
<div class="mf-properties-key">total_duration_ms</div>
|
||||
<div class="mf-properties-value" style="color:var(--profiler-danger)">173.4</div>
|
||||
</div>
|
||||
<div class="mf-properties-row">
|
||||
<div class="mf-properties-key">timestamp</div>
|
||||
<div class="mf-properties-value">2026-03-21 14:32:07.881</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- kwargs (Properties-style) -->
|
||||
<div class="mf-properties-group-card">
|
||||
<div class="mf-properties-group-header">kwargs</div>
|
||||
<div class="mf-properties-row">
|
||||
<div class="mf-properties-key">row</div>
|
||||
<div class="mf-properties-value">12</div>
|
||||
</div>
|
||||
<div class="mf-properties-row">
|
||||
<div class="mf-properties-key">col</div>
|
||||
<div class="mf-properties-value">3</div>
|
||||
</div>
|
||||
<div class="mf-properties-row">
|
||||
<div class="mf-properties-key">direction</div>
|
||||
<div class="mf-properties-value">down</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Span tree -->
|
||||
<div class="mf-profiler-span-tree">
|
||||
<div class="mf-profiler-span-tree-header">Span breakdown</div>
|
||||
|
||||
<!-- Root span -->
|
||||
<div class="mf-profiler-span-row">
|
||||
<div class="mf-profiler-span-indent" style="width:0"></div>
|
||||
<div class="mf-profiler-span-bar-wrap">
|
||||
<span class="mf-profiler-span-name" style="color:var(--hcg-text-primary);font-weight:600">NavigateCell</span>
|
||||
<div class="mf-profiler-span-bar-bg">
|
||||
<div class="mf-profiler-span-bar slow" style="width:100%"></div>
|
||||
</div>
|
||||
<span class="mf-profiler-span-ms" style="color:var(--profiler-danger)">173.4 ms</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- before_commands -->
|
||||
<div class="mf-profiler-span-row">
|
||||
<div class="mf-profiler-span-indent"
|
||||
style="width:16px; border-left:1px solid var(--hcg-border)"></div>
|
||||
<div class="mf-profiler-span-bar-wrap">
|
||||
<span class="mf-profiler-span-name">before_commands</span>
|
||||
<div class="mf-profiler-span-bar-bg">
|
||||
<div class="mf-profiler-span-bar" style="width:1%"></div>
|
||||
</div>
|
||||
<span class="mf-profiler-span-ms">0.8 ms</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- callback -->
|
||||
<div class="mf-profiler-span-row">
|
||||
<div class="mf-profiler-span-indent"
|
||||
style="width:16px; border-left:1px solid var(--hcg-border)"></div>
|
||||
<div class="mf-profiler-span-bar-wrap">
|
||||
<span class="mf-profiler-span-name">callback</span>
|
||||
<div class="mf-profiler-span-bar-bg">
|
||||
<div class="mf-profiler-span-bar slow" style="width:88%"></div>
|
||||
</div>
|
||||
<span class="mf-profiler-span-ms" style="color:var(--profiler-danger)">152.6 ms</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- navigate_cell (child of callback) -->
|
||||
<div class="mf-profiler-span-row">
|
||||
<div class="mf-profiler-span-indent"
|
||||
style="width:32px; border-left:1px solid var(--hcg-border)"></div>
|
||||
<div class="mf-profiler-span-bar-wrap">
|
||||
<span class="mf-profiler-span-name">navigate_cell</span>
|
||||
<div class="mf-profiler-span-bar-bg">
|
||||
<div class="mf-profiler-span-bar slow" style="width:86%"></div>
|
||||
</div>
|
||||
<span class="mf-profiler-span-ms" style="color:var(--profiler-danger)">149.0 ms</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- process_row (cumulative, child of navigate_cell) -->
|
||||
<div class="mf-profiler-span-row">
|
||||
<div class="mf-profiler-span-indent"
|
||||
style="width:48px; border-left:1px solid var(--hcg-border)"></div>
|
||||
<div class="mf-profiler-span-bar-wrap">
|
||||
<span class="mf-profiler-span-name">process_row</span>
|
||||
<div class="mf-profiler-span-bar-bg">
|
||||
<div class="mf-profiler-span-bar medium" style="width:80%"></div>
|
||||
</div>
|
||||
<span class="mf-profiler-span-ms" style="color:var(--profiler-warn)">138.5 ms</span>
|
||||
</div>
|
||||
<span class="mf-profiler-cumulative-badge">×1000 · min 0.1 · avg 0.14 · max 0.4 ms</span>
|
||||
</div>
|
||||
|
||||
<!-- after_commands -->
|
||||
<div class="mf-profiler-span-row">
|
||||
<div class="mf-profiler-span-indent"
|
||||
style="width:16px; border-left:1px solid var(--hcg-border)"></div>
|
||||
<div class="mf-profiler-span-bar-wrap">
|
||||
<span class="mf-profiler-span-name">after_commands</span>
|
||||
<div class="mf-profiler-span-bar-bg">
|
||||
<div class="mf-profiler-span-bar" style="width:6%"></div>
|
||||
</div>
|
||||
<span class="mf-profiler-span-ms">10.3 ms</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- oob_swap -->
|
||||
<div class="mf-profiler-span-row">
|
||||
<div class="mf-profiler-span-indent"
|
||||
style="width:16px; border-left:1px solid var(--hcg-border)"></div>
|
||||
<div class="mf-profiler-span-bar-wrap">
|
||||
<span class="mf-profiler-span-name">oob_swap</span>
|
||||
<div class="mf-profiler-span-bar-bg">
|
||||
<div class="mf-profiler-span-bar" style="width:5%"></div>
|
||||
</div>
|
||||
<span class="mf-profiler-span-ms">9.7 ms</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div><!-- /.mf-profiler-span-tree -->
|
||||
|
||||
</div><!-- /.mf-profiler-detail-body -->
|
||||
</div><!-- /.mf-profiler-detail -->
|
||||
|
||||
</div><!-- /.mf-profiler-body -->
|
||||
|
||||
<script>
|
||||
function selectRow(el, index) {
|
||||
document.querySelectorAll('.mf-profiler-row').forEach(r => r.classList.remove('selected'));
|
||||
el.classList.add('selected');
|
||||
}
|
||||
|
||||
function toggleEnabled(btn) {
|
||||
const enabled = btn.classList.toggle('active');
|
||||
btn.textContent = enabled ? '● Enabled' : '○ Disabled';
|
||||
}
|
||||
|
||||
function clearTraces() {
|
||||
document.getElementById('trace-list').innerHTML =
|
||||
'<div class="mf-profiler-empty">No traces recorded.</div>';
|
||||
document.getElementById('trace-count').textContent = '0';
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user