From ad31ea1e98db03b2652874aae162200845f3f7d9 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Fri, 28 Nov 2025 14:25:24 +0100 Subject: [PATCH] Turbopack: arrage empty space in trace viewer correctly --- .../turbopack-trace-server/src/span_ref.rs | 51 +++++++++++++++++-- .../turbopack-trace-server/src/viewer.rs | 48 +++++++++++------ 2 files changed, 80 insertions(+), 19 deletions(-) diff --git a/turbopack/crates/turbopack-trace-server/src/span_ref.rs b/turbopack/crates/turbopack-trace-server/src/span_ref.rs index 25adc8a234cb6..eb1fe620625c9 100644 --- a/turbopack/crates/turbopack-trace-server/src/span_ref.rs +++ b/turbopack/crates/turbopack-trace-server/src/span_ref.rs @@ -184,9 +184,13 @@ impl<'a> SpanRef<'a> { // TODO(sokra) use events instead of children for visualizing span graphs #[allow(dead_code)] - pub fn events(&self) -> impl Iterator> { + pub fn events(&self) -> impl DoubleEndedIterator> { self.span.events.iter().map(|event| match event { - &SpanEvent::SelfTime { start, end } => SpanEventRef::SelfTime { start, end }, + &SpanEvent::SelfTime { start, end } => SpanEventRef::SelfTime { + store: self.store, + start, + end, + }, SpanEvent::Child { index } => SpanEventRef::Child { span: SpanRef { span: &self.store.spans[index.get()], @@ -545,6 +549,45 @@ impl Debug for SpanRef<'_> { #[allow(dead_code)] #[derive(Copy, Clone)] pub enum SpanEventRef<'a> { - SelfTime { start: Timestamp, end: Timestamp }, - Child { span: SpanRef<'a> }, + SelfTime { + store: &'a Store, + start: Timestamp, + end: Timestamp, + }, + Child { + span: SpanRef<'a>, + }, +} + +impl SpanEventRef<'_> { + pub fn start(&self) -> Timestamp { + match self { + SpanEventRef::SelfTime { start, .. } => *start, + SpanEventRef::Child { span } => span.start(), + } + } + + pub fn total_time(&self) -> Timestamp { + match self { + SpanEventRef::SelfTime { start, end, .. } => end.saturating_sub(*start), + SpanEventRef::Child { span } => span.total_time(), + } + } + + pub fn corrected_self_time(&self) -> Timestamp { + match self { + SpanEventRef::SelfTime { store, start, end } => { + let duration = *end - *start; + if !duration.is_zero() { + store.set_max_self_time_lookup(*end); + store.self_time_tree.as_ref().map_or(duration, |tree| { + tree.lookup_range_corrected_time(*start, *end) + }) + } else { + Timestamp::ZERO + } + } + SpanEventRef::Child { span } => span.corrected_self_time(), + } + } } diff --git a/turbopack/crates/turbopack-trace-server/src/viewer.rs b/turbopack/crates/turbopack-trace-server/src/viewer.rs index 555000e4c4ca6..5bc1e25bc4ac9 100644 --- a/turbopack/crates/turbopack-trace-server/src/viewer.rs +++ b/turbopack/crates/turbopack-trace-server/src/viewer.rs @@ -10,7 +10,7 @@ use crate::{ server::ViewRect, span_bottom_up_ref::SpanBottomUpRef, span_graph_ref::{SpanGraphEventRef, SpanGraphRef}, - span_ref::SpanRef, + span_ref::{SpanEventRef, SpanRef}, store::{SpanId, Store}, timestamp::Timestamp, u64_empty_string, @@ -76,6 +76,17 @@ impl ValueMode { } } + fn value_from_event(&self, event: &SpanEventRef<'_>) -> u64 { + match self { + ValueMode::Duration => *event.corrected_self_time(), + ValueMode::Cpu => *event.total_time(), + _ => match event { + SpanEventRef::Child { span } => self.value_from_span(span), + SpanEventRef::SelfTime { .. } => 0, + }, + } + } + fn value_from_graph(&self, graph: &SpanGraphRef<'_>) -> u64 { match self { ValueMode::Duration => *graph.corrected_total_time(), @@ -651,24 +662,31 @@ impl Viewer { } } else if !selected_view_mode.aggregate_children() { let spans = if selected_view_mode.sort_children() { - Either::Left(span.children().sorted_by_cached_key(|child| { - Reverse(value_mode.value_from_span(child)) + Either::Left(span.events().sorted_by_cached_key(|child| { + Reverse(value_mode.value_from_event(child)) })) } else { - Either::Right(span.children().sorted_by_key(|child| child.start())) + Either::Right(span.events().sorted_by_key(|child| child.start())) }; for child in spans { - let filtered = get_filter_mode(child.id()); - add_child_item( - &mut children, - &mut current, - view_rect, - child_line_index, - view_mode, - value_mode, - QueueItem::Span(child), - filtered, - ); + match child { + SpanEventRef::SelfTime { .. } => { + current += value_mode.value_from_event(&child); + } + SpanEventRef::Child { span: child } => { + let filtered = get_filter_mode(child.id()); + add_child_item( + &mut children, + &mut current, + view_rect, + child_line_index, + view_mode, + value_mode, + QueueItem::Span(child), + filtered, + ); + } + } } } else { let events = if selected_view_mode.sort_children() {