Skip to content

Commit 3de52d6

Browse files
authored
perf: Improve performance of lots of grids in a dashboard (#1987)
- Each GridRenderer had an independent cache for checking various colour operations, instead use a shared cache - Grids are likely to share the same colours because they have similar themes anyway - Improves performance when opening dashboards with lots of grids
1 parent d1fba8f commit 3de52d6

1 file changed

Lines changed: 42 additions & 30 deletions

File tree

packages/grid/src/GridRenderer.ts

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,34 @@ export class GridRenderer {
145145
);
146146
}
147147

148+
/**
149+
* Cache shared between all grids. Often grids will have the same theme/colors, so we should share the cache.
150+
*/
151+
static getCachedBackgroundColors = memoizeClear(
152+
(backgroundColors: GridColorWay, maxDepth: number): GridColor[][] =>
153+
backgroundColors.split(' ').map(color => {
154+
const colors = [];
155+
for (let i = 0; i < maxDepth; i += 1) {
156+
colors.push(GridColorUtils.darkenForDepth(color, i, maxDepth));
157+
}
158+
return colors;
159+
}),
160+
{ max: 1000 }
161+
);
162+
163+
/**
164+
* A memoized version of the GridColorUtils.colorWithAlpha function.
165+
*/
166+
static getCachedColorWithAlpha = memoizeClear(GridColorUtils.colorWithAlpha, {
167+
max: 1000,
168+
});
169+
170+
/**
171+
* A memoized version of the ColorUtils.isDark function.
172+
* ColorUtils.isDark is a very expensive function, and having a shared cache between all grids is a good idea.
173+
*/
174+
static getCachedColorIsDark = memoizeClear(ColorUtils.isDark, { max: 1000 });
175+
148176
/**
149177
* Draw the grid canvas with the state provided
150178
* @param state The state of the grid
@@ -596,7 +624,7 @@ export class GridRenderer {
596624
const { theme, metrics, model } = state;
597625
const { maxDepth, shadowBlur, shadowColor, shadowAlpha } = theme;
598626

599-
const colorSets = this.getCachedBackgroundColors(
627+
const colorSets = GridRenderer.getCachedBackgroundColors(
600628
rowBackgroundColors,
601629
maxDepth
602630
);
@@ -654,8 +682,11 @@ export class GridRenderer {
654682
if (topShadowRows.length > 0) {
655683
context.save();
656684

657-
const startColor = this.getCachedColorWithAlpha(shadowColor, shadowAlpha);
658-
const endColor = this.getCachedColorWithAlpha(shadowColor, 0);
685+
const startColor = GridRenderer.getCachedColorWithAlpha(
686+
shadowColor,
687+
shadowAlpha
688+
);
689+
const endColor = GridRenderer.getCachedColorWithAlpha(shadowColor, 0);
659690
const gradient = context.createLinearGradient(0, 0, 0, shadowBlur);
660691
gradient.addColorStop(0, startColor);
661692
gradient.addColorStop(1, endColor);
@@ -676,8 +707,11 @@ export class GridRenderer {
676707
if (bottomShadowRows.length > 0) {
677708
context.save();
678709

679-
const startColor = this.getCachedColorWithAlpha(shadowColor, 0);
680-
const endColor = this.getCachedColorWithAlpha(shadowColor, shadowAlpha);
710+
const startColor = GridRenderer.getCachedColorWithAlpha(shadowColor, 0);
711+
const endColor = GridRenderer.getCachedColorWithAlpha(
712+
shadowColor,
713+
shadowAlpha
714+
);
681715
const gradient = context.createLinearGradient(0, 0, 0, shadowBlur);
682716
gradient.addColorStop(0, startColor);
683717
gradient.addColorStop(1, endColor);
@@ -1082,29 +1116,6 @@ export class GridRenderer {
10821116
}
10831117
}
10841118

1085-
getCachedBackgroundColors = memoizeClear(
1086-
(backgroundColors: GridColorWay, maxDepth: number): GridColor[][] =>
1087-
backgroundColors.split(' ').map(color => {
1088-
const colors = [];
1089-
for (let i = 0; i < maxDepth; i += 1) {
1090-
colors.push(GridColorUtils.darkenForDepth(color, i, maxDepth));
1091-
}
1092-
return colors;
1093-
}),
1094-
{ max: 1000 }
1095-
);
1096-
1097-
getCachedColorWithAlpha = memoizeClear(
1098-
(color: string, alpha: number) =>
1099-
GridColorUtils.colorWithAlpha(color, alpha),
1100-
{ max: 1000 }
1101-
);
1102-
1103-
getCachedColorIsDark = memoizeClear(
1104-
(color: string) => ColorUtils.isDark(color),
1105-
{ max: 1000 }
1106-
);
1107-
11081119
drawHeaders(context: CanvasRenderingContext2D, state: GridRenderState): void {
11091120
const { theme } = state;
11101121

@@ -1547,8 +1558,9 @@ export class GridRenderer {
15471558
let { textColor = headerColor } = style ?? {};
15481559

15491560
try {
1550-
const isDarkBackground = this.getCachedColorIsDark(backgroundColor);
1551-
const isDarkText = this.getCachedColorIsDark(textColor);
1561+
const isDarkBackground =
1562+
GridRenderer.getCachedColorIsDark(backgroundColor);
1563+
const isDarkText = GridRenderer.getCachedColorIsDark(textColor);
15521564
if (isDarkBackground && isDarkText) {
15531565
textColor = white;
15541566
} else if (!isDarkBackground && !isDarkText) {

0 commit comments

Comments
 (0)