Skip to content

Commit cab0024

Browse files
MayaKirovaMKirovarkaraivanov
authored
feat(grids): Apply different throttle based on the amount of data in display
--------- Co-authored-by: MKirova <MKirova@DEV-MKIROVA> Co-authored-by: Radoslav Karaivanov <rkaraivanov@infragistics.com>
1 parent b05bee1 commit cab0024

13 files changed

Lines changed: 73 additions & 32 deletions

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ All notable changes for each version of this project will be documented in this
1717
```
1818

1919
### General
20+
21+
- `IgxGrid`, `IgxTreeGrid`, `IgxHierarchicalGrid`, `IgxPivotGrid`
22+
- Improved performance by dynamically adjusting the scroll throttle based on the data displayed in grid.
23+
2024
- `IgxCombo`, `IgxSimpleCombo`
2125
- Combo and Simple Combo now close the dropdown list and move the focus to the next focusable element on "Tab" press and clear the selection if the combo is collapsed on "Escape".
2226

projects/igniteui-angular/directives/src/directives/for-of/for_of.directive.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ export abstract class IgxForOfToken<T, U extends T[] = T[]> {
6464

6565
public abstract chunkLoad: EventEmitter<IForOfState>;
6666
public abstract chunkPreload: EventEmitter<IForOfState>;
67+
public abstract chunkSizeChange: EventEmitter<number>;
6768

6869
public abstract scrollTo(index: number): void;
6970
public abstract getScrollForIndex(index: number, bottom?: boolean): number;
@@ -203,6 +204,13 @@ export class IgxForOfDirective<T, U extends T[] = T[]> extends IgxForOfToken<T,U
203204
@Output()
204205
public scrollbarVisibilityChanged = new EventEmitter<any>();
205206

207+
/**
208+
* @hidden @internal
209+
* An event that is emitted when chunk size is changing. Emits new value.
210+
*/
211+
@Output()
212+
public chunkSizeChange = new EventEmitter<number>();
213+
206214
/**
207215
* An event that is emitted after the rendered content size of the igxForOf has been changed.
208216
*/
@@ -1453,6 +1461,9 @@ export class IgxForOfDirective<T, U extends T[] = T[]> extends IgxForOfToken<T,U
14531461
*/
14541462
protected applyChunkSizeChange() {
14551463
const chunkSize = this.isRemote ? (this.igxForOf ? this.igxForOf.length : 0) : this._calculateChunkSize();
1464+
if (chunkSize !== this.state.chunkSize) {
1465+
this.chunkSizeChange.emit(chunkSize);
1466+
}
14561467
if (chunkSize > this.state.chunkSize) {
14571468
const diff = chunkSize - this.state.chunkSize;
14581469
for (let i = 0; i < diff; i++) {

projects/igniteui-angular/grids/grid/src/grid-base.directive.ts

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@ import {
9494
onResourceChangeHandle
9595
} from 'igniteui-angular/core';
9696
import { IgcTrialWatermark } from 'igniteui-trial-watermark';
97-
import { Subject, pipe, fromEvent, animationFrameScheduler, merge } from 'rxjs';
98-
import { takeUntil, first, filter, throttleTime, map, shareReplay, takeWhile } from 'rxjs/operators';
97+
import { Subject, pipe, fromEvent, animationFrameScheduler, merge, BehaviorSubject, timer } from 'rxjs';
98+
import { takeUntil, first, filter, throttleTime, map, shareReplay, takeWhile, throttle, take, switchMap } from 'rxjs/operators';
9999
import {
100100
IgxToggleDirective,
101101
IForOfDataChangeEventArgs,
@@ -113,11 +113,11 @@ import { getCurrentI18n, getNumberFormatter, IResourceChangeEventArgs, } from '
113113
import { I18N_FORMATTER } from 'igniteui-angular/core';
114114

115115
/**
116-
* Injection token for setting the throttle time used in grid virtual scroll.
116+
* Injection token for setting the throttle time multiplier used in grid virtual scroll.
117117
* @hidden
118118
*/
119-
export const SCROLL_THROTTLE_TIME = /*@__PURE__*/new InjectionToken<number>('SCROLL_THROTTLE_TIME', {
120-
factory: () => 40
119+
export const SCROLL_THROTTLE_TIME_MULTIPLIER = /*@__PURE__*/new InjectionToken<number>('SCROLL_THROTTLE_TIME_MULTIPLIER', {
120+
factory: () => 10
121121
});
122122

123123

@@ -177,7 +177,11 @@ export abstract class IgxGridBaseDirective implements GridType,
177177
protected _diTransactions = inject(IgxGridTransaction, { optional: true });
178178
/** @hidden @internal */
179179
public i18nFormatter = inject(I18N_FORMATTER);
180-
private readonly THROTTLE_TIME = inject(SCROLL_THROTTLE_TIME);
180+
private readonly THROTTLE_TIME_MULTIPLIER = inject(SCROLL_THROTTLE_TIME_MULTIPLIER);
181+
private throttleTime$ = new BehaviorSubject<number>(this.THROTTLE_TIME_MULTIPLIER);
182+
/** @hidden @internal */
183+
public throttleScheduler = animationFrameScheduler;
184+
private readonly MAX_SCROLL_THROTTLE: number = 60;
181185

182186
/**
183187
* Gets/Sets the display time for the row adding snackbar notification.
@@ -3731,7 +3735,12 @@ export abstract class IgxGridBaseDirective implements GridType,
37313735

37323736
this.scrollNotify.pipe(
37333737
filter(() => !this._init),
3734-
throttleTime(this.THROTTLE_TIME, animationFrameScheduler, { leading: false, trailing: true }),
3738+
throttle(() =>
3739+
this.throttleTime$.pipe(
3740+
take(1),
3741+
switchMap(time => timer(time, this.throttleScheduler))
3742+
)
3743+
),
37353744
destructor
37363745
)
37373746
.subscribe((event) => {
@@ -3822,6 +3831,14 @@ export abstract class IgxGridBaseDirective implements GridType,
38223831
this.updateMergedData();
38233832
});
38243833

3834+
this.verticalScrollContainer.chunkSizeChange.pipe(destructor).subscribe((count: number) => {
3835+
this.updateScrollThrottle(count * this.headerContainer.state.chunkSize);
3836+
});
3837+
3838+
this.headerContainer?.chunkSizeChange.pipe(destructor).subscribe((count: number) => {
3839+
this.updateScrollThrottle(count * this.verticalScrollContainer.state.chunkSize);
3840+
});
3841+
38253842
this.verticalScrollContainer.scrollbarVisibilityChanged.pipe(filter(() => !this._init), destructor).subscribe(() => {
38263843
// called to recalc all widths that may have changes as a result of
38273844
// the vert. scrollbar showing/hiding
@@ -3969,6 +3986,12 @@ export abstract class IgxGridBaseDirective implements GridType,
39693986
return this._mergedDataInView;
39703987
}
39713988

3989+
protected updateScrollThrottle(cells: number) {
3990+
// for less than 100 - throttle 0, 10ms more for every 100 cells upto max of 60ms
3991+
const currentThrottle = cells <= 100 ? 0 : Math.floor(cells / 100) * this.THROTTLE_TIME_MULTIPLIER;
3992+
this.throttleTime$.next(Math.min(currentThrottle, this.MAX_SCROLL_THROTTLE));
3993+
}
3994+
39723995
/**
39733996
* @hidden
39743997
* @internal

projects/igniteui-angular/grids/grid/src/grid-cell-selection.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { TestBed, fakeAsync, tick, ComponentFixture, waitForAsync } from '@angular/core/testing';
22
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
33
import { IgxGridComponent } from './public_api';
4-
import { SCROLL_THROTTLE_TIME } from './../src/grid-base.directive';
4+
import { SCROLL_THROTTLE_TIME_MULTIPLIER } from './../src/grid-base.directive';
55
import {
66
SelectionWithScrollsComponent,
77
SelectionWithTransactionsComponent,
@@ -980,7 +980,7 @@ describe('IgxGrid - Cell selection #grid', () => {
980980

981981
beforeEach(() => {
982982
TestBed.configureTestingModule({
983-
providers: [{ provide: SCROLL_THROTTLE_TIME, useValue: 0 }]
983+
providers: [{ provide: SCROLL_THROTTLE_TIME_MULTIPLIER, useValue: 0 }]
984984
});
985985
fix = TestBed.createComponent(SelectionWithScrollsComponent);
986986
fix.detectChanges();

projects/igniteui-angular/grids/grid/src/grid-keyBoardNav.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { DebugElement, QueryList } from '@angular/core';
1515
import { IgxGridGroupByRowComponent } from './groupby-row.component';
1616
import { CellType } from 'igniteui-angular/grids/core';
1717
import { DefaultSortingStrategy, SortingDirection } from 'igniteui-angular/core';
18-
import { SCROLL_THROTTLE_TIME } from './../src/grid-base.directive';
18+
import { SCROLL_THROTTLE_TIME_MULTIPLIER } from './../src/grid-base.directive';
1919

2020
const DEBOUNCETIME = 100;
2121

@@ -224,7 +224,7 @@ describe('IgxGrid - Keyboard navigation #grid', () => {
224224

225225
beforeEach(() => {
226226
TestBed.configureTestingModule({
227-
providers: [{ provide: SCROLL_THROTTLE_TIME, useValue: 0 }]
227+
providers: [{ provide: SCROLL_THROTTLE_TIME_MULTIPLIER, useValue: 0 }]
228228
});
229229
fix = TestBed.createComponent(VirtualGridComponent);
230230
fix.detectChanges();

projects/igniteui-angular/grids/grid/src/grid-mrl-keyboard-nav.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { GridFunctions, GRID_MRL_BLOCK } from '../../../test-utils/grid-function
1111
import { CellType, IGridCellEventArgs, IgxColumnComponent, IgxGridMRLNavigationService } from 'igniteui-angular/grids/core';
1212
import { IgxColumnLayoutComponent } from 'igniteui-angular/grids/core';
1313
import { DefaultSortingStrategy, SortingDirection } from 'igniteui-angular/core';
14-
import { SCROLL_THROTTLE_TIME } from './../src/grid-base.directive';
14+
import { SCROLL_THROTTLE_TIME_MULTIPLIER } from './../src/grid-base.directive';
1515

1616
const DEBOUNCE_TIME = 60;
1717
const CELL_CSS_CLASS = '.igx-grid__td';
@@ -30,7 +30,7 @@ describe('IgxGrid Multi Row Layout - Keyboard navigation #grid', () => {
3030

3131
beforeEach(() => {
3232
TestBed.configureTestingModule({
33-
providers: [{ provide: SCROLL_THROTTLE_TIME, useValue: 0 }]
33+
providers: [{ provide: SCROLL_THROTTLE_TIME_MULTIPLIER, useValue: 0 }]
3434
});
3535
fix = TestBed.createComponent(ColumnLayoutTestComponent);
3636
});

projects/igniteui-angular/grids/grid/src/grid.component.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { AsyncPipe } from '@angular/common';
1818
import { setElementSize, ymd } from '../../../test-utils/helper-utils.spec';
1919
import { FilteringExpressionsTree, FilteringLogic, getComponentSize, GridColumnDataType, IgxNumberFilteringOperand, IgxStringFilteringOperand, ISortingExpression, ɵSize, SortingDirection } from 'igniteui-angular/core';
2020
import { IgxPaginatorComponent, IgxPaginatorContentDirective } from 'igniteui-angular/paginator';
21-
import { SCROLL_THROTTLE_TIME } from './../src/grid-base.directive';
21+
import { SCROLL_THROTTLE_TIME_MULTIPLIER } from './../src/grid-base.directive';
2222

2323
describe('IgxGrid Component Tests #grid', () => {
2424
const MIN_COL_WIDTH = '136px';
@@ -44,7 +44,7 @@ describe('IgxGrid Component Tests #grid', () => {
4444

4545
beforeEach(() => {
4646
TestBed.configureTestingModule({
47-
providers: [{ provide: SCROLL_THROTTLE_TIME, useValue: 0 }]
47+
providers: [{ provide: SCROLL_THROTTLE_TIME_MULTIPLIER, useValue: 0 }]
4848
});
4949
});
5050

projects/igniteui-angular/grids/grid/src/grid.master-detail.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { GridSummaryCalculationMode, IgxStringFilteringOperand, SortingDirection
1515
import { IgxCheckboxComponent } from 'igniteui-angular/checkbox';
1616
import { IgxInputDirective, IgxInputGroupComponent } from 'igniteui-angular/input-group';
1717
import { IgxPaginatorComponent } from 'igniteui-angular/paginator';
18-
import { SCROLL_THROTTLE_TIME } from './../src/grid-base.directive';
18+
import { SCROLL_THROTTLE_TIME_MULTIPLIER } from './../src/grid-base.directive';
1919

2020
const DEBOUNCE_TIME = 60;
2121
const ROW_TAG = 'igx-grid-row';
@@ -46,7 +46,7 @@ describe('IgxGrid Master Detail #grid', () => {
4646

4747
beforeEach(waitForAsync(() => {
4848
TestBed.configureTestingModule({
49-
providers: [{ provide: SCROLL_THROTTLE_TIME, useValue: 0 }]
49+
providers: [{ provide: SCROLL_THROTTLE_TIME_MULTIPLIER, useValue: 0 }]
5050
});
5151
}));
5252

projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.navigation.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { clearGridSubs, setupHierarchicalGridScrollDetection } from '../../../te
1010
import { GridFunctions } from '../../../test-utils/grid-functions.spec';
1111
import { IGridCellEventArgs, IgxColumnComponent, IgxGridCellComponent, IgxGridNavigationService } from 'igniteui-angular/grids/core';
1212
import { IPathSegment } from 'igniteui-angular/core';
13-
import { SCROLL_THROTTLE_TIME } from './../../grid/src/grid-base.directive';
13+
import { SCROLL_THROTTLE_TIME_MULTIPLIER } from './../../grid/src/grid-base.directive';
1414

1515
const DEBOUNCE_TIME = 60;
1616
const GRID_CONTENT_CLASS = '.igx-grid__tbody-content';
@@ -40,7 +40,7 @@ describe('IgxHierarchicalGrid Navigation', () => {
4040

4141
beforeEach(waitForAsync(() => {
4242
TestBed.configureTestingModule({
43-
providers: [{ provide: SCROLL_THROTTLE_TIME, useValue: 0 }]
43+
providers: [{ provide: SCROLL_THROTTLE_TIME_MULTIPLIER, useValue: 0 }]
4444
});
4545
}));
4646

@@ -50,7 +50,7 @@ describe('IgxHierarchicalGrid Navigation', () => {
5050

5151
beforeEach(waitForAsync(() => {
5252
TestBed.configureTestingModule({
53-
providers: [{ provide: SCROLL_THROTTLE_TIME, useValue: 0 }]
53+
providers: [{ provide: SCROLL_THROTTLE_TIME_MULTIPLIER, useValue: 0 }]
5454
});
5555
fixture = TestBed.createComponent(IgxHierarchicalGridTestBaseComponent);
5656
fixture.detectChanges();
@@ -965,7 +965,7 @@ describe('IgxHierarchicalGrid Navigation', () => {
965965
describe('IgxHierarchicalGrid Navigation API #hGrid', () => {
966966
beforeEach(waitForAsync(() => {
967967
TestBed.configureTestingModule({
968-
providers: [{ provide: SCROLL_THROTTLE_TIME, useValue: 1 }]
968+
providers: [{ provide: SCROLL_THROTTLE_TIME_MULTIPLIER, useValue: 0 }]
969969
});
970970
fixture = TestBed.createComponent(IgxHierarchicalGridMultiLayoutComponent);
971971
fixture.detectChanges();

projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.virtualization.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { IgxHierarchicalGridDefaultComponent } from '../../../test-utils/hierarc
1414
import { firstValueFrom } from 'rxjs';
1515
import { FilteringExpressionsTree, FilteringLogic, IgxStringFilteringOperand } from 'igniteui-angular/core';
1616
import { IgxGridNavigationService } from 'igniteui-angular/grids/core';
17-
import { SCROLL_THROTTLE_TIME } from './../../grid/src/grid-base.directive';
17+
import { SCROLL_THROTTLE_TIME_MULTIPLIER } from './../../grid/src/grid-base.directive';
1818

1919
describe('IgxHierarchicalGrid Virtualization #hGrid', () => {
2020
let fixture;
@@ -35,7 +35,7 @@ describe('IgxHierarchicalGrid Virtualization #hGrid', () => {
3535

3636
beforeEach(() => {
3737
TestBed.configureTestingModule({
38-
providers: [{ provide: SCROLL_THROTTLE_TIME, useValue: 1 }]
38+
providers: [{ provide: SCROLL_THROTTLE_TIME_MULTIPLIER, useValue: 0 }]
3939
});
4040
fixture = TestBed.createComponent(IgxHierarchicalGridTestBaseComponent);
4141
fixture.detectChanges();

0 commit comments

Comments
 (0)