-
Notifications
You must be signed in to change notification settings - Fork 14.4k
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
perf(dashboard): reduce number of rerenders of Charts #16444
Changes from 1 commit
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 |
---|---|---|
|
@@ -87,7 +87,8 @@ const defaultProps = { | |
// resizing across all slices on a dashboard on every update | ||
const RESIZE_TIMEOUT = 350; | ||
const SHOULD_UPDATE_ON_PROP_CHANGES = Object.keys(propTypes).filter( | ||
prop => prop !== 'width' && prop !== 'height', | ||
prop => | ||
prop !== 'width' && prop !== 'height' && prop !== 'isComponentVisible', | ||
); | ||
const OVERFLOWABLE_VIZ_TYPES = new Set(['filter_box']); | ||
const DEFAULT_HEADER_HEIGHT = 22; | ||
|
@@ -100,6 +101,8 @@ const ChartOverlay = styled.div` | |
`; | ||
|
||
export default class Chart extends React.Component { | ||
static whyDidYouRender = true; | ||
|
||
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. do we want to start introducing these in the codebase now? I'm fine either way 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. i have no idea what is this. Since this is open source code base, everything should either self-explained or well documented for the whole community. 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. I left that in by accident, thanks for pointing out! |
||
constructor(props) { | ||
super(props); | ||
this.state = { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,6 +25,7 @@ import { | |
import { ChartQueryPayload, Charts, LayoutItem } from 'src/dashboard/types'; | ||
import { getExtraFormData } from 'src/dashboard/components/nativeFilters/utils'; | ||
import { DataMaskStateWithId } from 'src/dataMask/types'; | ||
import { areObjectsEqual } from 'src/reduxUtils'; | ||
import getEffectiveExtraFilters from './getEffectiveExtraFilters'; | ||
import { ChartConfiguration, NativeFiltersState } from '../../reducers/types'; | ||
import { getAllActiveFilters } from '../activeAllDashboardFilters'; | ||
|
@@ -68,13 +69,15 @@ export default function getFormDataWithExtraFilters({ | |
|
||
// if dashboard metadata + filters have not changed, use cache if possible | ||
if ( | ||
(cachedFiltersByChart[sliceId] || {}) === filters && | ||
(colorScheme == null || | ||
cachedFormdataByChart[sliceId].color_scheme === colorScheme) && | ||
cachedFormdataByChart[sliceId].color_namespace === colorNamespace && | ||
isEqual(cachedFormdataByChart[sliceId].label_colors, labelColors) && | ||
cachedFiltersByChart[sliceId] === filters && | ||
(colorScheme === null || | ||
cachedFormdataByChart[sliceId]?.color_scheme === colorScheme) && | ||
cachedFormdataByChart[sliceId]?.color_namespace === colorNamespace && | ||
isEqual(cachedFormdataByChart[sliceId]?.label_colors, labelColors) && | ||
!!cachedFormdataByChart[sliceId] && | ||
dataMask === undefined | ||
areObjectsEqual(cachedFormdataByChart[sliceId]?.dataMask, dataMask, { | ||
ignoreUndefined: true, | ||
}) | ||
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. While we're modifying code here and for the sake of DRY, would it make sense to break out const cachedFormdata = cachedFormdataByChart[sliceId]; 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. Agreed. Btw, Is it designed to not use the cache when the
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. Great point Stephen! I think we can safely remove 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. Issues from both comments fixed |
||
) { | ||
return cachedFormdataByChart[sliceId]; | ||
} | ||
|
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.
Thanks for the work! this perf improvement work is great!
Before: chart component not update when width or height changed,
after: chart component not update width or height or visibility change.
But when chart component hide and show when tab changes, why chart component not need update?
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.
In
shouldComponentUpdate
we have aif(isComponentVisible)
statement followed by additional checks if component should render. The point is that we run those only when component is visible.In other words,
isComponentVisible
should be used to decide if we should run checks to determine if component should be rerendered. However, the change ofisComponentVisible
alone shouldn't trigger a rerender, because it's already rendered. You can check out that behaviour by switching tabs back and forth. On the first change of tab,isComponentVisible
changes, but so do other props, so the chart is rerendered. But if you go back to previous tab, onlyisComponentVisible
changes, so there's no point in rerendering a chart because there are no changes that would affect that chart.Sorry for rambling, I hope that it makes sense 😆