Skip to content

Timeline Tab

The Timeline tab displays a composable-by-time heatmap, showing recomposition patterns over time. It reveals temporal patterns that point-in-time snapshots cannot: sustained hotspots, burst patterns, and correlation between composables.

The heatmap is a grid where:

  • X-axis — time, scrollable, 1 pixel per second. You can scroll back through the session history (up to the configured retention, default 1 hour).
  • Y-axis — composables, sorted by peak rate (highest at top), scrollable. Composables that never recomposed are omitted.

Each cell is colored based on the composable’s rate relative to its budget at that point in time:

ColorConditionBudget Utilization
Dark grayNo data or zero rate0%
GreenWell within budget0-50%
YellowApproaching budget50-100%
RedOver budget (violation)>100%

The color interpolation is continuous, not discrete. A composable at 80% of its budget appears as a yellow-orange, giving a smooth visual gradient.

A horizontal band of yellow/red cells that lasts 2-5 seconds, then returns to green/gray. This is a normal scroll pattern — list items recompose during the scroll and settle afterward. If the band extends across many composables vertically, the scroll is cascading recompositions up the tree.

A composable that stays red for an extended period (30+ seconds) while the app is idle. This indicates a continuous recomposition source — a sensor, a timer, or an upstream state that changes frequently.

Multiple composables spiking at the same time point. This usually means a single state change at a high level is cascading recompositions through the tree. Look for the top-most composable in the spike — that is likely where the problem originates.

Regular spikes at fixed intervals (every 1 second, every 5 seconds). This suggests a timer or polling mechanism that triggers recompositions on a schedule.

Click or hover over any cell to see exact details:

  • Composable name
  • Rate at that timestamp
  • Budget and budget class
  • Interaction state at that time

The heatmap renders to a BufferedImage that is only redrawn when new snapshot data arrives. This avoids continuous repainting for a potentially large grid. Scrolling and zooming operate on the existing image buffer.

The heatmap is populated from SessionStore.snapshots — full metric snapshots stored at a configurable interval (default: every 5 seconds). Each snapshot becomes one column in the heatmap. With the default 5-second interval and 1-hour retention, the heatmap can display up to 720 columns of data.