Skip to content

Commit feefd22

Browse files
committed
fix: Improve grid performance by preventing unnecessary change detection
Signed-off-by: Akshat Patel <[email protected]>
1 parent 3336ecb commit feefd22

File tree

1 file changed

+61
-66
lines changed

1 file changed

+61
-66
lines changed

src/grid/grid.directive.ts

Lines changed: 61 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ import {
55
HostBinding,
66
Input,
77
OnChanges,
8-
OnInit,
9-
QueryList
8+
QueryList,
9+
AfterViewInit
1010
} from "@angular/core";
1111

1212
@Directive({
1313
selector: "[ibmCol]"
1414
})
15-
export class ColumnDirective implements OnInit, OnChanges {
15+
export class ColumnDirective implements AfterViewInit, OnChanges {
1616
@HostBinding("class")
1717
get columnClasses(): string {
1818
return this._columnClasses.join(" ");
@@ -59,7 +59,7 @@ export class ColumnDirective implements OnInit, OnChanges {
5959

6060
protected _columnClasses: string[] = [];
6161

62-
ngOnInit() {
62+
ngAfterViewInit() {
6363
this.updateColumnClasses();
6464
}
6565

@@ -68,76 +68,72 @@ export class ColumnDirective implements OnInit, OnChanges {
6868
}
6969

7070
private updateColumnClasses() {
71-
// Using setTimeout to simulate a tick to capture an update isCss property
72-
// otherwise, isCss will always be false
73-
setTimeout(() => {
74-
try {
75-
this._columnClasses = [];
76-
const columnKeys = Object.keys(this.columnNumbers);
77-
78-
// Assign classes based on the type of grid used.
79-
if (this.isCss) {
80-
// Default css grid class
81-
this._columnClasses.push("cds--css-grid-column");
82-
if (this.columnHang) {
83-
this._columnClasses.push("cds--grid-column-hang");
84-
}
71+
try {
72+
this._columnClasses = [];
73+
const columnKeys = Object.keys(this.columnNumbers);
74+
75+
// Assign classes based on the type of grid used.
76+
if (this.isCss) {
77+
// Default css grid class
78+
this._columnClasses.push("cds--css-grid-column");
79+
if (this.columnHang) {
80+
this._columnClasses.push("cds--grid-column-hang");
81+
}
8582

86-
columnKeys.forEach(key => {
83+
columnKeys.forEach(key => {
84+
/**
85+
* Passing in `auto` to a breakpoint as such: {'md': 'auto'}
86+
* will assign the element which will automatically determine the width of the column
87+
* for the breakpoint passed
88+
*/
89+
if (this.columnNumbers[key] === "auto") {
90+
this._columnClasses.push(`cds--${key}:col-span-auto`);
91+
} else if (typeof this.columnNumbers[key] === "object") {
8792
/**
88-
* Passing in `auto` to a breakpoint as such: {'md': 'auto'}
89-
* will assign the element which will automatically determine the width of the column
90-
* for the breakpoint passed
93+
* In css grid, objects can be passed to the keys in the following format:
94+
* {'md': {'start': 3}}
95+
*
96+
* These objects are used to position the column
9197
*/
92-
if (this.columnNumbers[key] === "auto") {
93-
this._columnClasses.push(`cds--${key}:col-span-auto`);
94-
} else if (typeof this.columnNumbers[key] === "object") {
95-
/**
96-
* In css grid, objects can be passed to the keys in the following format:
97-
* {'md': {'start': 3}}
98-
*
99-
* These objects are used to position the column
100-
*/
101-
if (this.columnNumbers[key]["start"]) {
102-
// col-start is simular equivalent of flex offset
103-
this._columnClasses.push(`cds--${key}:col-start-${this.columnNumbers[key]}`);
104-
} else if (this.columnNumbers[key]["end"]) {
105-
this._columnClasses.push(`cds--${key}:col-end-${this.columnNumbers[key]}`);
106-
}
107-
} else {
108-
this._columnClasses.push(`cds--${key}:col-span-${this.columnNumbers[key]}`);
98+
if (this.columnNumbers[key]["start"]) {
99+
// col-start is simular equivalent of flex offset
100+
this._columnClasses.push(`cds--${key}:col-start-${this.columnNumbers[key]}`);
101+
} else if (this.columnNumbers[key]["end"]) {
102+
this._columnClasses.push(`cds--${key}:col-end-${this.columnNumbers[key]}`);
109103
}
110-
});
111-
} else {
112-
// Set column classes for flex grid
113-
if (columnKeys.length <= 0) {
114-
this._columnClasses.push("cds--col");
104+
} else {
105+
this._columnClasses.push(`cds--${key}:col-span-${this.columnNumbers[key]}`);
115106
}
107+
});
108+
} else {
109+
// Set column classes for flex grid
110+
if (columnKeys.length <= 0) {
111+
this._columnClasses.push("cds--col");
112+
}
116113

117-
columnKeys.forEach(key => {
118-
if (this.columnNumbers[key] === "nobreak") {
119-
this._columnClasses.push(`cds--col-${key}`);
120-
} else {
121-
this._columnClasses.push(`cds--col-${key}-${this.columnNumbers[key]}`);
122-
}
123-
});
114+
columnKeys.forEach(key => {
115+
if (this.columnNumbers[key] === "nobreak") {
116+
this._columnClasses.push(`cds--col-${key}`);
117+
} else {
118+
this._columnClasses.push(`cds--col-${key}-${this.columnNumbers[key]}`);
119+
}
120+
});
124121

125-
Object.keys(this.offsets).forEach(key => {
126-
this._columnClasses.push(`cds--offset-${key}-${this.offsets[key]}`);
127-
});
128-
}
129-
} catch (err) {
130-
console.error(`Malformed \`offsets\` or \`columnNumbers\`: ${err}`);
122+
Object.keys(this.offsets).forEach(key => {
123+
this._columnClasses.push(`cds--offset-${key}-${this.offsets[key]}`);
124+
});
131125
}
126+
} catch (err) {
127+
console.error(`Malformed \`offsets\` or \`columnNumbers\`: ${err}`);
128+
}
132129

133-
/**
134-
* Append the classes passed so they aren't overriden when we set the column classes
135-
* from host binding
136-
*/
137-
if (this.class) {
138-
this._columnClasses.push(this.class);
139-
}
140-
});
130+
/**
131+
* Append the classes passed so they aren't overriden when we set the column classes
132+
* from host binding
133+
*/
134+
if (this.class) {
135+
this._columnClasses.push(this.class);
136+
}
141137
}
142138
}
143139

@@ -157,7 +153,6 @@ export class RowDirective {
157153
selector: "[ibmGrid]"
158154
})
159155
export class GridDirective implements AfterContentInit {
160-
161156
@Input() condensed = false;
162157
@Input() narrow = false;
163158
@Input() fullWidth = false;

0 commit comments

Comments
 (0)