Skip to content

Do something useful with the selection when applying transforms - #6454

Open
mstange wants to merge 2 commits into
firefox-devtools:mainfrom
mstange:push-pwxywqtwplys
Open

mstange wants to merge 2 commits into
firefox-devtools:mainfrom
mstange:push-pwxywqtwplys

Conversation

@mstange

@mstange mstange commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Main | Deploy preview

Fixes #4618 and the problem that @canova mentioned in #6403 (review) .

@codecov

codecov Bot commented Nov 11, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.50000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.03%. Comparing base (68f63c0) to head (852adf9).
⚠️ Report is 11 commits behind head on main.

Files with missing lines Patch % Lines
src/profile-logic/transforms.ts 87.50% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6454      +/-   ##
==========================================
+ Coverage   84.97%   85.03%   +0.06%     
==========================================
  Files         359      363       +4     
  Lines       39170    39785     +615     
  Branches    11115    11331     +216     
==========================================
+ Hits        33284    33831     +547     
- Misses       5449     5515      +66     
- Partials      437      439       +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@mstange
mstange marked this pull request as ready for review November 11, 2026 15:32
@mstange
mstange requested a review from canova November 11, 2026 15:32
Fixes firefox-devtools#4618.

Previously, transforms such as "drop function" cleared the call tree
selection, and "merge function" moved the selection to the parent node.
Now addTransformToStack captures the old selection before dispatching
the transform, and then picks a replacement from the transformed tree:

- If the selected node survives, it stays selected.
- If the selected node was merged, we pick its caller, like before. This
  lets users merge a chain of callers by pressing "m" repeatedly. In the
  inverted tree, the callers are the children, so we pick the heaviest
  child, which takes the place of the merged node.
- Otherwise, or if there is no caller, we pick the node that moves into
  the selected node's position among its siblings. If there are fewer
  siblings now, we pick the last one, and if there are none, the parent.

We pick by position because the transform changes the totals of the
siblings too, and they get re-sorted. The siblings that shared stacks
with the removed node lose the most samples. So picking the old neighbor
of the selected node could move the selection far away. This happens a
lot among the roots of the inverted tree.

We use the same rule in all tabs, because the selection is shared
between the call tree, the flame graph and the stack chart. The rule
follows the call tree's order of siblings, by total.

Candidates are only accepted if they are displayed in the transformed
tree, which also covers paths whose samples were all filtered out (firefox-devtools#4618).

The two tests for inverted trees applied non-inverted transforms to
inverted paths, so the expected paths didn't exist in the transformed
tree. They now use transforms that make sense for inverted trees.
Previously, the function list kept the selected function after a
transform, even if the transform removed it, for example with "merge
function" or "drop function". The sidebar would keep showing a
function that wasn't in the list anymore.

Now addTransformToStack also picks a replacement for the selected
function: the function itself if it survives, otherwise the function
that is now in the selected function's row. This lets users press "d"
repeatedly to work their way down the list. Changing the selected
function also re-roots the wings.

We pick by position because the list is re-sorted after the transform.
The functions that shared stacks with the removed function lose the most
samples. So picking the old neighbor of the selected function could move
the selection far down the list.

To map functions through a transform, this adds applyTransformToFuncIndex,
the function-level equivalent of applyTransformToCallNodePath.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

After transforms, if the selected call node is not present in the call tree find a close-by call node to select

1 participant