From 1ebc7fa6e4eadb5acdcc1a3372a750b8531b95e5 Mon Sep 17 00:00:00 2001 From: Karl Seamon Date: Tue, 23 Jun 2020 22:29:16 -0400 Subject: [PATCH 1/2] perf(table): Reduce the number of times sticky column positioning is computed. --- src/cdk/table/table.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/cdk/table/table.ts b/src/cdk/table/table.ts index 1dabd49ad286..1a6438a2daae 100644 --- a/src/cdk/table/table.ts +++ b/src/cdk/table/table.ts @@ -376,6 +376,7 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes // this setter will be invoked before the row outlet has been defined hence the null check. if (this._rowOutlet && this._rowOutlet.viewContainer.length) { this._forceRenderDataRows(); + this.updateStickyColumnStyles(); } } _multiTemplateDataRows: boolean = false; @@ -459,24 +460,28 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes } // Render updates if the list of columns have been changed for the header, row, or footer defs. - this._renderUpdatedColumns(); + let forced = this._renderUpdatedColumns(); // If the header row definition has been changed, trigger a render to the header row. if (this._headerRowDefChanged) { this._forceRenderHeaderRows(); this._headerRowDefChanged = false; + forced = true; } // If the footer row definition has been changed, trigger a render to the footer row. if (this._footerRowDefChanged) { this._forceRenderFooterRows(); this._footerRowDefChanged = false; + forced = true; } // If there is a data source and row definitions, connect to the data source unless a // connection has already been made. if (this.dataSource && this._rowDefs.length > 0 && !this._renderChangeSubscription) { this._observeRenderChanges(); + } else if (forced) { + this.updateStickyColumnStyles(); } this._checkStickyStates(); @@ -785,20 +790,26 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes */ private _renderUpdatedColumns() { const columnsDiffReducer = (acc: boolean, def: BaseRowDef) => acc || !!def.getColumnsDiff(); + let forced = false; // Force re-render data rows if the list of column definitions have changed. if (this._rowDefs.reduce(columnsDiffReducer, false)) { this._forceRenderDataRows(); + forced = true; } // Force re-render header/footer rows if the list of column definitions have changed.. if (this._headerRowDefs.reduce(columnsDiffReducer, false)) { this._forceRenderHeaderRows(); + forced = true; } if (this._footerRowDefs.reduce(columnsDiffReducer, false)) { this._forceRenderFooterRows(); + forced = true; } + + return forced; } /** @@ -868,7 +879,6 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes this._headerRowDefs.forEach((def, i) => this._renderRow(this._headerRowOutlet, def, i)); this.updateStickyHeaderRowStyles(); - this.updateStickyColumnStyles(); } /** * Clears any existing content in the footer row outlet and creates a new embedded view @@ -882,7 +892,6 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes this._footerRowDefs.forEach((def, i) => this._renderRow(this._footerRowOutlet, def, i)); this.updateStickyFooterRowStyles(); - this.updateStickyColumnStyles(); } /** Adds the sticky column styles for the rows according to the columns' stick states. */ @@ -1042,7 +1051,6 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes this._dataDiffer.diff([]); this._rowOutlet.viewContainer.clear(); this.renderRows(); - this.updateStickyColumnStyles(); } /** From b50dbb9a2c8d8dc7d39baf5144e7fca6713a45aa Mon Sep 17 00:00:00 2001 From: Karl Seamon Date: Wed, 24 Jun 2020 11:52:55 -0400 Subject: [PATCH 2/2] Applied suggested readability improvements. --- src/cdk/table/table.ts | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/cdk/table/table.ts b/src/cdk/table/table.ts index 1a6438a2daae..9a9e4490362f 100644 --- a/src/cdk/table/table.ts +++ b/src/cdk/table/table.ts @@ -460,27 +460,29 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes } // Render updates if the list of columns have been changed for the header, row, or footer defs. - let forced = this._renderUpdatedColumns(); + const columnsChanged = this._renderUpdatedColumns(); + const stickyColumnStyleUpdateNeeded = + columnsChanged || this._headerRowDefChanged || this._footerRowDefChanged; // If the header row definition has been changed, trigger a render to the header row. if (this._headerRowDefChanged) { this._forceRenderHeaderRows(); this._headerRowDefChanged = false; - forced = true; } // If the footer row definition has been changed, trigger a render to the footer row. if (this._footerRowDefChanged) { this._forceRenderFooterRows(); this._footerRowDefChanged = false; - forced = true; } // If there is a data source and row definitions, connect to the data source unless a // connection has already been made. if (this.dataSource && this._rowDefs.length > 0 && !this._renderChangeSubscription) { this._observeRenderChanges(); - } else if (forced) { + } else if (stickyColumnStyleUpdateNeeded) { + // In the above case, _observeRenderChanges will result in updateStickyColumnStyles being + // called when it row data arrives. Otherwise, we need to call it proactively. this.updateStickyColumnStyles(); } @@ -788,28 +790,27 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes * whether the sticky states have changed for the header or footer. If there is a diff, then * re-render that section. */ - private _renderUpdatedColumns() { + private _renderUpdatedColumns(): boolean { const columnsDiffReducer = (acc: boolean, def: BaseRowDef) => acc || !!def.getColumnsDiff(); - let forced = false; // Force re-render data rows if the list of column definitions have changed. - if (this._rowDefs.reduce(columnsDiffReducer, false)) { + const dataColumnsChanged = this._rowDefs.reduce(columnsDiffReducer, false); + if (dataColumnsChanged) { this._forceRenderDataRows(); - forced = true; } - // Force re-render header/footer rows if the list of column definitions have changed.. - if (this._headerRowDefs.reduce(columnsDiffReducer, false)) { + // Force re-render header/footer rows if the list of column definitions have changed. + const headerColumnsChanged = this._headerRowDefs.reduce(columnsDiffReducer, false); + if (headerColumnsChanged) { this._forceRenderHeaderRows(); - forced = true; } - if (this._footerRowDefs.reduce(columnsDiffReducer, false)) { + const footerColumnsChanged = this._footerRowDefs.reduce(columnsDiffReducer, false); + if (footerColumnsChanged) { this._forceRenderFooterRows(); - forced = true; } - return forced; + return dataColumnsChanged || headerColumnsChanged || footerColumnsChanged; } /**