Skip to content

Commit fcadbf4

Browse files
mheveryvicb
authored andcommitted
perf: switch angular to use StaticInjector instead of ReflectiveInjector
This change allows ReflectiveInjector to be tree shaken resulting in not needed Reflect polyfil and smaller bundles. Code savings for HelloWorld using Closure: Reflective: bundle.js: 105,864(34,190 gzip) Static: bundle.js: 154,889(33,555 gzip) 645( 2%) BREAKING CHANGE: `platformXXXX()` no longer accepts providers which depend on reflection. Specifically the method signature when from `Provider[]` to `StaticProvider[]`. Example: Before: ``` [ MyClass, {provide: ClassA, useClass: SubClassA} ] ``` After: ``` [ {provide: MyClass, deps: [Dep1,...]}, {provide: ClassA, useClass: SubClassA, deps: [Dep1,...]} ] ``` NOTE: This only applies to platform creation and providers for the JIT compiler. It does not apply to `@Compotent` or `@NgModule` provides declarations. Benchpress note: Previously Benchpress also supported reflective provides, which now require static providers. DEPRECATION: - `ReflectiveInjector` is now deprecated as it will be remove. Use `Injector.create` as a replacement. closes #18496
1 parent d9d00bd commit fcadbf4

File tree

94 files changed

+380
-279
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+380
-279
lines changed

modules/e2e_util/perf_util.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const yargs = require('yargs');
1111
const nodeUuid = require('node-uuid');
1212
import * as fs from 'fs-extra';
1313

14-
import {SeleniumWebDriverAdapter, Options, JsonFileReporter, Validator, RegressionSlopeValidator, ConsoleReporter, SizeValidator, MultiReporter, MultiMetric, Runner, Provider} from '@angular/benchpress';
14+
import {SeleniumWebDriverAdapter, Options, JsonFileReporter, Validator, RegressionSlopeValidator, ConsoleReporter, SizeValidator, MultiReporter, MultiMetric, Runner, StaticProvider} from '@angular/benchpress';
1515
import {readCommandLine as readE2eCommandLine, openBrowser} from './e2e_util';
1616

