Skip to content

Commit

Permalink
perf: Improve performance of lots of grids in a dashboard (#1987)
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
mofojed committed May 9, 2024
1 parent d1fba8f commit 3de52d6
Showing 1 changed file with 42 additions and 30 deletions.
72 changes: 42 additions & 30 deletions packages/grid/src/GridRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,34 @@ export class GridRenderer {
);
}

/**
* Cache shared between all grids. Often grids will have the same theme/colors, so we should share the cache.
*/
static getCachedBackgroundColors = memoizeClear(
(backgroundColors: GridColorWay, maxDepth: number): GridColor[][] =>
backgroundColors.split(' ').map(color => {
const colors = [];
for (let i = 0; i < maxDepth; i += 1) {
colors.push(GridColorUtils.darkenForDepth(color, i, maxDepth));
}
return colors;
}),
{ max: 1000 }
);

/**
* A memoized version of the GridColorUtils.colorWithAlpha function.
*/
static getCachedColorWithAlpha = memoizeClear(GridColorUtils.colorWithAlpha, {
max: 1000,
});

/**
* A memoized version of the ColorUtils.isDark function.
* ColorUtils.isDark is a very expensive function, and having a shared cache between all grids is a good idea.
*/
static getCachedColorIsDark = memoizeClear(ColorUtils.isDark, { max: 1000 });

/**
* Draw the grid canvas with the state provided
* @param state The state of the grid
Expand Down Expand Up @@ -596,7 +624,7 @@ export class GridRenderer {
const { theme, metrics, model } = state;
const { maxDepth, shadowBlur, shadowColor, shadowAlpha } = theme;

const colorSets = this.getCachedBackgroundColors(
const colorSets = GridRenderer.getCachedBackgroundColors(
rowBackgroundColors,
maxDepth
);
Expand Down Expand Up @@ -654,8 +682,11 @@ export class GridRenderer {
if (topShadowRows.length > 0) {
context.save();

const startColor = this.getCachedColorWithAlpha(shadowColor, shadowAlpha);
const endColor = this.getCachedColorWithAlpha(shadowColor, 0);
const startColor = GridRenderer.getCachedColorWithAlpha(
shadowColor,
shadowAlpha
);
const endColor = GridRenderer.getCachedColorWithAlpha(shadowColor, 0);
const gradient = context.createLinearGradient(0, 0, 0, shadowBlur);
gradient.addColorStop(0, startColor);
gradient.addColorStop(1, endColor);
Expand All @@ -676,8 +707,11 @@ export class GridRenderer {
if (bottomShadowRows.length > 0) {
context.save();

const startColor = this.getCachedColorWithAlpha(shadowColor, 0);
const endColor = this.getCachedColorWithAlpha(shadowColor, shadowAlpha);
const startColor = GridRenderer.getCachedColorWithAlpha(shadowColor, 0);
const endColor = GridRenderer.getCachedColorWithAlpha(
shadowColor,
shadowAlpha
);
const gradient = context.createLinearGradient(0, 0, 0, shadowBlur);
gradient.addColorStop(0, startColor);
gradient.addColorStop(1, endColor);
Expand Down Expand Up @@ -1082,29 +1116,6 @@ export class GridRenderer {
}
}

getCachedBackgroundColors = memoizeClear(
(backgroundColors: GridColorWay, maxDepth: number): GridColor[][] =>
backgroundColors.split(' ').map(color => {
const colors = [];
for (let i = 0; i < maxDepth; i += 1) {
colors.push(GridColorUtils.darkenForDepth(color, i, maxDepth));
}
return colors;
}),
{ max: 1000 }
);

getCachedColorWithAlpha = memoizeClear(
(color: string, alpha: number) =>
GridColorUtils.colorWithAlpha(color, alpha),
{ max: 1000 }
);

getCachedColorIsDark = memoizeClear(
(color: string) => ColorUtils.isDark(color),
{ max: 1000 }
);

drawHeaders(context: CanvasRenderingContext2D, state: GridRenderState): void {
const { theme } = state;

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

try {
const isDarkBackground = this.getCachedColorIsDark(backgroundColor);
const isDarkText = this.getCachedColorIsDark(textColor);
const isDarkBackground =
GridRenderer.getCachedColorIsDark(backgroundColor);
const isDarkText = GridRenderer.getCachedColorIsDark(textColor);
if (isDarkBackground && isDarkText) {
textColor = white;
} else if (!isDarkBackground && !isDarkText) {
Expand Down

0 comments on commit 3de52d6

Please sign in to comment.