diff --git a/projects/igniteui-angular-performance/src/app/app.component.html b/projects/igniteui-angular-performance/src/app/app.component.html
index 8ca8b694e34..277913f006f 100644
--- a/projects/igniteui-angular-performance/src/app/app.component.html
+++ b/projects/igniteui-angular-performance/src/app/app.component.html
@@ -5,6 +5,10 @@
{{ route.title }}
}
+
+
diff --git a/projects/igniteui-angular-performance/src/app/app.component.ts b/projects/igniteui-angular-performance/src/app/app.component.ts
index 109d49db6d3..d25206dadf1 100644
--- a/projects/igniteui-angular-performance/src/app/app.component.ts
+++ b/projects/igniteui-angular-performance/src/app/app.component.ts
@@ -1,4 +1,4 @@
-import { Component } from '@angular/core';
+import { Component, ViewChild } from '@angular/core';
import { RouterLink, RouterOutlet, Routes } from '@angular/router';
import { IgxButtonDirective } from 'igniteui-angular';
import { routes } from './app.routes';
@@ -11,4 +11,24 @@ import { routes } from './app.routes';
})
export class AppComponent {
protected routes: Routes = routes;
+
+ @ViewChild(RouterOutlet) outlet!: RouterOutlet;
+
+ public async OnPerfTest() {
+ const longTask = [];
+ const observer = new PerformanceObserver((list) => {
+ longTask.push(...list.getEntries());
+ });
+ observer.observe({ entryTypes: ['longtask'] });
+ const grid = (this.outlet.component as any).grid || (this.outlet.component as any).pivotGrid;
+ for (let i = 0; i < 100; i++) {
+ grid.navigateTo(i * 50);
+ await new Promise(r => setTimeout(r, 50));
+ }
+ const sum = longTask.reduce((acc, task) => acc + task.duration, 0);
+ const avgTime = sum / longTask.length;
+ console.log('Long Tasks:'+ longTask.length + ", ", 'Average Long Task Time:', avgTime);
+ observer.disconnect();
+
+ }
}
diff --git a/projects/igniteui-angular-performance/src/app/grid/grid.component.html b/projects/igniteui-angular-performance/src/app/grid/grid.component.html
index 9cad429ffa8..dbc647f41e7 100644
--- a/projects/igniteui-angular-performance/src/app/grid/grid.component.html
+++ b/projects/igniteui-angular-performance/src/app/grid/grid.component.html
@@ -1,8 +1,9 @@
diff --git a/projects/igniteui-angular-performance/src/app/pivot-grid/pivot-grid.component.ts b/projects/igniteui-angular-performance/src/app/pivot-grid/pivot-grid.component.ts
index e6d9f8593af..9070c7202a8 100644
--- a/projects/igniteui-angular-performance/src/app/pivot-grid/pivot-grid.component.ts
+++ b/projects/igniteui-angular-performance/src/app/pivot-grid/pivot-grid.component.ts
@@ -182,9 +182,9 @@ export class PivotGridComponent {
sortDirection: SortingDirection.None
},
{
- fullDate: false,
+ fullDate: true,
quarters: true,
- months: false,
+ months: true,
}),
],
values: [
diff --git a/projects/igniteui-angular-performance/src/styles.scss b/projects/igniteui-angular-performance/src/styles.scss
index f6fc0768f45..513b45895b7 100644
--- a/projects/igniteui-angular-performance/src/styles.scss
+++ b/projects/igniteui-angular-performance/src/styles.scss
@@ -1,4 +1,4 @@
-@use '../../igniteui-angular/src/lib/core/styles/themes' as *;
+@use '../../igniteui-angular/core/src/core/styles/themes' as *;
@import url('https://fonts.googleapis.com/icon?family=Material+Icons');
@include core();
@include typography(
diff --git a/projects/igniteui-angular/directives/src/directives/for-of/base.helper.component.ts b/projects/igniteui-angular/directives/src/directives/for-of/base.helper.component.ts
index 7df0cac709d..f3afbf0b949 100644
--- a/projects/igniteui-angular/directives/src/directives/for-of/base.helper.component.ts
+++ b/projects/igniteui-angular/directives/src/directives/for-of/base.helper.component.ts
@@ -43,11 +43,6 @@ export class VirtualHelperBaseDirective implements OnDestroy, AfterViewInit {
this._scrollNativeSize = this.calculateScrollNativeSize();
}
- @HostListener('scroll', ['$event'])
- public onScroll(event) {
- this.scrollAmount = event.target.scrollTop || event.target.scrollLeft;
- }
-
public ngAfterViewInit() {
this._afterViewInit = true;
diff --git a/projects/igniteui-angular/directives/src/directives/for-of/for_of.directive.ts b/projects/igniteui-angular/directives/src/directives/for-of/for_of.directive.ts
index 7d035ae2888..56c6f77d9f8 100644
--- a/projects/igniteui-angular/directives/src/directives/for-of/for_of.directive.ts
+++ b/projects/igniteui-angular/directives/src/directives/for-of/for_of.directive.ts
@@ -1,5 +1,5 @@
import { NgForOfContext } from '@angular/common';
-import { ChangeDetectorRef, ComponentRef, Directive, DoCheck, EmbeddedViewRef, EventEmitter, Input, IterableChanges, IterableDiffer, IterableDiffers, NgZone, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, TemplateRef, TrackByFunction, ViewContainerRef, AfterViewInit, booleanAttribute, DOCUMENT, inject } from '@angular/core';
+import { ChangeDetectorRef, ComponentRef, Directive, EmbeddedViewRef, EventEmitter, Input, IterableChanges, IterableDiffer, IterableDiffers, NgZone, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, TemplateRef, TrackByFunction, ViewContainerRef, AfterViewInit, booleanAttribute, DOCUMENT, inject, afterNextRender, runInInjectionContext, EnvironmentInjector } from '@angular/core';
import { DisplayContainerComponent } from './display.container';
import { HVirtualHelperComponent } from './horizontal.virtual.helper.component';
@@ -84,16 +84,17 @@ export abstract class IgxForOfToken {
],
standalone: true
})
-export class IgxForOfDirective extends IgxForOfToken implements OnInit, OnChanges, DoCheck, OnDestroy, AfterViewInit {
+export class IgxForOfDirective extends IgxForOfToken implements OnInit, OnChanges, OnDestroy, AfterViewInit {
private _viewContainer = inject(ViewContainerRef);
protected _template = inject>>(TemplateRef);
protected _differs = inject(IterableDiffers);
+ protected _injector = inject(EnvironmentInjector);
public cdr = inject(ChangeDetectorRef);
protected _zone = inject(NgZone);
protected syncScrollService = inject(IgxForOfScrollSyncService);
protected platformUtil = inject(PlatformUtil);
protected document = inject(DOCUMENT);
-
+ private _igxForOf: U & T[] | null = null;
/**
* Sets the data to be rendered.
@@ -102,7 +103,14 @@ export class IgxForOfDirective extends IgxForOfToken extends IgxForOfToken extends IgxForOfToken extends IgxForOfToken {
+ afterNextRender({
+ write: () => {
+ this.dc.instance._viewContainer.element.nativeElement.style.transform = `translateY(${-scrollOffset}px)`;
+ }
+ });
+ });
}
const maxRealScrollTop = this.scrollComponent.nativeElement.scrollHeight - containerSize;
@@ -894,7 +908,13 @@ export class IgxForOfDirective extends IgxForOfToken {
+ afterNextRender({
+ write: () => {
+ this.dc.instance._viewContainer.element.nativeElement.style.transform = `translateY(${-scrollOffset}px)`;
+ }
+ });
+ });
this._zone.onStable.pipe(first()).subscribe(this.recalcUpdateSizes.bind(this));
@@ -1446,8 +1466,10 @@ export class IgxForOfDirective extends IgxForOfToken extends IgxForOfToken extends IgxForOfContext
selector: '[igxGridFor][igxGridForOf]',
standalone: true
})
-export class IgxGridForOfDirective extends IgxForOfDirective implements OnInit, OnChanges, DoCheck {
+export class IgxGridForOfDirective extends IgxForOfDirective implements OnInit, OnChanges {
protected syncService = inject(IgxForOfSyncService);
@Input()
@@ -1626,7 +1648,7 @@ export class IgxGridForOfDirective extends IgxForOfDirec
this.syncService.setMaster(this, true);
}
- public override ngDoCheck() {
+ public override resolveDataDiff() {
if (this._differ) {
const changes = this._differ.diff(this.igxForOf);
if (changes) {
@@ -1660,19 +1682,24 @@ export class IgxGridForOfDirective extends IgxForOfDirec
}
public override onScroll(event) {
- if (!parseInt(this.scrollComponent.nativeElement.style.height, 10)) {
+ this.scrollComponent.scrollAmount = event.target.scrollTop;
+ if (!this.scrollComponent.size) {
return;
}
if (!this._bScrollInternal) {
- this._calcVirtualScrollPosition(event.target.scrollTop);
+ this._calcVirtualScrollPosition(this.scrollComponent.scrollAmount);
} else {
this._bScrollInternal = false;
}
const scrollOffset = this.fixedUpdateAllElements(this._virtScrollPosition);
+ runInInjectionContext(this._injector, () => {
+ afterNextRender({
+ write: () => {
+ this.dc.instance._viewContainer.element.nativeElement.style.transform = `translateY(${-scrollOffset}px)`;
+ }
+ });
+ });
- this.dc.instance._viewContainer.element.nativeElement.style.top = -(scrollOffset) + 'px';
-
- this._zone.onStable.pipe(first()).subscribe(this.recalcUpdateSizes.bind(this));
this.cdr.markForCheck();
}
diff --git a/projects/igniteui-angular/grids/grid/src/grid-base.directive.ts b/projects/igniteui-angular/grids/grid/src/grid-base.directive.ts
index cb01b0beff7..cdf841a1388 100644
--- a/projects/igniteui-angular/grids/grid/src/grid-base.directive.ts
+++ b/projects/igniteui-angular/grids/grid/src/grid-base.directive.ts
@@ -2998,6 +2998,9 @@ export abstract class IgxGridBaseDirective implements GridType,
/** @hidden @internal */
public resizeNotify = new Subject();
+ /** @hidden @internal */
+ public scrollNotify = new Subject();
+
/** @hidden @internal */
public rowAddedNotifier = new Subject();
@@ -3709,6 +3712,15 @@ export abstract class IgxGridBaseDirective implements GridType,
this.subscribeToTransactions();
+ this.scrollNotify.pipe(
+ filter(() => !this._init),
+ throttleTime(40, animationFrameScheduler, { leading: false, trailing: true }),
+ destructor
+ )
+ .subscribe((event) => {
+ this.verticalScrollHandler(event);
+ });
+
this.resizeNotify.pipe(
filter(() => !this._init),
throttleTime(40, animationFrameScheduler, { leading: true, trailing: true }),
@@ -4153,7 +4165,7 @@ export abstract class IgxGridBaseDirective implements GridType,
this.zone.runOutsideAngular(() => {
this.verticalScrollHandler = this.verticalScrollHandler.bind(this);
this.horizontalScrollHandler = this.horizontalScrollHandler.bind(this);
- this.verticalScrollContainer.getScroll().addEventListener('scroll', this.verticalScrollHandler);
+ this.verticalScrollContainer.getScroll().addEventListener('scroll', (event) => this.scrollNotify.next(event));
this.headerContainer?.getScroll().addEventListener('scroll', this.horizontalScrollHandler);
if (this.hasColumnsToAutosize) {
this.headerContainer?.dataChanged.pipe(takeUntil(this.destroy$)).subscribe(() => {
@@ -7721,13 +7733,11 @@ export abstract class IgxGridBaseDirective implements GridType,
this.verticalScrollContainer.onScroll(event);
this.disableTransitions = true;
- this.zone.run(() => {
- this.zone.onStable.pipe(first()).subscribe(() => {
- this.verticalScrollContainer.chunkLoad.emit(this.verticalScrollContainer.state);
- if (this.rowEditable) {
- this.changeRowEditingOverlayStateOnScroll(this.crudService.rowInEditMode);
- }
- });
+ this.zone.onStable.pipe(first()).subscribe(() => {
+ this.verticalScrollContainer.chunkLoad.emit(this.verticalScrollContainer.state);
+ if (this.rowEditable) {
+ this.changeRowEditingOverlayStateOnScroll(this.crudService.rowInEditMode);
+ }
});
this.disableTransitions = false;