1717
let cmdArgs: {'sample-size': number, 'force-gc': boolean, 'dryrun': boolean, 'bundles': boolean};
@@ -59,7 +59,7 @@ function createBenchpressRunner(): Runner {
5959
}
6060
const resultsFolder = './dist/benchmark_results';
6161
fs.ensureDirSync(resultsFolder);
62-
const providers: Provider[] = [
62+
const providers: StaticProvider[] = [
6363
SeleniumWebDriverAdapter.PROTRACTOR_PROVIDERS,
6464
{provide: Options.FORCE_GC, useValue: cmdArgs['force-gc']},
6565
{provide: Options.DEFAULT_DESCRIPTION, useValue: {'runId': runId}}, JsonFileReporter.PROVIDERS,

modules/playground/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# How to run the examples locally
22

3+
```
34
$ cp -r ./modules/playground ./dist/all/
45
$ ./node_modules/.bin/tsc -p modules --emitDecoratorMetadata -w
56
$ gulp serve
67
$ open http://localhost:8000/all/playground/src/hello_world/index.html?bundles=false
8+
```

packages/benchpress/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// Must be imported first, because Angular decorators throw on load.
1010
import 'reflect-metadata';
1111

12-
export {InjectionToken, Injector, Provider, ReflectiveInjector} from '@angular/core';
12+
export {InjectionToken, Injector, Provider, ReflectiveInjector, StaticProvider} from '@angular/core';
1313
export {Options} from './src/common_options';
1414
export {MeasureValues} from './src/measure_values';
1515
export {Metric} from './src/metric';

packages/benchpress/src/metric/perflog_metric.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,14 @@ import {PerfLogEvent, PerfLogFeatures, WebDriverExtension} from '../web_driver_e
2020
export class PerflogMetric extends Metric {
2121
static SET_TIMEOUT = new InjectionToken('PerflogMetric.setTimeout');
2222
static PROVIDERS = [
23-
PerflogMetric, {
23+
{
24+
provide: PerflogMetric,
25+
deps: [
26+
WebDriverExtension, PerflogMetric.SET_TIMEOUT, Options.MICRO_METRICS, Options.FORCE_GC,
27+
Options.CAPTURE_FRAMES, Options.RECEIVED_DATA, Options.REQUEST_COUNT
28+
]
29+
},
30+
{
2431
provide: PerflogMetric.SET_TIMEOUT,
2532
useValue: (fn: Function, millis: number) => <any>setTimeout(fn, millis)
2633
}

packages/benchpress/src/metric/user_metric.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,16 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {Inject, Injectable} from '@angular/core';
9+
import {Inject, Injectable, StaticProvider} from '@angular/core';
1010

1111
import {Options} from '../common_options';
1212
import {Metric} from '../metric';
1313
import {WebDriverAdapter} from '../web_driver_adapter';
1414

1515
@Injectable()
1616
export class UserMetric extends Metric {
17-
static PROVIDERS = [UserMetric];
17+
static PROVIDERS =
18+
<StaticProvider[]>[{provide: UserMetric, deps: [Options.USER_METRICS, WebDriverAdapter]}];
1819

1920
constructor(
2021
@Inject(Options.USER_METRICS) private _userMetrics: {[key: string]: string},

packages/benchpress/src/reporter/console_reporter.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ export class ConsoleReporter extends Reporter {
2222
static PRINT = new InjectionToken('ConsoleReporter.print');
2323
static COLUMN_WIDTH = new InjectionToken('ConsoleReporter.columnWidth');
2424
static PROVIDERS = [
25-
ConsoleReporter, {provide: ConsoleReporter.COLUMN_WIDTH, useValue: 18}, {
25+
{
26+
provide: ConsoleReporter,
27+
deps: [ConsoleReporter.COLUMN_WIDTH, SampleDescription, ConsoleReporter.PRINT]
28+
},
29+
{provide: ConsoleReporter.COLUMN_WIDTH, useValue: 18}, {
2630
provide: ConsoleReporter.PRINT,
2731
useValue: function(v: any) {
2832
// tslint:disable-next-line:no-console

packages/benchpress/src/reporter/json_file_reporter.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,13 @@ import {formatStats, sortedProps} from './util';
2222
@Injectable()
2323
export class JsonFileReporter extends Reporter {
2424
static PATH = new InjectionToken('JsonFileReporter.path');
25-
static PROVIDERS = [JsonFileReporter, {provide: JsonFileReporter.PATH, useValue: '.'}];
25+
static PROVIDERS = [
26+
{
27+
provide: JsonFileReporter,
28+
deps: [SampleDescription, JsonFileReporter.PATH, Options.WRITE_FILE, Options.NOW]
29+
},
30+
{provide: JsonFileReporter.PATH, useValue: '.'}
31+
];
2632

2733
constructor(
2834
private _description: SampleDescription, @Inject(JsonFileReporter.PATH) private _path: string,

packages/benchpress/src/runner.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {Provider, ReflectiveInjector} from '@angular/core';
9+
import {Injector, StaticProvider} from '@angular/core';
1010

1111
import {Options} from './common_options';
1212
import {Metric} from './metric';
@@ -34,17 +34,17 @@ import {IOsDriverExtension} from './webdriver/ios_driver_extension';
3434
* It provides defaults, creates the injector and calls the sampler.
3535
*/
3636
export class Runner {
37-
constructor(private _defaultProviders: Provider[] = []) {}
37+
constructor(private _defaultProviders: StaticProvider[] = []) {}
3838

3939
sample({id, execute, prepare, microMetrics, providers, userMetrics}: {
4040
id: string,
4141
execute?: Function,
4242
prepare?: Function,
4343
microMetrics?: {[key: string]: string},
44-
providers?: Provider[],
44+
providers?: StaticProvider[],
4545
userMetrics?: {[key: string]: string}
4646
}): Promise<SampleState> {
47-
const sampleProviders: Provider[] = [
47+
const sampleProviders: StaticProvider[] = [
4848
_DEFAULT_PROVIDERS, this._defaultProviders, {provide: Options.SAMPLE_ID, useValue: id},
4949
{provide: Options.EXECUTE, useValue: execute}
5050
];
@@ -61,7 +61,7 @@ export class Runner {
6161
sampleProviders.push(providers);
6262
}
6363

64-
const inj = ReflectiveInjector.resolveAndCreate(sampleProviders);
64+
const inj = Injector.create(sampleProviders);
6565
const adapter: WebDriverAdapter = inj.get(WebDriverAdapter);
6666

6767
return Promise
@@ -75,7 +75,7 @@ export class Runner {
7575
// Only WebDriverAdapter is reused.
7676
// TODO vsavkin consider changing it when toAsyncFactory is added back or when child
7777
// injectors are handled better.
78-
const injector = ReflectiveInjector.resolveAndCreate([
78+
const injector = Injector.create([
7979
sampleProviders, {provide: Options.CAPABILITIES, useValue: capabilities},
8080
{provide: Options.USER_AGENT, useValue: userAgent},
8181
{provide: WebDriverAdapter, useValue: adapter}

packages/benchpress/src/sampler.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {Inject, Injectable} from '@angular/core';
9+
import {Inject, Injectable, StaticProvider} from '@angular/core';
1010

1111
import {Options} from './common_options';
1212
import {MeasureValues} from './measure_values';
@@ -26,8 +26,12 @@ import {WebDriverAdapter} from './web_driver_adapter';
2626
*/
2727
@Injectable()
2828
export class Sampler {
29-
static PROVIDERS = [Sampler];
30-
29+
static PROVIDERS = <StaticProvider[]>[{
30+
provide: Sampler,
31+
deps: [
32+
WebDriverAdapter, Metric, Reporter, Validator, Options.PREPARE, Options.EXECUTE, Options.NOW
33+
]
34+
}];
3135
constructor(
3236
private _driver: WebDriverAdapter, private _metric: Metric, private _reporter: Reporter,
3337
private _validator: Validator, @Inject(Options.PREPARE) private _prepare: Function,

packages/benchpress/src/validator/regression_slope_validator.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ export class RegressionSlopeValidator extends Validator {
2121
static SAMPLE_SIZE = new InjectionToken('RegressionSlopeValidator.sampleSize');
2222
static METRIC = new InjectionToken('RegressionSlopeValidator.metric');
2323
static PROVIDERS = [
24-
RegressionSlopeValidator, {provide: RegressionSlopeValidator.SAMPLE_SIZE, useValue: 10},
24+
{
25+
provide: RegressionSlopeValidator,
26+
deps: [RegressionSlopeValidator.SAMPLE_SIZE, RegressionSlopeValidator.METRIC]
27+
},
28+
{provide: RegressionSlopeValidator.SAMPLE_SIZE, useValue: 10},
2529
{provide: RegressionSlopeValidator.METRIC, useValue: 'scriptTime'}
2630
];
2731

packages/benchpress/src/validator/size_validator.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ import {Validator} from '../validator';
1717
@Injectable()
1818
export class SizeValidator extends Validator {
1919
static SAMPLE_SIZE = new InjectionToken('SizeValidator.sampleSize');
20-
static PROVIDERS = [SizeValidator, {provide: SizeValidator.SAMPLE_SIZE, useValue: 10}];
20+
static PROVIDERS = [
21+
{provide: SizeValidator, deps: [SizeValidator.SAMPLE_SIZE]},
22+
{provide: SizeValidator.SAMPLE_SIZE, useValue: 10}
23+
];
2124

2225
constructor(@Inject(SizeValidator.SAMPLE_SIZE) private _sampleSize: number) { super(); }
2326

packages/benchpress/src/webdriver/chrome_driver_extension.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {Inject, Injectable} from '@angular/core';
9+
import {Inject, Injectable, StaticProvider} from '@angular/core';
1010

1111
import {Options} from '../common_options';
1212
import {WebDriverAdapter} from '../web_driver_adapter';
@@ -21,7 +21,10 @@ import {PerfLogEvent, PerfLogFeatures, WebDriverExtension} from '../web_driver_e
2121
*/
2222
@Injectable()
2323
export class ChromeDriverExtension extends WebDriverExtension {
24-
static PROVIDERS = [ChromeDriverExtension];
24+
static PROVIDERS = <StaticProvider>[{
25+
provide: ChromeDriverExtension,
26+
deps: [WebDriverAdapter, Options.USER_AGENT]
27+
}];
2528

2629
private _majorChromeVersion: number;
2730
private _firstRun = true;

packages/benchpress/src/webdriver/firefox_driver_extension.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {PerfLogEvent, PerfLogFeatures, WebDriverExtension} from '../web_driver_e
1313

1414
@Injectable()
1515
export class FirefoxDriverExtension extends WebDriverExtension {
16-
static PROVIDERS = [FirefoxDriverExtension];
16+
static PROVIDERS = [{provide: FirefoxDriverExtension, deps: [WebDriverAdapter]}];
1717

1818
private _profilerStarted: boolean;
1919

packages/benchpress/src/webdriver/ios_driver_extension.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {PerfLogEvent, PerfLogFeatures, WebDriverExtension} from '../web_driver_e
1313

1414
@Injectable()
1515
export class IOsDriverExtension extends WebDriverExtension {
16-
static PROVIDERS = [IOsDriverExtension];
16+
static PROVIDERS = [{provide: IOsDriverExtension, deps: [WebDriverAdapter]}];
1717

1818
constructor(private _driver: WebDriverAdapter) { super(); }
1919

packages/benchpress/src/webdriver/selenium_webdriver_adapter.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,19 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9+
import {StaticProvider} from '@angular/core';
10+
911
import {WebDriverAdapter} from '../web_driver_adapter';
1012

13+
1114
/**
1215
* Adapter for the selenium-webdriver.
1316
*/
1417
export class SeleniumWebDriverAdapter extends WebDriverAdapter {
15-
static PROTRACTOR_PROVIDERS = [{
18+
static PROTRACTOR_PROVIDERS = <StaticProvider[]>[{
1619
provide: WebDriverAdapter,
17-
useFactory: () => new SeleniumWebDriverAdapter((<any>global).browser)
20+
useFactory: () => new SeleniumWebDriverAdapter((<any>global).browser),
21+
deps: []
1822
}];
1923

2024
constructor(private _driver: any) { super(); }

packages/benchpress/test/metric/multi_metric_spec.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77
*/
88

99
import {AsyncTestCompleter, describe, expect, inject, it} from '@angular/core/testing/src/testing_internal';
10-
import {Metric, MultiMetric, ReflectiveInjector} from '../../index';
10+
11+
import {Injector, Metric, MultiMetric} from '../../index';
1112

1213
export function main() {
1314
function createMetric(ids: any[]) {
14-
const m = ReflectiveInjector
15-
.resolveAndCreate([
15+
const m = Injector
16+
.create([
1617
ids.map(id => ({provide: id, useValue: new MockMetric(id)})),
1718
MultiMetric.provideWith(ids)
1819
])

packages/benchpress/test/metric/perflog_metric_spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {Provider} from '@angular/core';
9+
import {StaticProvider} from '@angular/core';
1010
import {AsyncTestCompleter, beforeEach, describe, expect, inject, it} from '@angular/core/testing/src/testing_internal';
1111

12-
import {Metric, Options, PerfLogEvent, PerfLogFeatures, PerflogMetric, ReflectiveInjector, WebDriverExtension} from '../../index';
12+
import {Injector, Metric, Options, PerfLogEvent, PerfLogFeatures, PerflogMetric, WebDriverExtension} from '../../index';
1313
import {TraceEventFactory} from '../trace_event_factory';
1414

1515
export function main() {
@@ -33,7 +33,7 @@ export function main() {
3333
if (!microMetrics) {
3434
microMetrics = {};
3535
}
36-
const providers: Provider[] = [
36+
const providers: StaticProvider[] = [
3737
Options.DEFAULT_PROVIDERS, PerflogMetric.PROVIDERS,
3838
{provide: Options.MICRO_METRICS, useValue: microMetrics}, {
3939
provide: PerflogMetric.SET_TIMEOUT,
@@ -59,7 +59,7 @@ export function main() {
5959
if (requestCount != null) {
6060
providers.push({provide: Options.REQUEST_COUNT, useValue: requestCount});
6161
}
62-
return ReflectiveInjector.resolveAndCreate(providers).get(PerflogMetric);
62+
return Injector.create(providers).get(PerflogMetric);
6363
}
6464

6565
describe('perflog metric', () => {

packages/benchpress/test/metric/user_metric_spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {Provider, ReflectiveInjector} from '@angular/core';
9+
import {Injector, StaticProvider} from '@angular/core';
1010
import {AsyncTestCompleter, describe, expect, inject, it} from '@angular/core/testing/src/testing_internal';
1111

1212
import {Options, PerfLogEvent, PerfLogFeatures, UserMetric, WebDriverAdapter} from '../../index';
@@ -25,12 +25,12 @@ export function main() {
2525
userMetrics = {};
2626
}
2727
wdAdapter = new MockDriverAdapter();
28-
const providers: Provider[] = [
28+
const providers: StaticProvider[] = [
2929
Options.DEFAULT_PROVIDERS, UserMetric.PROVIDERS,
3030
{provide: Options.USER_METRICS, useValue: userMetrics},
3131
{provide: WebDriverAdapter, useValue: wdAdapter}
3232
];
33-
return ReflectiveInjector.resolveAndCreate(providers).get(UserMetric);
33+
return Injector.create(providers).get(UserMetric);
3434
}
3535

3636
describe('user metric', () => {

packages/benchpress/test/reporter/console_reporter_spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {Provider} from '@angular/core';
9+
import {StaticProvider} from '@angular/core';
1010
import {describe, expect, it} from '@angular/core/testing/src/testing_internal';
1111

12-
import {ConsoleReporter, MeasureValues, ReflectiveInjector, SampleDescription} from '../../index';
12+
import {ConsoleReporter, Injector, MeasureValues, SampleDescription} from '../../index';
1313

1414
export function main() {
1515
describe('console reporter', () => {
@@ -30,7 +30,7 @@ export function main() {
3030
if (sampleId == null) {
3131
sampleId = 'null';
3232
}
33-
const providers: Provider[] = [
33+
const providers: StaticProvider[] = [
3434
ConsoleReporter.PROVIDERS, {
3535
provide: SampleDescription,
3636
useValue: new SampleDescription(sampleId, descriptions, metrics !)
@@ -40,7 +40,7 @@ export function main() {
4040
if (columnWidth != null) {
4141
providers.push({provide: ConsoleReporter.COLUMN_WIDTH, useValue: columnWidth});
4242
}
43-
reporter = ReflectiveInjector.resolveAndCreate(providers).get(ConsoleReporter);
43+
reporter = Injector.create(providers).get(ConsoleReporter);
4444
}
4545

4646
it('should print the sample id, description and table header', () => {

packages/benchpress/test/reporter/json_file_reporter_spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import {AsyncTestCompleter, describe, expect, inject, it} from '@angular/core/testing/src/testing_internal';
1010

11-
import {JsonFileReporter, MeasureValues, Options, ReflectiveInjector, SampleDescription} from '../../index';
11+
import {Injector, JsonFileReporter, MeasureValues, Options, SampleDescription} from '../../index';
1212

1313
export function main() {
1414
describe('file reporter', () => {
@@ -34,7 +34,7 @@ export function main() {
3434
}
3535
}
3636
];
37-
return ReflectiveInjector.resolveAndCreate(providers).get(JsonFileReporter);
37+
return Injector.create(providers).get(JsonFileReporter);
3838
}
3939

4040
it('should write all data into a file',

packages/benchpress/test/reporter/multi_reporter_spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88

99
import {AsyncTestCompleter, describe, expect, inject, it} from '@angular/core/testing/src/testing_internal';
1010

11-
import {MeasureValues, MultiReporter, ReflectiveInjector, Reporter} from '../../index';
11+
import {Injector, MeasureValues, MultiReporter, Reporter} from '../../index';
1212

1313
export function main() {
1414
function createReporters(ids: any[]) {
15-
const r = ReflectiveInjector
16-
.resolveAndCreate([
15+
const r = Injector
16+
.create([
1717
ids.map(id => ({provide: id, useValue: new MockReporter(id)})),
1818
MultiReporter.provideWith(ids)
1919
])

0 commit comments

Comments
 (0)