From d865ae160f9f9be38cf66a32ca7d03f2d90cb93e Mon Sep 17 00:00:00 2001 From: adrian3de Date: Tue, 21 Mar 2023 17:44:56 +0200 Subject: [PATCH] feat: improve the grid responsiveness by caching and reusing the last style object (#873) --- .../src/lib/gridsterRenderer.interface.ts | 17 ++++ .../src/lib/gridsterRenderer.service.ts | 85 ++++++++++++++++--- 2 files changed, 89 insertions(+), 13 deletions(-) create mode 100644 projects/angular-gridster2/src/lib/gridsterRenderer.interface.ts diff --git a/projects/angular-gridster2/src/lib/gridsterRenderer.interface.ts b/projects/angular-gridster2/src/lib/gridsterRenderer.interface.ts new file mode 100644 index 00000000..8b65f87b --- /dev/null +++ b/projects/angular-gridster2/src/lib/gridsterRenderer.interface.ts @@ -0,0 +1,17 @@ +export interface CommonGridStyle { + [key: string]: string; +} + +export interface CommonGridCachedStyle { + width: number; + height: number; + style: CommonGridStyle; +} + +export interface GridColumnCachedStyle extends CommonGridCachedStyle { + left: number; +} + +export interface GridRowCachedStyle extends CommonGridCachedStyle { + top: number; +} diff --git a/projects/angular-gridster2/src/lib/gridsterRenderer.service.ts b/projects/angular-gridster2/src/lib/gridsterRenderer.service.ts index 3b6f968d..5d78eb4c 100644 --- a/projects/angular-gridster2/src/lib/gridsterRenderer.service.ts +++ b/projects/angular-gridster2/src/lib/gridsterRenderer.service.ts @@ -3,8 +3,25 @@ import { Renderer2 } from '@angular/core'; import { GridsterComponentInterface } from './gridster.interface'; import { DirTypes, GridType } from './gridsterConfig.interface'; import { GridsterItem } from './gridsterItem.interface'; +import { + CommonGridStyle, + GridColumnCachedStyle, + GridRowCachedStyle +} from './gridsterRenderer.interface'; export class GridsterRenderer { + /** + * Caches the last grid column styles. + * This improves the grid responsiveness by caching and reusing the last style object instead of creating a new one. + */ + private lastGridColumnStyles: { [key: number]: GridColumnCachedStyle } = {}; + + /** + * Caches the last grid row styles. + * This improves the grid responsiveness by caching and reusing the last style object instead of creating a new one. + */ + private lastGridRowStyles: { [key: number]: GridRowCachedStyle } = {}; + constructor(private gridster: GridsterComponentInterface) {} destroy(): void { @@ -160,26 +177,68 @@ export class GridsterRenderer { this.gridster.renderer.removeClass(this.gridster.el, removeClass3); } - getGridColumnStyle(i: number): { [key: string]: string } { - return { - ...this.getLeftPosition(this.gridster.curColWidth * i), - width: this.gridster.curColWidth - this.gridster.$options.margin + 'px', + getGridColumnStyle(i: number): CommonGridStyle { + // generates the new style + const newPos: GridColumnCachedStyle = { + left: this.gridster.curColWidth * i, + width: this.gridster.curColWidth - this.gridster.$options.margin, height: this.gridster.gridRows.length * this.gridster.curRowHeight - - this.gridster.$options.margin + - 'px' + this.gridster.$options.margin, + style: {} }; + newPos.style = { + ...this.getLeftPosition(newPos.left), + width: newPos.width + 'px', + height: newPos.height + 'px' + }; + + // use the last cached style if it has same values as the generated one + const last = this.lastGridColumnStyles[i]; + if ( + last && + last.left === newPos.left && + last.width === newPos.width && + last.height === newPos.height + ) { + return last.style; + } + + // cache and set new style + this.lastGridColumnStyles[i] = newPos; + return newPos.style; } - getGridRowStyle(i: number): { [key: string]: string } { - return { - ...this.getTopPosition(this.gridster.curRowHeight * i), + getGridRowStyle(i: number): CommonGridStyle { + // generates the new style + const newPos: GridRowCachedStyle = { + top: this.gridster.curRowHeight * i, width: - this.gridster.gridColumns.length * this.gridster.curColWidth - - this.gridster.$options.margin + - 'px', - height: this.gridster.curRowHeight - this.gridster.$options.margin + 'px' + this.gridster.gridColumns.length * this.gridster.curColWidth + + this.gridster.$options.margin, + height: this.gridster.curRowHeight - this.gridster.$options.margin, + style: {} + }; + newPos.style = { + ...this.getTopPosition(newPos.top), + width: newPos.width + 'px', + height: newPos.height + 'px' }; + + // use the last cached style if it has same values as the generated one + const last = this.lastGridRowStyles[i]; + if ( + last && + last.top === newPos.top && + last.width === newPos.width && + last.height === newPos.height + ) { + return last.style; + } + + // cache and set new style + this.lastGridRowStyles[i] = newPos; + return newPos.style; } getLeftPosition(d: number): { left: string } | { transform: string } {