Added Perf details to profiler control
This commit is contained in:
@@ -34,6 +34,7 @@ from myfasthtml.core.formatting.dsl.parser import DSLParser
|
||||
from myfasthtml.core.formatting.engine import FormattingEngine
|
||||
from myfasthtml.core.instances import MultipleInstance, InstancesManager
|
||||
from myfasthtml.core.optimized_ft import OptimizedDiv
|
||||
from myfasthtml.core.profiler import profiler
|
||||
from myfasthtml.core.utils import merge_classes, is_null
|
||||
from myfasthtml.icons.carbon import row, column, grid
|
||||
from myfasthtml.icons.fluent import checkbox_unchecked16_regular
|
||||
@@ -709,6 +710,7 @@ class DataGrid(MultipleInstance):
|
||||
|
||||
return self.render_partial()
|
||||
|
||||
@profiler.trace_calls()
|
||||
def on_key_pressed(self, combination, has_focus, is_inside):
|
||||
logger.debug(f"on_key_pressed table={self.get_table_name()} {combination=} {has_focus=} {is_inside=}")
|
||||
if combination == "esc":
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import logging
|
||||
|
||||
from fasthtml.components import Div, Span
|
||||
from fasthtml.components import Details, Div, Span, Summary
|
||||
|
||||
from myfasthtml.controls.BaseCommands import BaseCommands
|
||||
from myfasthtml.controls.IconsHelper import IconsHelper
|
||||
@@ -24,8 +24,13 @@ logger = logging.getLogger("Profiler")
|
||||
# Span tree renderer — module-level, passed via PropertiesConf.types
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _mk_span_rows(span, depth: int, total_ms: float) -> list:
|
||||
"""Recursively build span rows for the tree view.
|
||||
def _mk_span_rows(span, depth: int, total_ms: float):
|
||||
"""Recursively build the span tree.
|
||||
|
||||
Spans with children are rendered as a collapsible ``<details>`` element
|
||||
(expanded by default). Leaf spans and cumulative spans are rendered as
|
||||
plain ``<div>`` rows. The ``mf-profiler-span-row`` class is applied to
|
||||
both ``<summary>`` and ``<div>`` so CSS rules are shared.
|
||||
|
||||
Args:
|
||||
span: A ProfilingSpan or CumulativeSpan to render.
|
||||
@@ -33,11 +38,10 @@ def _mk_span_rows(span, depth: int, total_ms: float) -> list:
|
||||
total_ms: Reference duration used to compute bar widths.
|
||||
|
||||
Returns:
|
||||
List of FT elements, one per span row (depth-first order).
|
||||
A single FT element (Details or Div).
|
||||
"""
|
||||
rows = []
|
||||
indent = [Div(cls="mf-profiler-span-indent") for _ in range(depth)]
|
||||
|
||||
|
||||
if isinstance(span, CumulativeSpan):
|
||||
pct = (span.total_ms / total_ms * 100) if total_ms > 0 else 0
|
||||
duration_cls = _span_duration_cls(span.total_ms)
|
||||
@@ -45,7 +49,7 @@ def _mk_span_rows(span, depth: int, total_ms: float) -> list:
|
||||
f"×{span.count} · min {span.min_ms:.2f} · avg {span.avg_ms:.2f} · max {span.max_ms:.2f} ms",
|
||||
cls="mf-profiler-cumulative-badge",
|
||||
)
|
||||
row = Div(
|
||||
return Div(
|
||||
*indent,
|
||||
Div(
|
||||
Span(span.name, cls="mf-profiler-span-name"),
|
||||
@@ -56,27 +60,28 @@ def _mk_span_rows(span, depth: int, total_ms: float) -> list:
|
||||
),
|
||||
cls="mf-profiler-span-row",
|
||||
)
|
||||
rows.append(row)
|
||||
|
||||
else:
|
||||
pct = (span.duration_ms / total_ms * 100) if total_ms > 0 else 0
|
||||
duration_cls = _span_duration_cls(span.duration_ms)
|
||||
name_cls = "mf-profiler-span-name mf-profiler-span-name-root" if depth == 0 else "mf-profiler-span-name"
|
||||
row = Div(
|
||||
*indent,
|
||||
Div(
|
||||
Span(span.name, cls=name_cls),
|
||||
Div(Div(cls=f"mf-profiler-span-bar {duration_cls}", style=f"width:{pct:.1f}%"), cls="mf-profiler-span-bar-bg"),
|
||||
Span(f"{span.duration_ms:.1f} ms", cls=f"mf-profiler-span-ms {duration_cls}"),
|
||||
cls="mf-profiler-span-body",
|
||||
),
|
||||
cls="mf-profiler-span-row",
|
||||
)
|
||||
rows.append(row)
|
||||
for child in span.children:
|
||||
rows.extend(_mk_span_rows(child, depth + 1, total_ms))
|
||||
|
||||
return rows
|
||||
|
||||
pct = (span.duration_ms / total_ms * 100) if total_ms > 0 else 0
|
||||
duration_cls = _span_duration_cls(span.duration_ms)
|
||||
name_cls = "mf-profiler-span-name mf-profiler-span-name-root" if depth == 0 else "mf-profiler-span-name"
|
||||
row_content = (
|
||||
*indent,
|
||||
Div(
|
||||
Span(span.name, cls=name_cls),
|
||||
Div(Div(cls=f"mf-profiler-span-bar {duration_cls}", style=f"width:{pct:.1f}%"), cls="mf-profiler-span-bar-bg"),
|
||||
Span(f"{span.duration_ms:.1f} ms", cls=f"mf-profiler-span-ms {duration_cls}"),
|
||||
cls="mf-profiler-span-body",
|
||||
),
|
||||
)
|
||||
|
||||
if not span.children:
|
||||
return Div(*row_content, cls="mf-profiler-span-row")
|
||||
|
||||
return Details(
|
||||
Summary(*row_content, cls="mf-profiler-span-row"),
|
||||
*[_mk_span_rows(child, depth + 1, total_ms) for child in span.children],
|
||||
open=True,
|
||||
)
|
||||
|
||||
|
||||
def _span_duration_cls(duration_ms: float) -> str:
|
||||
@@ -98,8 +103,7 @@ def _span_tree_renderer(span: ProfilingSpan, trace: ProfilingTrace):
|
||||
Returns:
|
||||
A FT element containing the full span tree.
|
||||
"""
|
||||
rows = _mk_span_rows(span, 0, trace.total_duration_ms)
|
||||
return Div(*rows, cls="mf-profiler-span-tree-content")
|
||||
return Div(_mk_span_rows(span, 0, trace.total_duration_ms), cls="mf-profiler-span-tree-content")
|
||||
|
||||
|
||||
class Commands(BaseCommands):
|
||||
@@ -187,12 +191,12 @@ class Profiler(SingleInstance):
|
||||
def handle_select_trace(self, trace_id: str):
|
||||
"""Select a trace row and re-render to show it highlighted."""
|
||||
if self._selected_id is not None:
|
||||
old_trace = next(trace for trace in profiler.traces if trace.trace_id == self._selected_id)
|
||||
old_trace = next((t for t in profiler.traces if t.trace_id == self._selected_id), None)
|
||||
else:
|
||||
old_trace = None
|
||||
|
||||
|
||||
self._selected_id = trace_id
|
||||
trace = next(trace for trace in profiler.traces if trace.trace_id == trace_id)
|
||||
trace = next((t for t in profiler.traces if t.trace_id == trace_id), None)
|
||||
|
||||
return (self._mk_trace_item(trace),
|
||||
self._mk_trace_item(old_trace),
|
||||
|
||||
@@ -65,7 +65,7 @@ class Properties(MultipleInstance):
|
||||
cls="mf-properties-value",
|
||||
title=str(value))
|
||||
|
||||
def _render_group_content(self, proxy) -> Div:
|
||||
def _render_group_content(self, proxy):
|
||||
"""Render a group's content.
|
||||
|
||||
When the group contains exactly one property whose type is registered in
|
||||
|
||||
Reference in New Issue
Block a user