diff --git a/CHANGELOG.md b/CHANGELOG.md
index ab72d1f3c..0cace6d49 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,22 @@
+<a name="5.2.0"></a>
+# [5.2.0](https://github.com/angular/angularfire2/compare/5.1.3...5.2.0) (2019-05-24)
+
+### Bug Fixes
+
+* **firestore:** Fix for builds targeting Node ([#2079](https://github.com/angular/angularfire2/issues/2079)) ([8a33826](https://github.com/angular/angularfire2/commit/8a33826))
+* **storage:** Typo in updateMetadata method ([#2029](https://github.com/angular/angularfire2/issues/2029)) ([6133296](https://github.com/angular/angularfire2/commit/6133296))
+
+### Features
+
+* **performance:** AngularFire Performance Monitoring ([#2064](https://github.com/angular/angularfire2/issues/2064))
+* **auth-guard:** AngularFire Auth Guards ([#2016](https://github.com/angular/angularfire2/issues/2016)) ([e32164d](https://github.com/angular/angularfire2/commit/e32164d))
+* **firestore:** Added option to include document IDs on valueChanges() ([#1976](https://github.com/angular/angularfire2/issues/1976)) ([7108875](https://github.com/angular/angularfire2/commit/7108875))
+* **firestore:** Support Firestore Collection Group Queries ([#2066](https://github.com/angular/angularfire2/issues/2066)) ([c34c0f3](https://github.com/angular/angularfire2/commit/c34c0f3))
+* **functions:** Allow configuration of Functions Emulator Origin ([#2017](https://github.com/angular/angularfire2/issues/2017)) ([d12b4c5](https://github.com/angular/angularfire2/commit/d12b4c5))
+* **schematics:** ng deploy schematic ([#2046](https://github.com/angular/angularfire2/issues/2046)) ([be0a1fb](https://github.com/angular/angularfire2/commit/be0a1fb))
+
+
+
 <a name="5.1.2"></a>
 # [5.1.2](https://github.com/angular/angularfire2/compare/5.1.1...5.1.2) (2019-03-11)
 
diff --git a/README.md b/README.md
index dcc8bd114..2b8446404 100644
--- a/README.md
+++ b/README.md
@@ -98,6 +98,10 @@ Firebase offers two cloud-based, client-accessible database solutions that suppo
 
 - [Getting started with Firebase Messaging](docs/messaging/messaging.md)
 
+### Monitor your application performance in production
+
+- [Getting started with Performance Monitoring](docs/performance/getting-started.md)
+
 ### Directly call Cloud Functions
 
 - [Getting started with Callable Functions](docs/functions/functions.md)
diff --git a/cloudbuild.yaml b/cloudbuild.yaml
index 866bd6dc4..fc52bd244 100644
--- a/cloudbuild.yaml
+++ b/cloudbuild.yaml
@@ -4,19 +4,19 @@
 #   @next   `gcloud builds submit --substitutions=TAG_NAME="v1.2.3-rc.1"`
 #   @latest `gcloud builds submit --substitutions=TAG_NAME="v1.2.3"`
 steps:
-- name: 'gcr.io/cloud-builders/yarn'
-  entrypoint: 'bash'
+- name: node:lts
+  entrypoint: bash
   args: ["./tools/build.sh"]
   env:
   - 'TAG_NAME=$TAG_NAME'
   - 'SHORT_SHA=$SHORT_SHA'
 
-- name: 'gcr.io/cloud-builders/yarn'
-  entrypoint: 'bash'
+- name: node:lts
+  entrypoint: bash
   args: ["./tools/test.sh"]
 
-- name: 'gcr.io/cloud-builders/npm'
-  entrypoint: 'bash'
+- name: node:lts
+  entrypoint: bash
   env: ['TAG_NAME=$TAG_NAME']
   args: ["./tools/release.sh"]
   secretEnv: ['NPM_TOKEN']
@@ -24,4 +24,6 @@ steps:
 secrets:
 - kmsKeyName: projects/angularfire/locations/global/keyRings/cloud-build/cryptoKeys/cloud-build
   secretEnv:
-    NPM_TOKEN: CiQAwtE8WoPa1sNqAQJZ1WMODuJooVmO6zihz2hAZOfUmDsgogUSTQCq8yp8qgltY+8jWpAR9GuS1JaVhd+fTVRilqLtdi2yXSdiDPTzLhZ+30bMlAOcoc0PxhCBn3JOpn8H1xshX+mG8yK7xog2Uq+CLVx/
\ No newline at end of file
+    NPM_TOKEN: CiQAwtE8WoPa1sNqAQJZ1WMODuJooVmO6zihz2hAZOfUmDsgogUSTQCq8yp8qgltY+8jWpAR9GuS1JaVhd+fTVRilqLtdi2yXSdiDPTzLhZ+30bMlAOcoc0PxhCBn3JOpn8H1xshX+mG8yK7xog2Uq+CLVx/
+
+timeout: 1200s
\ No newline at end of file
diff --git a/docs/performance/getting-started.md b/docs/performance/getting-started.md
new file mode 100644
index 000000000..e38abd933
--- /dev/null
+++ b/docs/performance/getting-started.md
@@ -0,0 +1,145 @@
+# Getting started with Performance Monitoring
+
+## Automatic page load tracing
+
+Understand your Angular application's real-world performance with [Firebase Performance Monitoring](https://firebase.google.com/docs/perf-mon). Performance Monitoring automatically provides a trace for **page load** when you add `AngularFirePerformanceModule` into your App Module's imports.
+
+```ts
+import { AngularFireModule } from '@angular/fire';
+import { AngularFirePerformanceModule } from '@angular/fire/performance';
+import { environment } from '../environments/environment';
+
+@NgModule({
+  imports: [
+    BrowserModule,
+    AngularFireModule.initializeApp(environment.firebase),
+    AngularFirePerformanceModule,
+    ...
+  ],
+  declarations: [ AppComponent ],
+  bootstrap: [ AppComponent ]
+})
+export class AppModule {}
+```
+
+The page load trace breaks down into the following default metrics:
+
+* [first paint traces](https://firebase.google.com/docs/perf-mon/automatic-web#first-paint) — measure the time between when the user navigates to a page and when any visual change happens
+* [first contentful paint traces](https://firebase.google.com/docs/perf-mon/automatic-web#contentful-paint) — measure the time between when a user navigates to a page and when meaningful content displays, like an image or text
+* [domInteractive traces](https://firebase.google.com/docs/perf-mon/automatic-web#domInteractive) — measure the time between when the user navigates to a page and when the page is considered interactive for the user
+* [domContentLoadedEventEnd traces](https://firebase.google.com/docs/perf-mon/automatic-web#domContentLoaded) — measure the time between when the user navigates to a page and when the initial HTML document is completely loaded and parsed
+* [loadEventEnd traces](https://firebase.google.com/docs/perf-mon/automatic-web#loadEventEnd) — measure the time between when the user navigates to the page and when the current document's load event completes
+* [first input delay traces](https://firebase.google.com/docs/perf-mon/automatic-web#input-delay) — measure the time between when the user interacts with a page and when the browser is able to respond to that input
+* **Angular specific traces** - measure the time needed for `ApplicationRef.isStable` to be true, an important metric to track if you're concerned about solving Zone.js issues for proper functionality of NGSW and Server Side Rendering
+
+## Manual traces
+
+You can inject `AngularFirePerformance` to perform manual traces on Observables.
+
+```ts
+constructor(private afp: AngularFirePerformance, private afs: AngularFirestore) {}
+
+ngOnInit() {
+  this.articles = afs.collection('articles')
+      .collection('articles', ref => ref.orderBy('publishedAt', 'desc'))
+      .snapshotChanges()
+      .pipe(
+        // measure the amount of time between the Observable being subscribed to and first emission (or completion)
+        this.afp.trace('getArticles'),
+        map(articles => ...)
+      );
+}
+```
+
+### `trace(name:string)`
+
+The most basic operator, `trace` will measure the amount of time it takes for your observable to either complete or emit its first value. Beyond the basic trace there are several other operators:
+
+### `traceUntil(name:string, test: (T) => Boolean)`
+
+Trace the observable until the first emission that passes the provided test.
+
+### `traceWhile(name:string, test: (T) => Boolean)`
+
+Trace the observable until the first emission that fails the provided test.
+
+### `traceUntilLast(name:string)`
+
+Trace the observable until completion.
+
+### `traceUntilFirst(name: string)`
+
+Traces the observable until the first emission.
+
+## Advanced usage
+
+### Configuration via Dependency Injection
+
+By default, `AngularFirePerformanceModule` traces your Angular application's time to `ApplicationRef.isStable`. `isStable` is an important metric to track if you're concerned about proper functionality of NGSW and Server Side Rendering. If you want to opt-out of the tracing of this metric use the `AUTOMATICALLY_TRACE_CORE_NG_METRICS` injection token:
+
+```ts
+import { NgModule } from '@angular/core';
+import { AngularFirePerformanceModule, AUTOMATICALLY_TRACE_CORE_NG_METRICS } from '@angular/fire/functions';
+
+@NgModule({
+  imports: [
+    ...
+    AngularFirePerformanceModule,
+    ...
+  ],
+  ...
+  providers: [
+   { provide: AUTOMATICALLY_TRACE_CORE_NG_METRICS, useValue: false }
+  ]
+})
+export class AppModule {}
+```
+
+Similarly, setting `INSTRUMENTATION_ENABLED` or `DATA_COLLECTION_ENABLED` to false disable all automatic and custom traces respectively.
+
+### Get at an observable form of trace
+
+`trace$(name:string)` provides an observable version of `firebase/perf`'s `.trace` method; the basis for `AngularFirePerfomance`'s pipes.
+
+`.subscribe()` is equivalent to calling `.start()`
+`.unsubscribe()` is equivalent to calling `.stop()`
+
+### Using `TraceOptions` to collect additional metrics
+
+`TraceOptions` can be provided to the aformentioned operators to collect custom metrics and attributes on your traces:
+
+```ts
+type TraceOptions = {
+  metrics?: { [key:string]: number },
+  attributes?: { [key:string]: string },
+  attribute$?: { [key:string]: Observable<string> },
+  incrementMetric$: { [key:string]: Observable<number|void|null|undefined> },
+  metric$?: { [key:string]: Observable<number> }
+};
+```
+
+#### Usage:
+
+```ts
+const articleLength$ = this.articles.pipe(
+  map(actions => actions.length)
+);
+
+const articleSize$ = this.articles.pipe(
+  map(actions => actions.reduce((sum, a) => sum += JSON.stringify(a.payload.doc.data()).length))
+)
+
+this.articles = afs.collection('articles')
+      .collection('articles', ref => ref.orderBy('publishedAt', 'desc'))
+      .snapshotChanges()
+      .pipe(
+        this.afp.trace('getArticles', {
+          attributes: { gitSha: '1d277f823ad98dd739fb86e9a6c440aa8237ff3a' },
+          metrics: { something: 42 },
+          metrics$: { count: articleLength$, size: articleSize$ },
+          attributes$: { user: this.afAuth.user },
+          incrementMetric$: { buttonClicks: fromEvent(button, 'click') }
+        }),
+        share()
+      );
+```
\ No newline at end of file
diff --git a/karma.conf.js b/karma.conf.js
index 741435dd8..5ab48f0da 100644
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -30,6 +30,7 @@ module.exports = function(config) {
       'node_modules/firebase/firebase-database.js',
       'node_modules/firebase/firebase-firestore.js',
       'node_modules/firebase/firebase-functions.js',
+      'node_modules/firebase/firebase-performance.js',
       'node_modules/firebase/firebase-storage.js',
       'dist/packages-dist/bundles/core.umd.{js,map}',
       'dist/packages-dist/bundles/auth.umd.{js,map}',
@@ -38,6 +39,7 @@ module.exports = function(config) {
       'dist/packages-dist/bundles/firestore.umd.{js,map}',
       'dist/packages-dist/bundles/functions.umd.{js,map}',
       'dist/packages-dist/bundles/storage.umd.{js,map}',
+      'dist/packages-dist/bundles/performance.umd.{js,map}',
       'dist/packages-dist/bundles/database-deprecated.umd.{js,map}',
       'dist/packages-dist/bundles/test.umd.{js,map}',
     ],
diff --git a/package.json b/package.json
index 0a500276f..2322578a1 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,5 @@
 {
-  "name": "angularfire2",
+  "name": "@angular/fire",
   "version": "5.2.0",
   "description": "The official library of Firebase and Angular.",
   "private": true,
@@ -33,7 +33,7 @@
   },
   "homepage": "https://github.com/angular/angularfire2#readme",
   "dependencies": {
-    "@angular-devkit/architect": "^0.800.0-rc.4",
+    "@angular-devkit/architect": "^0.800.0-rc.4 || >=8.0.0 <9 || 9.0.0-0",
     "@angular-devkit/core": ">=6.0.0 <9 || 9.0.0-0",
     "@angular-devkit/schematics": ">=6.0.0 <9 || 9.0.0-0",
     "@angular/common": ">=6.0.0 <9 || 9.0.0-0",
diff --git a/src/core/firebase.app.module.ts b/src/core/firebase.app.module.ts
index 72b195969..ed35ff51d 100644
--- a/src/core/firebase.app.module.ts
+++ b/src/core/firebase.app.module.ts
@@ -25,6 +25,7 @@ export class FirebaseApp {
     auth: () => FirebaseAuth;
     database: (databaseURL?: string) => FirebaseDatabase;
     messaging: () => FirebaseMessaging;
+    performance: () => any; // SEMVER: once >= 6 import performance.Performance
     storage: (storageBucket?: string) => FirebaseStorage;
     delete: () => Promise<void>;
     firestore: () => FirebaseFirestore;
diff --git a/src/performance/index.spec.ts b/src/performance/index.spec.ts
new file mode 100644
index 000000000..bf7cd6401
--- /dev/null
+++ b/src/performance/index.spec.ts
@@ -0,0 +1 @@
+export * from './performance.spec';
diff --git a/src/performance/index.ts b/src/performance/index.ts
new file mode 100644
index 000000000..4aaf8f92e
--- /dev/null
+++ b/src/performance/index.ts
@@ -0,0 +1 @@
+export * from './public_api';
diff --git a/src/performance/package.json b/src/performance/package.json
new file mode 100644
index 000000000..67c354cbd
--- /dev/null
+++ b/src/performance/package.json
@@ -0,0 +1,30 @@
+{
+  "name": "@angular/fire/performance",
+  "version": "ANGULARFIRE2_VERSION",
+  "description": "The performance monitoring module",
+  "main": "../bundles/performance.umd.js",
+  "module": "index.js",
+  "es2015": "./es2015/index.js",
+  "keywords": [
+    "angular",
+    "firebase",
+    "rxjs"
+  ],
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/angular/angularfire2.git"
+  },
+  "author": "angular,firebase",
+  "license": "MIT",
+  "peerDependencies": {
+    "@angular/fire": "ANGULARFIRE2_VERSION",
+    "@angular/common": "ANGULAR_VERSION",
+    "@angular/core": "ANGULAR_VERSION",
+    "@angular/platform-browser": "ANGULAR_VERSION",
+    "@angular/platform-browser-dynamic": "ANGULAR_VERSION",
+    "firebase": "FIREBASE_VERSION",
+    "rxjs": "RXJS_VERSION",
+    "zone.js": "ZONEJS_VERSION"
+  },
+  "typings": "index.d.ts"
+}
diff --git a/src/performance/performance.module.ts b/src/performance/performance.module.ts
new file mode 100644
index 000000000..c167877fc
--- /dev/null
+++ b/src/performance/performance.module.ts
@@ -0,0 +1,9 @@
+import { NgModule } from '@angular/core';
+import { AngularFirePerformance } from './performance';
+
+import 'firebase/performance';
+
+@NgModule({
+  providers: [ AngularFirePerformance ]
+})
+export class AngularFirePerformanceModule { }
diff --git a/src/performance/performance.spec.ts b/src/performance/performance.spec.ts
new file mode 100644
index 000000000..f610feeeb
--- /dev/null
+++ b/src/performance/performance.spec.ts
@@ -0,0 +1,36 @@
+import { TestBed, inject } from '@angular/core/testing';
+import { FirebaseApp, AngularFireModule } from '@angular/fire';
+import { AngularFirePerformance, AngularFirePerformanceModule } from '@angular/fire/performance';
+import { COMMON_CONFIG } from './test-config';
+
+describe('AngularFirePerformance', () => {
+  let app: FirebaseApp;
+  let afp: AngularFirePerformance;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({
+      imports: [
+        AngularFireModule.initializeApp(COMMON_CONFIG),
+        AngularFirePerformanceModule
+      ]
+    });
+    inject([FirebaseApp, AngularFirePerformance], (app_: FirebaseApp, _perf: AngularFirePerformance) => {
+      app = app_;
+      afp = _perf;
+    })();
+  });
+
+  afterEach(done => {
+    app.delete();
+    done();
+  });
+
+  it('should be exist', () => {
+    expect(afp instanceof AngularFirePerformance).toBe(true);
+  });
+
+  it('should have the Performance instance', () => {
+    expect(afp.performance).toBeDefined();
+  });
+
+});
\ No newline at end of file
diff --git a/src/performance/performance.ts b/src/performance/performance.ts
new file mode 100644
index 000000000..f1c909565
--- /dev/null
+++ b/src/performance/performance.ts
@@ -0,0 +1,123 @@
+import { Injectable, NgZone, ApplicationRef, InjectionToken, Inject, Optional } from '@angular/core';
+import { Observable } from 'rxjs';
+import { first, tap } from 'rxjs/operators';
+import { performance } from 'firebase/app';
+
+export const AUTOMATICALLY_TRACE_CORE_NG_METRICS = new InjectionToken<boolean>('angularfire2.performance.auto_trace');
+export const INSTRUMENTATION_ENABLED = new InjectionToken<boolean>('angularfire2.performance.instrumentationEnabled');
+export const DATA_COLLECTION_ENABLED = new InjectionToken<boolean>('angularfire2.performance.dataCollectionEnabled');
+
+export type TraceOptions = {
+  metrics?: {[key:string]: number},
+  attributes?: {[key:string]:string},
+  attribute$?: {[key:string]:Observable<string>},
+  incrementMetric$?: {[key:string]: Observable<number|void|null|undefined>},
+  metric$?: {[key:string]: Observable<number>}
+};
+
+@Injectable()
+export class AngularFirePerformance {
+  
+  performance: performance.Performance;
+
+  constructor(
+    @Optional() @Inject(AUTOMATICALLY_TRACE_CORE_NG_METRICS) automaticallyTraceCoreNgMetrics:boolean|null,
+    @Optional() @Inject(INSTRUMENTATION_ENABLED) instrumentationEnabled:boolean|null,
+    @Optional() @Inject(DATA_COLLECTION_ENABLED) dataCollectionEnabled:boolean|null,
+    appRef: ApplicationRef,
+    private zone: NgZone
+  ) {
+    
+    this.performance = zone.runOutsideAngular(() => performance());
+
+    if (instrumentationEnabled == false) { this.performance.instrumentationEnabled = false }
+    if (dataCollectionEnabled == false) { this.performance.dataCollectionEnabled = false }
+    
+    if (automaticallyTraceCoreNgMetrics != false) {
+
+      // TODO determine more built in metrics
+      appRef.isStable.pipe(
+        this.traceUntilLast('isStable'),
+        first(it => it)
+      ).subscribe();
+
+    }
+
+  }
+
+  trace$ = (name:string, options?: TraceOptions) => new Observable<void>(emitter => 
+    this.zone.runOutsideAngular(() => {
+      const trace = this.performance.trace(name);
+      options && options.metrics && Object.keys(options.metrics).forEach(metric => {
+        trace.putMetric(metric, options!.metrics![metric])
+      });
+      options && options.attributes && Object.keys(options.attributes).forEach(attribute => {
+        trace.putAttribute(attribute, options!.attributes![attribute])
+      });
+      const attributeSubscriptions = options && options.attribute$ ? Object.keys(options.attribute$).map(attribute =>
+        options!.attribute$![attribute].subscribe(next => trace.putAttribute(attribute, next))
+      ) : [];
+      const metricSubscriptions = options && options.metric$ ? Object.keys(options.metric$).map(metric =>
+        options!.metric$![metric].subscribe(next => trace.putMetric(metric, next))
+      ) : [];
+      const incrementOnSubscriptions = options && options.incrementMetric$ ? Object.keys(options.incrementMetric$).map(metric =>
+        options!.incrementMetric$![metric].subscribe(next => trace.incrementMetric(metric, next || undefined))
+      ) : [];
+      emitter.next(trace.start());
+      return { unsubscribe: () => {
+        trace.stop();
+        metricSubscriptions.forEach(m => m.unsubscribe());
+        incrementOnSubscriptions.forEach(m => m.unsubscribe());
+        attributeSubscriptions.forEach(m => m.unsubscribe());
+      }};
+    })
+  );
+
+  traceUntil = <T=any>(name:string, test: (a:T) => boolean, options?: TraceOptions) => (source$: Observable<T>) => {
+    const traceSubscription = this.trace$(name, options).subscribe();
+    return source$.pipe(
+      tap(a => { if (test(a)) { traceSubscription.unsubscribe() }})
+    )
+  };
+
+  traceWhile = <T=any>(name:string, test: (a:T) => boolean, options?: TraceOptions) => (source$: Observable<T>) => {
+    const traceSubscription = this.trace$(name, options).subscribe();
+    return source$.pipe(
+      tap(a => { if (!test(a)) { traceSubscription.unsubscribe() }})
+    )
+  };
+
+  traceUntilLast= <T=any>(name:string, options?: TraceOptions) => (source$: Observable<T>) => {
+    const traceSubscription = this.trace$(name, options).subscribe();
+    return source$.pipe(
+      tap(
+        () => {},
+        () => {},
+        () => traceSubscription.unsubscribe()
+      )
+    )
+  };
+
+  traceUntilFirst = <T=any>(name:string, options?: TraceOptions) => (source$: Observable<T>) => {
+    const traceSubscription = this.trace$(name, options).subscribe();
+    return source$.pipe(
+      tap(
+        () => traceSubscription.unsubscribe(),
+        () => {},
+        () => {}
+      )
+    )
+  };
+
+  trace = <T=any>(name:string, options?: TraceOptions) => (source$: Observable<T>) => {
+    const traceSubscription = this.trace$(name, options).subscribe();
+    return source$.pipe(
+      tap(
+        () => traceSubscription.unsubscribe(),
+        () => {},
+        () => traceSubscription.unsubscribe()
+      )
+    )
+  };
+
+}
diff --git a/src/performance/public_api.ts b/src/performance/public_api.ts
new file mode 100644
index 000000000..620865da9
--- /dev/null
+++ b/src/performance/public_api.ts
@@ -0,0 +1,2 @@
+export * from './performance';
+export * from './performance.module';
diff --git a/src/performance/test-config.ts b/src/performance/test-config.ts
new file mode 100644
index 000000000..e134426d4
--- /dev/null
+++ b/src/performance/test-config.ts
@@ -0,0 +1,10 @@
+
+export const COMMON_CONFIG = {
+  apiKey: "AIzaSyBVSy3YpkVGiKXbbxeK0qBnu3-MNZ9UIjA",
+  authDomain: "angularfire2-test.firebaseapp.com",
+  databaseURL: "https://angularfire2-test.firebaseio.com",
+  projectId: "angularfire2-test",
+  storageBucket: "angularfire2-test.appspot.com",
+  messagingSenderId: "920323787688",
+  appId: "1:920323787688:web:2253a0e5eb5b9a8b"
+};
diff --git a/src/performance/tsconfig-build.json b/src/performance/tsconfig-build.json
new file mode 100644
index 000000000..aa254cafe
--- /dev/null
+++ b/src/performance/tsconfig-build.json
@@ -0,0 +1,33 @@
+{
+  "compilerOptions": {
+    "baseUrl": ".",
+    "experimentalDecorators": true,
+    "emitDecoratorMetadata": true,
+    "module": "es2015",
+    "target": "es2015",
+    "noImplicitAny": false,
+    "outDir": "../../dist/packages-dist/performance/es2015",
+    "rootDir": ".",
+    "sourceMap": true,
+    "inlineSources": true,
+    "declaration": false,
+    "removeComments": true,
+    "strictNullChecks": true,
+    "lib": ["es2015", "dom", "es2015.promise", "es2015.collection", "es2015.iterable"],
+    "skipLibCheck": true,
+    "moduleResolution": "node",
+    "paths": {
+      "@angular/fire": ["../../dist/packages-dist"]
+    }
+  },
+  "files": [
+    "index.ts",
+    "../../node_modules/zone.js/dist/zone.js.d.ts"
+  ],
+  "angularCompilerOptions": {
+    "skipTemplateCodegen": true,
+    "strictMetadataEmit": true,
+    "enableSummariesForJit": false
+  }
+}
+
diff --git a/src/performance/tsconfig-esm.json b/src/performance/tsconfig-esm.json
new file mode 100644
index 000000000..4dd3842af
--- /dev/null
+++ b/src/performance/tsconfig-esm.json
@@ -0,0 +1,19 @@
+{
+  "extends": "./tsconfig-build.json",
+  "compilerOptions": {
+    "target": "es5",
+    "outDir": "../../dist/packages-dist/performance",
+    "declaration": true
+  },
+  "files": [
+    "public_api.ts",
+    "../../node_modules/zone.js/dist/zone.js.d.ts"
+  ],
+  "angularCompilerOptions": {
+    "skipTemplateCodegen": true,
+    "strictMetadataEmit": true,
+    "enableSummariesForJit": false,
+    "flatModuleOutFile": "index.js",
+    "flatModuleId": "@angular/fire/performance"
+  }    
+}
diff --git a/src/performance/tsconfig-test.json b/src/performance/tsconfig-test.json
new file mode 100644
index 000000000..f6ca2b3c2
--- /dev/null
+++ b/src/performance/tsconfig-test.json
@@ -0,0 +1,13 @@
+{
+  "extends": "./tsconfig-esm.json",
+  "compilerOptions": {
+    "baseUrl": ".",
+    "paths": {
+      "@angular/fire": ["../../dist/packages-dist"]
+    }
+  },
+  "files": [
+    "index.spec.ts",
+    "../../node_modules/zone.js/dist/zone.js.d.ts"
+  ]
+}
diff --git a/src/root.spec.js b/src/root.spec.js
index a44c7a68b..2819c3a0e 100644
--- a/src/root.spec.js
+++ b/src/root.spec.js
@@ -15,6 +15,7 @@ export * from './packages-dist/database/list/snapshot-changes.spec';
 export * from './packages-dist/database/list/state-changes.spec';
 export * from './packages-dist/database/list/audit-trail.spec';
 export * from './packages-dist/storage/storage.spec';
+export * from './packages-dist/performance/performance.spec';
 //export * from './packages-dist/messaging/messaging.spec';
 
 // // Since this a deprecated API, we run on it on manual tests only
diff --git a/src/tsconfig.json b/src/tsconfig.json
index 42b5cd977..6978e6669 100644
--- a/src/tsconfig.json
+++ b/src/tsconfig.json
@@ -18,6 +18,7 @@
       "@angular/fire/functions": ["./functions"],
       "@angular/fire/storage": ["./storage"],
       "@angular/fire/messaging": ["./messaging"],
+      "@angular/fire/performance": ["./performance"],
       "@angular/fire/database-deprecated": ["./database-deprecated"]
     },
     "rootDir": ".",
diff --git a/tools/build.js b/tools/build.js
index 41c8bfcc4..0fe66ccb9 100644
--- a/tools/build.js
+++ b/tools/build.js
@@ -27,6 +27,7 @@ const GLOBALS = {
   'firebase/messaging': 'firebase',
   'firebase/firestore': 'firebase',
   'firebase/functions': 'firebase',
+  'firebase/performance': 'firebase',
   'firebase/storage': 'firebase',
   '@angular/fire': 'angularfire2',
   '@angular/fire/auth': 'angularfire2.auth',
@@ -37,6 +38,7 @@ const GLOBALS = {
   '@angular/fire/functions': 'angularfire2.functions',
   '@angular/fire/storage': 'angularfire2.storage',
   '@angular/fire/messaging': 'angularfire2.messaging',
+  '@angular/fire/performance': 'angularfire2.performance',
   'fs': 'node.fs',
   'path': 'node.path',
   'inquirer': 'inquirer'
@@ -72,6 +74,7 @@ const MODULE_NAMES = {
   schematics: 'angularfire2.schematics',
   storage: 'angularfire2.storage',
   messaging: 'angularfire2.messaging',
+  performance: 'angularfire2.performance'
 };
 
 const ENTRIES = {
@@ -85,6 +88,7 @@ const ENTRIES = {
   schematics: `${process.cwd()}/dist/packages-dist/schematics/index.js`,
   storage: `${process.cwd()}/dist/packages-dist/storage/index.js`,
   messaging: `${process.cwd()}/dist/packages-dist/messaging/index.js`,
+  performance: `${process.cwd()}/dist/packages-dist/performance/index.js`
 };
 
 const SRC_PKG_PATHS = {
@@ -98,6 +102,7 @@ const SRC_PKG_PATHS = {
   functions: `${process.cwd()}/src/functions/package.json`,
   storage: `${process.cwd()}/src/storage/package.json`,
   messaging: `${process.cwd()}/src/messaging/package.json`,
+  performance: `${process.cwd()}/src/performance/package.json`
 };
 
 const DEST_PKG_PATHS = {
@@ -111,6 +116,7 @@ const DEST_PKG_PATHS = {
   functions: `${process.cwd()}/dist/packages-dist/functions/package.json`,
   storage: `${process.cwd()}/dist/packages-dist/storage/package.json`,
   messaging: `${process.cwd()}/dist/packages-dist/messaging/package.json`,
+  performance: `${process.cwd()}/dist/packages-dist/performance/package.json`
 };
 
 // Constants for running typescript commands
@@ -295,6 +301,7 @@ function getVersions() {
     getDestPackageFile('functions'),
     getDestPackageFile('storage'),
     getDestPackageFile('messaging'),
+    getDestPackageFile('performance'),
     getDestPackageFile('database-deprecated')
   ];
   return paths
@@ -336,6 +343,7 @@ function buildModules(globals) {
   const schematics$ = buildModule('schematics', globals);
   const storage$ = buildModule('storage', globals);
   const messaging$ = buildModule('messaging', globals);
+  const performance$ = buildModule('performance', globals);
   const dbdep$ = buildModule('database-deprecated', globals);
   return forkJoin(core$, from(copyRootTest())).pipe(
     switchMapTo(schematics$),
@@ -346,6 +354,7 @@ function buildModules(globals) {
     switchMapTo(functions$),
     switchMapTo(storage$),
     switchMapTo(messaging$),
+    switchMapTo(performance$),
     switchMapTo(dbdep$)
   );
 }
@@ -369,6 +378,7 @@ function buildLibrary(globals) {
       const functionsStats = measure('functions');
       const storageStats = measure('storage');
       const messagingStats = measure('messaging');
+      const performanceStats = measure('performance');
       const dbdepStats = measure('database-deprecated');
       console.log(`
 core.umd.js - ${coreStats.size}, ${coreStats.gzip}
@@ -379,6 +389,7 @@ firestore.umd.js - ${fsStats.size}, ${fsStats.gzip}
 functions.umd.js - ${functionsStats.size}, ${functionsStats.gzip}
 storage.umd.js - ${storageStats.size}, ${storageStats.gzip}
 messaging.umd.js - ${messagingStats.size}, ${messagingStats.gzip}
+performance.umd.js - ${performanceStats.size}, ${performanceStats.gzip}
 database-deprecated.umd.js - ${dbdepStats.size}, ${dbdepStats.gzip}
       `);
       verifyVersions();
diff --git a/yarn.lock b/yarn.lock
index 398dd46a5..010be29a0 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,7 +2,7 @@
 # yarn lockfile v1
 
 
-"@angular-devkit/architect@^0.800.0-rc.4":
+"@angular-devkit/architect@^0.800.0-rc.4 || >=8.0.0 <9 || 9.0.0-0":
   version "0.800.0-rc.4"
   resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.800.0-rc.4.tgz#ca0bb9b7b62663caf7bf76f8f0afb2ec5ac32db1"
   integrity sha512-R+LxKHuGKawzAtSBL7fQ9oYEQfzAEX5DNMvDVC1f+INmyA03vcTKPNf1JzgzetKAN4Y3rt4zpv4OSLiuhjvFwg==