-
Notifications
You must be signed in to change notification settings - Fork 482
Hide the user interface components showing stacks for tracks that don't have stack samples #4133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,7 +5,11 @@ | |
| // @flow | ||
| import { createSelector } from 'reselect'; | ||
|
|
||
| import { tabSlugs, type TabSlug } from '../../app-logic/tabs-handling'; | ||
| import { | ||
| tabSlugs, | ||
| type TabSlug, | ||
| tabsShowingSampleData, | ||
| } from '../../app-logic/tabs-handling'; | ||
|
|
||
| import type { | ||
| Selector, | ||
|
|
@@ -22,6 +26,8 @@ import type { | |
| StackTimingByDepth, | ||
| } from '../../profile-logic/stack-timing'; | ||
|
|
||
| import { ensureExists } from '../../utils/flow'; | ||
|
|
||
| /** | ||
| * Infer the return type from the getStackAndSampleSelectorsPerThread function. This | ||
| * is done that so that the local type definition with `Selector<T>` is the canonical | ||
|
|
@@ -59,7 +65,15 @@ export function getComposedSelectorsPerThread( | |
| threadSelectors.getThread, | ||
| threadSelectors.getIsNetworkChartEmptyInFullRange, | ||
| threadSelectors.getJsTracerTable, | ||
| ({ processType }, isNetworkChartEmpty, jsTracerTable) => { | ||
| (thread, isNetworkChartEmpty, jsTracerTable) => { | ||
| const { | ||
| processType, | ||
| samples, | ||
| stackTable, | ||
| stringTable, | ||
| frameTable, | ||
| funcTable, | ||
| } = thread; | ||
| if (processType === 'comparison') { | ||
| // For a diffing tracks, we display only the calltree tab for now, because | ||
| // other views make no or not much sense. | ||
|
|
@@ -76,6 +90,27 @@ export function getComposedSelectorsPerThread( | |
| if (!jsTracerTable) { | ||
| visibleTabs = visibleTabs.filter((tabSlug) => tabSlug !== 'js-tracer'); | ||
| } | ||
| let hasSamples = samples.length > 0 && stackTable.length > 0; | ||
| if (hasSamples) { | ||
| const stackIndex = ensureExists(samples.stack[0]); | ||
| if (stackTable.prefix[stackIndex] === null) { | ||
| // There's only a single stack frame, check if it's '(root)'. | ||
| const frameIndex = stackTable.frame[stackIndex]; | ||
| const funcIndex = frameTable.func[frameIndex]; | ||
| const stringIndex = funcTable.name[funcIndex]; | ||
| if (stringTable.getString(stringIndex) === '(root)') { | ||
| // If the first sample's stack is only the root, check if any other | ||
| // sample is different. | ||
| hasSamples = samples.stack.some((s) => s !== stackIndex); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm, this looks a bit costly, but probably it's going to return early after two iterations for most of our profiles. And not sure how else we can do it without looping. I think it's okay to keep like this.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it could be faster to:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
| } | ||
| } | ||
| } | ||
|
|
||
| if (!hasSamples) { | ||
| visibleTabs = visibleTabs.filter( | ||
| (tabSlug) => !tabsShowingSampleData.includes(tabSlug) | ||
| ); | ||
| } | ||
| return visibleTabs; | ||
| } | ||
| ); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ import { selectedThreadSelectors } from '../../selectors/per-thread'; | |
|
|
||
| import { storeWithProfile } from '../fixtures/stores'; | ||
| import { | ||
| getMarkerTableProfile, | ||
| getProfileFromTextSamples, | ||
| getProfileWithMarkers, | ||
| getNetworkMarkers, | ||
|
|
@@ -33,9 +34,6 @@ describe('getUsefulTabs', function () { | |
| const profile = getProfileWithMarkers(getNetworkMarkers()); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you add a small tests for this new behavior too? We already see that in some of the tests, we don't have the sample related tabs anymore since the profiles only include markers, but it could be nice to add a simple test that checks this new behavior only. |
||
| const { getState } = storeWithProfile(profile); | ||
| expect(selectedThreadSelectors.getUsefulTabs(getState())).toEqual([ | ||
| 'calltree', | ||
| 'flame-graph', | ||
| 'stack-chart', | ||
| 'marker-chart', | ||
| 'marker-table', | ||
| 'network-chart', | ||
|
|
@@ -46,9 +44,6 @@ describe('getUsefulTabs', function () { | |
| const profile = getProfileWithJsTracerEvents([['A', 0, 10]]); | ||
| const { getState } = storeWithProfile(profile); | ||
| expect(selectedThreadSelectors.getUsefulTabs(getState())).toEqual([ | ||
| 'calltree', | ||
| 'flame-graph', | ||
| 'stack-chart', | ||
| 'marker-chart', | ||
| 'marker-table', | ||
| 'js-tracer', | ||
|
|
@@ -97,12 +92,27 @@ describe('getUsefulTabs', function () { | |
|
|
||
| // Check the tabs and make sure that the network chart is there. | ||
| expect(selectedThreadSelectors.getUsefulTabs(getState())).toEqual([ | ||
| 'calltree', | ||
| 'flame-graph', | ||
| 'stack-chart', | ||
| 'marker-chart', | ||
| 'marker-table', | ||
| 'network-chart', | ||
| ]); | ||
| }); | ||
|
|
||
| it('hides sample related tabs when there is no sample data in the profile', function () { | ||
| const profile = getMarkerTableProfile(); | ||
| const { getState } = storeWithProfile(profile); | ||
| expect(selectedThreadSelectors.getUsefulTabs(getState())).toEqual([ | ||
| 'marker-chart', | ||
| 'marker-table', | ||
| ]); | ||
| }); | ||
|
|
||
| it('hides sample related tabs when samples contain only the (root) frame', function () { | ||
| const { profile } = getProfileFromTextSamples('(root)'); | ||
| const { getState } = storeWithProfile(profile); | ||
| expect(selectedThreadSelectors.getUsefulTabs(getState())).toEqual([ | ||
| 'marker-chart', | ||
| 'marker-table', | ||
| ]); | ||
| }); | ||
| }); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a good idea to hide the stacks if we only have
(root)! It wasn't looking good anyways.