With default CSS encapsulation Angular needs to create attributes in the DOM to scope CSS selectors (ex.: <div _ngcontent-c0>. It turns out that sometimes those attributes are added even if not needed - this happens when a component references an empty styles file (via stylesUrl). Normally it wouldn't be a big deal but CLI scaffolding generates empty style files and triggers unnecessary DOM attributes creation.
Compiler should understand that there are no meaningful CSS styles referenced and skip CSS-scoping attributes creation. It is should be a trivial fix and can speed up views creation by more than 11% in certain scenarios. Given a simple component like so:
import { Component } from '@angular/core';
const items = [
{id: 'foo0', name: 'Foo0'},
{id: 'foo1', name: 'Foo1'},
{id: 'foo2', name: 'Foo2'},
{id: 'foo3', name: 'Foo3'},
...
{id: 'foo99', name: 'Foo99'}
];
@Component({
selector: 'app-root',
template: `
<button (click)="show()" id="show">Show</button>
<button (click)="this.items = []" id="hide">Hide</button>
<div *ngFor="let item of items">
<span>{{item.id}}</span>
<span>{{item.name}}</span>
</div>
`,
styleUrls: ['./app.component.css']
})
export class AppComponent {
items = [];
show() {
this.items = items;
}
}
and the following benchpress test:
runner.sample({
id: 'ngFor-no-styles',
execute: function() {
$('#show').click();
$('#hide').click();
}
}).then(done, done.fail);
I'm seeing ~11% improvement on my machine. I guess most of it can be explained by less DOM manipulation (no need to create attributes)
Here the detailed benchpress results.
Before (with empty styles)
forcedGcAmount | forcedGcTime | gcAmount | gcTime | majorGcTime | pureScriptTime | renderTime | scriptTime
------------------ | ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | ------------------
1279.56 | 8.29 | 483.42 | 1.43 | 0.00 | 30.69 | 7.51 | 30.69
1968.33 | 8.01 | 0.00 | 0.00 | 0.00 | 13.13 | 6.13 | 13.13
3198.80 | 7.80 | 0.00 | 0.00 | 0.00 | 10.48 | 5.38 | 10.48
1946.09 | 6.88 | 0.00 | 0.00 | 0.00 | 6.60 | 5.60 | 6.60
2052.39 | 7.48 | 0.00 | 0.00 | 0.00 | 9.04 | 5.27 | 9.04
1976.34 | 7.47 | 0.00 | 0.00 | 0.00 | 9.05 | 6.01 | 9.05
1933.99 | 6.96 | 0.00 | 0.00 | 0.00 | 5.94 | 5.35 | 5.94
1961.12 | 7.55 | 0.00 | 0.00 | 0.00 | 7.48 | 4.97 | 7.48
1925.58 | 7.60 | 0.00 | 0.00 | 0.00 | 6.79 | 5.37 | 6.79
2016.03 | 7.57 | 0.00 | 0.00 | 0.00 | 8.65 | 5.41 | 8.65
1972.84 | 7.61 | 0.00 | 0.00 | 0.00 | 7.74 | 4.94 | 7.74
1928.36 | 7.07 | 0.00 | 0.00 | 0.00 | 5.38 | 5.89 | 5.38
1937.99 | 8.63 | 0.00 | 0.00 | 0.00 | 5.02 | 5.66 | 5.02
1924.54 | 7.37 | 0.00 | 0.00 | 0.00 | 5.42 | 5.85 | 5.42
1941.75 | 7.02 | 0.00 | 0.00 | 0.00 | 3.69 | 5.25 | 3.69
1920.25 | 6.95 | 0.00 | 0.00 | 0.00 | 12.78 | 5.24 | 12.78
1923.54 | 7.15 | 0.00 | 0.00 | 0.00 | 4.65 | 5.65 | 4.65
1891.48 | 7.02 | 0.00 | 0.00 | 0.00 | 4.58 | 5.40 | 4.58
1903.53 | 7.45 | 0.00 | 0.00 | 0.00 | 4.96 | 4.90 | 4.96
1936.62 | 8.09 | 0.00 | 0.00 | 0.00 | 3.64 | 5.13 | 3.64
1890.22 | 7.45 | 0.00 | 0.00 | 0.00 | 3.80 | 5.01 | 3.80
1908.25 | 6.99 | 0.00 | 0.00 | 0.00 | 4.06 | 5.16 | 4.06
1892.44 | 7.63 | 0.00 | 0.00 | 0.00 | 5.00 | 5.35 | 5.00
1904.94 | 6.98 | 0.00 | 0.00 | 0.00 | 3.84 | 5.98 | 3.84
1933.43 | 7.52 | 0.00 | 0.00 | 0.00 | 4.32 | 5.68 | 4.32
1891.48 | 7.14 | 0.00 | 0.00 | 0.00 | 4.18 | 5.98 | 4.18
1891.48 | 6.92 | 0.00 | 0.00 | 0.00 | 3.50 | 5.23 | 3.50
1892.95 | 7.59 | 0.00 | 0.00 | 0.00 | 3.80 | 4.94 | 3.80
1889.54 | 8.16 | 0.00 | 0.00 | 0.00 | 3.50 | 5.08 | 3.50
1891.48 | 6.84 | 0.00 | 0.00 | 0.00 | 3.55 | 4.84 | 3.55
1901.51 | 7.36 | 0.00 | 0.00 | 0.00 | 3.70 | 5.00 | 3.70
1896.13 | 7.51 | 0.00 | 0.00 | 0.00 | 5.02 | 5.60 | 5.02
1907.18 | 8.18 | 0.00 | 0.00 | 0.00 | 4.78 | 4.95 | 4.78
1943.86 | 7.12 | 0.00 | 0.00 | 0.00 | 3.79 | 5.77 | 3.79
1888.72 | 6.92 | 0.00 | 0.00 | 0.00 | 3.81 | 6.35 | 3.81
1905.81 | 8.32 | 0.00 | 0.00 | 0.00 | 4.41 | 7.13 | 4.41
1892.22 | 6.94 | 0.00 | 0.00 | 0.00 | 4.08 | 5.87 | 4.08
1893.14 | 7.03 | 0.00 | 0.00 | 0.00 | 3.62 | 5.39 | 3.62
1933.35 | 7.44 | 0.00 | 0.00 | 0.00 | 3.65 | 5.10 | 3.65
1891.40 | 7.33 | 0.00 | 0.00 | 0.00 | 4.20 | 4.92 | 4.20
1982.29 | 7.81 | 0.00 | 0.00 | 0.00 | 4.61 | 5.04 | 4.61
1892.40 | 7.56 | 0.00 | 0.00 | 0.00 | 3.65 | 5.50 | 3.65
1891.40 | 7.64 | 0.00 | 0.00 | 0.00 | 3.69 | 5.41 | 3.69
================== | ================== | ================== | ================== | ================== | ================== | ================== | ==================
1905.74+-1% | 7.42+-5% | 0.00 | 0.00 | 0.00 | 3.98+-10% | 5.49+-10% | 3.98+-10%
After (no attributes for DOM encapsulation generated)
forcedGcAmount | forcedGcTime | gcAmount | gcTime | majorGcTime | pureScriptTime | renderTime | scriptTime
------------------ | ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | ------------------
1291.92 | 8.28 | 483.76 | 1.24 | 0.00 | 33.55 | 7.19 | 33.55
1960.42 | 7.75 | 0.00 | 0.00 | 0.00 | 12.69 | 6.64 | 12.69
3193.17 | 7.13 | 0.00 | 0.00 | 0.00 | 10.84 | 6.31 | 10.84
1949.03 | 7.23 | 0.00 | 0.00 | 0.00 | 6.39 | 6.48 | 6.39
2042.38 | 7.67 | 0.00 | 0.00 | 0.00 | 7.47 | 5.23 | 7.47
1971.87 | 6.98 | 0.00 | 0.00 | 0.00 | 8.88 | 6.06 | 8.88
1947.78 | 6.54 | 0.00 | 0.00 | 0.00 | 6.18 | 5.71 | 6.18
1954.94 | 7.54 | 0.00 | 0.00 | 0.00 | 6.81 | 5.94 | 6.81
1925.70 | 6.70 | 0.00 | 0.00 | 0.00 | 8.83 | 6.63 | 8.83
2014.10 | 6.78 | 0.00 | 0.00 | 0.00 | 6.85 | 5.44 | 6.85
1985.87 | 6.79 | 0.00 | 0.00 | 0.00 | 7.59 | 5.12 | 7.59
1941.79 | 7.23 | 0.00 | 0.00 | 0.00 | 5.21 | 5.91 | 5.21
1927.33 | 7.60 | 0.00 | 0.00 | 0.00 | 6.48 | 6.37 | 6.48
1925.79 | 7.26 | 0.00 | 0.00 | 0.00 | 5.49 | 5.18 | 5.49
1952.45 | 6.57 | 0.00 | 0.00 | 0.00 | 3.48 | 5.83 | 3.48
1931.18 | 7.24 | 0.00 | 0.00 | 0.00 | 9.71 | 5.98 | 9.71
1932.65 | 7.31 | 0.00 | 0.00 | 0.00 | 4.91 | 5.45 | 4.91
1892.64 | 7.42 | 0.00 | 0.00 | 0.00 | 3.56 | 5.66 | 3.56
1913.31 | 7.61 | 0.00 | 0.00 | 0.00 | 6.65 | 6.35 | 6.65
1945.38 | 6.70 | 0.00 | 0.00 | 0.00 | 3.66 | 5.50 | 3.66
1893.10 | 6.98 | 0.00 | 0.00 | 0.00 | 4.71 | 5.57 | 4.71
1916.23 | 7.43 | 0.00 | 0.00 | 0.00 | 3.60 | 5.83 | 3.60
1893.06 | 7.83 | 0.00 | 0.00 | 0.00 | 3.73 | 5.53 | 3.73
1904.94 | 7.40 | 0.00 | 0.00 | 0.00 | 3.96 | 6.28 | 3.96
1935.42 | 6.78 | 0.00 | 0.00 | 0.00 | 4.20 | 6.51 | 4.20
1891.48 | 7.46 | 0.00 | 0.00 | 0.00 | 3.72 | 5.55 | 3.72
1891.48 | 7.57 | 0.00 | 0.00 | 0.00 | 3.44 | 5.33 | 3.44
1892.42 | 8.72 | 0.00 | 0.00 | 0.00 | 3.44 | 5.67 | 3.44
1889.54 | 7.31 | 0.00 | 0.00 | 0.00 | 4.16 | 5.29 | 4.16
1891.48 | 6.73 | 0.00 | 0.00 | 0.00 | 3.13 | 5.24 | 3.13
1900.89 | 6.71 | 0.00 | 0.00 | 0.00 | 3.50 | 5.86 | 3.50
1896.81 | 7.36 | 0.00 | 0.00 | 0.00 | 4.30 | 5.63 | 4.30
1911.38 | 7.27 | 0.00 | 0.00 | 0.00 | 3.34 | 5.63 | 3.34
1950.96 | 7.39 | 0.00 | 0.00 | 0.00 | 3.64 | 6.29 | 3.64
1888.80 | 7.34 | 0.00 | 0.00 | 0.00 | 3.25 | 5.33 | 3.25
1905.91 | 6.83 | 0.00 | 0.00 | 0.00 | 3.28 | 5.17 | 3.28
1893.04 | 6.81 | 0.00 | 0.00 | 0.00 | 3.45 | 5.30 | 3.45
1892.48 | 7.05 | 0.00 | 0.00 | 0.00 | 3.29 | 5.80 | 3.29
1933.43 | 7.55 | 0.00 | 0.00 | 0.00 | 3.71 | 6.36 | 3.71
1891.48 | 8.58 | 0.00 | 0.00 | 0.00 | 3.12 | 5.12 | 3.12
1999.46 | 7.93 | 0.00 | 0.00 | 0.00 | 3.32 | 5.22 | 3.32
1889.46 | 6.94 | 0.00 | 0.00 | 0.00 | 3.93 | 5.10 | 3.93
1892.22 | 7.38 | 0.00 | 0.00 | 0.00 | 3.31 | 5.50 | 3.31
1939.72 | 7.51 | 0.00 | 0.00 | 0.00 | 3.23 | 5.67 | 3.23
1891.85 | 7.35 | 0.00 | 0.00 | 0.00 | 3.23 | 5.63 | 3.23
1892.95 | 7.94 | 0.00 | 0.00 | 0.00 | 4.15 | 5.10 | 4.15
1892.48 | 6.90 | 0.00 | 0.00 | 0.00 | 3.90 | 5.66 | 3.90
1891.48 | 8.08 | 0.00 | 0.00 | 0.00 | 3.09 | 5.28 | 3.09
1933.43 | 6.91 | 0.00 | 0.00 | 0.00 | 4.15 | 5.37 | 4.15
================== | ================== | ================== | ================== | ================== | ================== | ================== | ==================
1908.99+-1% | 7.33+-6% | 0.00 | 0.00 | 0.00 | 3.52+-10% | 5.51+-6% | 3.52+-10%
With default CSS encapsulation Angular needs to create attributes in the DOM to scope CSS selectors (ex.:
<div _ngcontent-c0>. It turns out that sometimes those attributes are added even if not needed - this happens when a component references an empty styles file (viastylesUrl). Normally it wouldn't be a big deal but CLI scaffolding generates empty style files and triggers unnecessary DOM attributes creation.Compiler should understand that there are no meaningful CSS styles referenced and skip CSS-scoping attributes creation. It is should be a trivial fix and can speed up views creation by more than 11% in certain scenarios. Given a simple component like so:
and the following benchpress test:
I'm seeing ~11% improvement on my machine. I guess most of it can be explained by less DOM manipulation (no need to create attributes)
Here the detailed benchpress results.
Before (with empty styles)
After (no attributes for DOM encapsulation generated)