Skip to content

Commit bf953e9

Browse files
authored
perf(table): Do column name string interpolation once per column instead of once per cell (#19801)
* perf(table): Use only one column classname and do string interpolation once per column * missed a couple * lint * update api * For now, just share the css classname across cells, but keep same behavior. * lint * update api
1 parent e2bc083 commit bf953e9

File tree

5 files changed

+57
-49
lines changed

5 files changed

+57
-49
lines changed

src/cdk/table/cell.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ export class CdkColumnDef extends _CdkColumnDefBase implements CanStick {
7979
if (name) {
8080
this._name = name;
8181
this.cssClassFriendlyName = name.replace(/[^a-z0-9_-]/ig, '-');
82+
this._updateColumnCssClassName();
8283
}
8384
}
8485
_name: string;
@@ -115,19 +116,40 @@ export class CdkColumnDef extends _CdkColumnDefBase implements CanStick {
115116
*/
116117
cssClassFriendlyName: string;
117118

119+
/**
120+
* Class name for cells in this column.
121+
* @docs-private
122+
*/
123+
_columnCssClassName: string[];
124+
118125
constructor(@Inject(CDK_TABLE) @Optional() public _table?: any) {
119126
super();
120127
}
121128

129+
/**
130+
* Overridable method that sets the css classes that will be added to every cell in this
131+
* column.
132+
* In the future, columnCssClassName will change from type string[] to string and this
133+
* will set a single string value.
134+
* @docs-private
135+
*/
136+
protected _updateColumnCssClassName() {
137+
this._columnCssClassName = [`cdk-column-${this.cssClassFriendlyName}`];
138+
}
139+
122140
static ngAcceptInputType_sticky: BooleanInput;
123141
static ngAcceptInputType_stickyEnd: BooleanInput;
124142
}
125143

126144
/** Base class for the cells. Adds a CSS classname that identifies the column it renders in. */
127145
export class BaseCdkCell {
128146
constructor(columnDef: CdkColumnDef, elementRef: ElementRef) {
129-
const columnClassName = `cdk-column-${columnDef.cssClassFriendlyName}`;
130-
elementRef.nativeElement.classList.add(columnClassName);
147+
// If IE 11 is dropped before we switch to setting a single class name, change to multi param
148+
// with destructuring.
149+
const classList = elementRef.nativeElement.classList;
150+
for (const className of columnDef._columnCssClassName) {
151+
classList.add(className);
152+
}
131153
}
132154
}
133155

src/material-experimental/mdc-table/cell.ts

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import {BooleanInput} from '@angular/cdk/coercion';
10-
import {Directive, ElementRef, Input} from '@angular/core';
10+
import {Directive, Input} from '@angular/core';
1111
import {
1212
CdkCell,
1313
CdkCellDef,
@@ -62,6 +62,17 @@ export class MatColumnDef extends CdkColumnDef {
6262
/** Unique name for this column. */
6363
@Input('matColumnDef') name: string;
6464

65+
/**
66+
* Add "mat-column-" prefix in addition to "cdk-column-" prefix.
67+
* In the future, this will only add "mat-column-" and columnCssClassName
68+
* will change from type string[] to string.
69+
* @docs-private
70+
*/
71+
protected _updateColumnCssClassName() {
72+
super._updateColumnCssClassName();
73+
this._columnCssClassName!.push(`mat-column-${this.cssClassFriendlyName}`);
74+
}
75+
6576
static ngAcceptInputType_sticky: BooleanInput;
6677
}
6778

@@ -73,13 +84,7 @@ export class MatColumnDef extends CdkColumnDef {
7384
'role': 'columnheader',
7485
},
7586
})
76-
export class MatHeaderCell extends CdkHeaderCell {
77-
constructor(columnDef: CdkColumnDef,
78-
elementRef: ElementRef<HTMLElement>) {
79-
super(columnDef, elementRef);
80-
elementRef.nativeElement.classList.add(`mat-column-${columnDef.cssClassFriendlyName}`);
81-
}
82-
}
87+
export class MatHeaderCell extends CdkHeaderCell {}
8388

8489
/** Footer cell template container that adds the right classes and role. */
8590
@Directive({
@@ -89,13 +94,7 @@ export class MatHeaderCell extends CdkHeaderCell {
8994
'role': 'gridcell',
9095
},
9196
})
92-
export class MatFooterCell extends CdkFooterCell {
93-
constructor(columnDef: CdkColumnDef,
94-
elementRef: ElementRef) {
95-
super(columnDef, elementRef);
96-
elementRef.nativeElement.classList.add(`mat-column-${columnDef.cssClassFriendlyName}`);
97-
}
98-
}
97+
export class MatFooterCell extends CdkFooterCell {}
9998

10099
/** Cell template container that adds the right classes and role. */
101100
@Directive({
@@ -105,10 +104,4 @@ export class MatFooterCell extends CdkFooterCell {
105104
'role': 'gridcell',
106105
},
107106
})
108-
export class MatCell extends CdkCell {
109-
constructor(columnDef: CdkColumnDef,
110-
elementRef: ElementRef<HTMLElement>) {
111-
super(columnDef, elementRef);
112-
elementRef.nativeElement.classList.add(`mat-column-${columnDef.cssClassFriendlyName}`);
113-
}
114-
}
107+
export class MatCell extends CdkCell {}

src/material/table/cell.ts

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import {BooleanInput} from '@angular/cdk/coercion';
10-
import {Directive, ElementRef, Input} from '@angular/core';
10+
import {Directive, Input} from '@angular/core';
1111
import {
1212
CdkCell,
1313
CdkCellDef,
@@ -62,6 +62,17 @@ export class MatColumnDef extends CdkColumnDef {
6262
/** Unique name for this column. */
6363
@Input('matColumnDef') name: string;
6464

65+
/**
66+
* Add "mat-column-" prefix in addition to "cdk-column-" prefix.
67+
* In the future, this will only add "mat-column-" and columnCssClassName
68+
* will change from type string[] to string.
69+
* @docs-private
70+
*/
71+
protected _updateColumnCssClassName() {
72+
super._updateColumnCssClassName();
73+
this._columnCssClassName!.push(`mat-column-${this.cssClassFriendlyName}`);
74+
}
75+
6576
static ngAcceptInputType_sticky: BooleanInput;
6677
}
6778

@@ -73,13 +84,7 @@ export class MatColumnDef extends CdkColumnDef {
7384
'role': 'columnheader',
7485
},
7586
})
76-
export class MatHeaderCell extends CdkHeaderCell {
77-
constructor(columnDef: CdkColumnDef,
78-
elementRef: ElementRef<HTMLElement>) {
79-
super(columnDef, elementRef);
80-
elementRef.nativeElement.classList.add(`mat-column-${columnDef.cssClassFriendlyName}`);
81-
}
82-
}
87+
export class MatHeaderCell extends CdkHeaderCell {}
8388

8489
/** Footer cell template container that adds the right classes and role. */
8590
@Directive({
@@ -89,13 +94,7 @@ export class MatHeaderCell extends CdkHeaderCell {
8994
'role': 'gridcell',
9095
},
9196
})
92-
export class MatFooterCell extends CdkFooterCell {
93-
constructor(columnDef: CdkColumnDef,
94-
elementRef: ElementRef) {
95-
super(columnDef, elementRef);
96-
elementRef.nativeElement.classList.add(`mat-column-${columnDef.cssClassFriendlyName}`);
97-
}
98-
}
97+
export class MatFooterCell extends CdkFooterCell {}
9998

10099
/** Cell template container that adds the right classes and role. */
101100
@Directive({
@@ -105,10 +104,4 @@ export class MatFooterCell extends CdkFooterCell {
105104
'role': 'gridcell',
106105
},
107106
})
108-
export class MatCell extends CdkCell {
109-
constructor(columnDef: CdkColumnDef,
110-
elementRef: ElementRef<HTMLElement>) {
111-
super(columnDef, elementRef);
112-
elementRef.nativeElement.classList.add(`mat-column-${columnDef.cssClassFriendlyName}`);
113-
}
114-
}
107+
export class MatCell extends CdkCell {}

tools/public_api_guard/cdk/table.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ export interface CdkCellOutletRowContext<T> {
8989
}
9090

9191
export declare class CdkColumnDef extends _CdkColumnDefBase implements CanStick {
92+
_columnCssClassName: string[];
9293
_name: string;
9394
_stickyEnd: boolean;
9495
_table?: any;
@@ -101,6 +102,7 @@ export declare class CdkColumnDef extends _CdkColumnDefBase implements CanStick
101102
get stickyEnd(): boolean;
102103
set stickyEnd(v: boolean);
103104
constructor(_table?: any);
105+
protected _updateColumnCssClassName(): void;
104106
static ngAcceptInputType_sticky: BooleanInput;
105107
static ngAcceptInputType_stickyEnd: BooleanInput;
106108
static ɵdir: i0.ɵɵDirectiveDefWithMeta<CdkColumnDef, "[cdkColumnDef]", never, { "sticky": "sticky"; "name": "cdkColumnDef"; "stickyEnd": "stickyEnd"; }, {}, ["cell", "headerCell", "footerCell"]>;

tools/public_api_guard/material/table.d.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
export declare class MatCell extends CdkCell {
2-
constructor(columnDef: CdkColumnDef, elementRef: ElementRef<HTMLElement>);
32
static ɵdir: i0.ɵɵDirectiveDefWithMeta<MatCell, "mat-cell, td[mat-cell]", never, {}, {}, never>;
43
static ɵfac: i0.ɵɵFactoryDef<MatCell, never>;
54
}
@@ -11,13 +10,13 @@ export declare class MatCellDef extends CdkCellDef {
1110

1211
export declare class MatColumnDef extends CdkColumnDef {
1312
name: string;
13+
protected _updateColumnCssClassName(): void;
1414
static ngAcceptInputType_sticky: BooleanInput;
1515
static ɵdir: i0.ɵɵDirectiveDefWithMeta<MatColumnDef, "[matColumnDef]", never, { "sticky": "sticky"; "name": "matColumnDef"; }, {}, never>;
1616
static ɵfac: i0.ɵɵFactoryDef<MatColumnDef, never>;
1717
}
1818

1919
export declare class MatFooterCell extends CdkFooterCell {
20-
constructor(columnDef: CdkColumnDef, elementRef: ElementRef);
2120
static ɵdir: i0.ɵɵDirectiveDefWithMeta<MatFooterCell, "mat-footer-cell, td[mat-footer-cell]", never, {}, {}, never>;
2221
static ɵfac: i0.ɵɵFactoryDef<MatFooterCell, never>;
2322
}
@@ -39,7 +38,6 @@ export declare class MatFooterRowDef extends CdkFooterRowDef {
3938
}
4039

4140
export declare class MatHeaderCell extends CdkHeaderCell {
42-
constructor(columnDef: CdkColumnDef, elementRef: ElementRef<HTMLElement>);
4341
static ɵdir: i0.ɵɵDirectiveDefWithMeta<MatHeaderCell, "mat-header-cell, th[mat-header-cell]", never, {}, {}, never>;
4442
static ɵfac: i0.ɵɵFactoryDef<MatHeaderCell, never>;
4543
}

0 commit comments

Comments
 (0)