Firebase Performance Monitoring for web

1. Overview

In this codelab, you'll learn how to use Firebase Performance Monitoring to measure the performance of a chat web app. Visit https://fireperf-friendlychat.web.app/ to see a live demo.

3b1284f5144b54f6.png

What you'll learn

  • How to add Firebase Performance Monitoring to your web app to get out-of-the-box metrics (page load and network requests).
  • How to measure a specific piece of code with custom traces.
  • How to record additional, custom metrics tied to a custom trace.
  • How to further segment your performance data with custom attributes.
  • How to use the performance monitoring dashboard to understand your web app's performance.

What you'll need

  • The IDE or text editor of your choice, such as WebStorm, Atom, Sublime, or VS Code
  • A terminal/console
  • A browser of your choice, such as Chrome
  • The codelab's sample code (See the next section of this codelab for how to get the code.)

2. Get the sample code

Clone the codelab's GitHub repository from the command line:

git clone https://github.com/firebase/codelab-friendlychat-web

Alternatively, if you do not have git installed, you can download the repo as a zip file.

Import the starter app

Using your IDE, open or import the 📁 performance-monitoring-start directory from the cloned repository. This 📁 performance-monitoring-start directory contains the starting code for the codelab, which is a chat web app.

3. Create and set up a Firebase project

Create a Firebase project

  1. In the Firebase console, click Add Project.
  2. Name your Firebase project FriendlyChat.

Remember the project ID for your Firebase project.

  1. Click Create Project.

Upgrade your Firebase pricing plan

To use Cloud Storage for Firebase, your Firebase project needs to be on the pay-as-you go (Blaze) pricing plan, which means it's linked to a Cloud Billing account.

  • A Cloud Billing account requires a payment method, like a credit card.
  • If you're new to Firebase and Google Cloud, check if you're eligible for a $300 credit and a Free Trial Cloud Billing account.
  • If you're doing this codelab as part of an event, ask your organizer if there are any Cloud credits available.

To upgrade your project to the Blaze plan, follow these steps:

  1. In the Firebase console, select to upgrade your plan.
  2. Select the Blaze plan. Follow the on-screen instructions to link a Cloud Billing account to your project.
    If you needed to create a Cloud Billing account as part of this upgrade, you might need to navigate back to the upgrade flow in the Firebase console to complete the upgrade.

Add a Firebase web app to the project

  1. Click the web icon 58d6543a156e56f9.pngto create a new Firebase web app.
  2. Register the app with the nickname Friendly Chat, and then check the box next to Also set up Firebase Hosting for this app.
  3. Click Register app.
  4. Click through the remaining steps. You don't need to follow the on-screen instructions now; these will be covered in later steps of this codelab.

ea9ab0db531a104c.png

Enable Google sign-in for Firebase authentication

To allow users to sign in to the chat app with their Google accounts, we'll use the Google sign-in method.

You'll need to enable Google sign-in:

  1. In the Firebase console, locate the Develop section in the left panel.
  2. Click Authentication, then click the Sign-in method tab ( go to console).
  3. Enable the Google sign-in provider, and then click Save.

7f3040a646c2e502.png

Set up Cloud Firestore

The web app uses Cloud Firestore to save chat messages and receive new chat messages.

Here's how to set up Cloud Firestore in your Firebase project:

  1. In the left-panel of the Firebase console, expand Build and then select Firestore database.
  2. Click Create database.
  3. Leave the Database ID set to (default).
  4. Select a location for your database, then click Next.
    For a real app, you want to choose a location that's close to your users.
  5. Click Start in test mode. Read the disclaimer about the security rules.
    Later in this codelab, you'll add Security Rules to secure your data. Do not distribute or expose an app publicly without adding Security Rules for your database.
  6. Click Create.

Set Up Cloud Storage for Firebase

The web app uses Cloud Storage for Firebase to store, upload, and share pictures.

Here's how to set up Cloud Storage for Firebase in your Firebase project:

  1. In the left-panel of the Firebase console, expand Build and then select Storage.
  2. Click Get started.
  3. Select a location for your default Storage bucket.
    Buckets in US-WEST1, US-CENTRAL1, and US-EAST1 can take advantage of the "Always Free" tier for Google Cloud Storage. Buckets in all other locations follow Google Cloud Storage pricing and usage.
  4. Click Start in test mode. Read the disclaimer about the security rules.
    Later in this codelab, you'll add security rules to secure your data. Do not distribute or expose an app publicly without adding Security Rules for your Storage bucket.
  5. Click Create.

4. Install the Firebase command-line interface

The Firebase command-line interface (CLI) allows you to use Firebase Hosting to serve your web app locally as well as to deploy your web app to your Firebase project.

  1. Install the CLI by following these instructions in the Firebase docs.
  2. Verify that the CLI has been installed correctly by running the following command in a terminal:
firebase --version

Make sure that your version of the Firebase CLI is v8.0.0 or later.

  1. Authorize the Firebase CLI by running the following command:
firebase login

We've set up the web app template to pull your app's configuration for Firebase Hosting from your app's local directory (the repository that you cloned earlier in the codelab). But to pull the configuration, we need to associate your app with your Firebase project.

  1. Make sure that your command line is accessing your app's local performance-monitoring-start directory.
  2. Associate your app with your Firebase project by running the following command:
firebase use --add
  1. When prompted, select your project ID, and then give your Firebase project an alias.

An alias is useful if you have multiple environments (production, staging, etc). However, for this codelab, let's just use the alias of default.

  1. Follow the remaining instructions in your command line.

5. Integrate with Firebase Performance Monitoring

There are various ways to integrate with the Firebase Performance Monitoring SDK for web (refer to the documentation for details). In this codelab, we'll enable performance monitoring from Hosting URLs.

Add performance monitoring and initialize Firebase

  1. Open the src/index.js file, then add the following line below the TODO to include the Firebase Performance Monitoring SDK.

index.js

// TODO: Import the Firebase Performance Monitoring library here.
 import {
   getPerformance,
   trace
 } from 'firebase/performance';
  1. We also need to initialize the Firebase SDK with a configuration object that contains information about the Firebase project and the web app we want to use. Since we're using Firebase Hosting, you can import a special script that will do this configuration for you. For this codelab, we've already added the following line for you at the bottom of the public/index.html file, but double-check that it is there.

index.html

<!-- This script is created by webpack -->
<script type="module" src="scripts/main.js"></script>
  1. In the src/index.js file, add the following line below the TODO to initialize performance monitoring.

index.js

// TODO: Initialize Firebase Performance Monitoring.
getPerformance();

Performance Monitoring will now automatically collect page load and network request metrics for you when users use your site! Refer to the documentation to learn more about automatic page load traces.

Add the first input delay polyfill library

First input delay is useful since the browser responding to a user interaction gives users their first impressions about the responsiveness of your app.

First input delay starts when the user first interacts with an element on the page, like clicking a button or hyperlink. It stops immediately after the browser is able to respond to the input, meaning that the browser isn't busy loading or parsing your content.

This polyfill library is optional for performance monitoring integration.

Open the public/index.html file, then uncomment the following line.

index.html

<!-- TODO: Enable First Input Delay polyfill library. -->
<script type="text/javascript">!function(n,e){var t,o,i,c=[],f={passive:!0,capture:!0},r=new Date,a="pointerup",u="pointercancel";function p(n,c){t||(t=c,o=n,i=new Date,w(e),s())}function s(){o>=0&&o<i-r&&(c.forEach(function(n){n(o,t)}),c=[])}function l(t){if(t.cancelable){var o=(t.timeStamp>1e12?new Date:performance.now())-t.timeStamp;"pointerdown"==t.type?function(t,o){function i(){p(t,o),r()}function c(){r()}function r(){e(a,i,f),e(u,c,f)}n(a,i,f),n(u,c,f)}(o,t):p(o,t)}}function w(n){["click","mousedown","keydown","touchstart","pointerdown"].forEach(function(e){n(e,l,f)})}w(n),self.perfMetrics=self.perfMetrics||{},self.perfMetrics.onFirstInputDelay=function(n){c.push(n),s()}}(addEventListener,removeEventListener);</script>

At this point, you've finished the integration with Firebase Performance Monitoring in your code!

In the following steps, you learn about adding custom traces using Firebase Performance Monitoring. If you only want to collect the automatic traces, go to the "Deploy and start sending images" section.

6. Add a custom trace to your app

Performance Monitoring allows you to create custom traces. A custom trace is a report for the duration of an execution block in your app. You define the start and end of a custom trace using the APIs provided by the SDK.

  1. In the src/index.js file, get a performance object, then create a custom trace for uploading an image message.

index.js

// TODO: Create custom trace to monitor image upload.
const t = trace(perf, "saveImageMessage");
  1. To record a custom trace, you need to specify the starting point and stopping point for the trace. You can think of a trace as a timer.

index.js

// TODO: Start the "timer" for the custom trace.
t.start();

 ...

    // TODO: Stop the "timer" for the custom trace.
    t.stop();

You have successfully defined a custom trace! After deploying your code, the duration of the custom trace will be recorded if a user sends an image message. This will give you an idea of how long it takes real-world users to send images in your chat app.

7. Add a custom metric to your app.

You can further configure a custom trace to record custom metrics for performance-related events that occur within its scope. For example, you can use a metric to investigate if the upload time is affected by the size of an image for the custom trace we defined in the last step.

  1. Locate the custom trace from the previous step (defined in your src/index.js file).
  2. Add the following line below the TODO to record the size of the uploaded image.

index.js

 ...

// TODO: Record image size.
t.putMetric('imageSize', file.size);

 ...

This metric enables performance monitoring to record the custom trace duration as well as the uploaded image size.

8. Add a custom attribute to your app

Building on the previous steps, you can also collect custom attributes on your custom traces. Custom attributes can help in segmenting data by categories specific to your app. For example, you can collect the image file's MIME type to investigate how the MIME type might affect the performance.

  1. Use the custom trace defined in your src/index.js file.
  2. Add the following line below the TODO to record the MIME type of the uploaded image.

index.js

 ...

// TODO: Record image MIME type.
t.putAttribute('imageType', file.type);

 ...

This attribute enables performance monitoring to categorize the custom trace duration based on uploaded image type.

9. [Extend] Add a custom trace with User Timing API

The Firebase Performance Monitoring SDK was designed so it could be loaded asynchronously, and so it wouldn't negatively impact the performance of web apps during page load. Before the SDK is loaded, the Firebase Performance Monitoring API is not available. In this scenario, you are still able to add custom traces by using the User Timing API. Firebase performance SDK will pick up the durations from measure() and log them as custom traces.

We are going to measure the duration of loading app styling scripts using User Timing API.

  1. In the public/index.html file, add the following line to mark the start of the app styling scripts load.

index.html

<!-- TODO: Mark the starting of `timer` for loading App Styling script. -->
<script type="text/javascript">performance && performance.mark('loadStylingStart');</script>
  1. Add the following lines to mark the end of the app styling scripts load, and to measure the duration between start and end.

index.html

<!-- TODO: Mark the ending of `timer` for loading App Styling script. Measure the duration from start to end. -->
<script type="text/javascript">
  performance && performance.mark('loadStylingEnd');
  performance && performance.measure('loadStyling', 'loadStylingStart', 'loadStylingEnd');
</script>

The entry you have created here will be automatically collected by Firebase Performance Monitoring. You will be able to find a custom trace called loadStyling in the Firebase Performance console later.

10. Deploy and start sending images

Deploy to Firebase Hosting

After adding Firebase Performance Monitoring to your code, follow these steps to deploy your code to Firebase Hosting:

  1. Make sure that your command line is accessing your app's local performance-monitoring-start directory.
  2. Deploy your files to your Firebase project by running the following command:
firebase deploy
  1. The console should display the following:
=== Deploying to 'friendlychat-1234'...

i  deploying firestore, storage, hosting
i  storage: checking storage.rules for compilation errors...
  storage: rules file storage.rules compiled successfully
i  firestore: checking firestore.rules for compilation errors...
  firestore: rules file firestore.rules compiled successfully
i  storage: uploading rules storage.rules...
i  firestore: uploading rules firestore.rules...
i  hosting[friendlychat-1234]: beginning deploy...
i  hosting[friendlychat-1234]: found 8 files in ./public
  hosting[friendlychat-1234]: file upload complete
  storage: released rules storage.rules to firebase.storage/friendlychat-1234.firebasestorage.app
  firestore: released rules firestore.rules to cloud.firestore
i  hosting[friendlychat-1234]: finalizing version...
  hosting[friendlychat-1234]: version finalized
i  hosting[friendlychat-1234]: releasing new version...
  hosting[friendlychat-1234]: release complete

  Deploy complete!

Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview
Hosting URL: https://friendlychat-1234.firebaseapp.com
  1. Visit your web app that's now fully hosted using Firebase Hosting at two of your very own Firebase subdomains: https://<projectId>.firebaseapp.com and https://<projectId>.web.app.

Verify that performance monitoring is enabled

Open Firebase console and go to the Performance tab. If you see a welcome message showing "SDK detected", then you have successfully integrated with Firebase Performance Monitoring!

30df67e5a07d03b0.png

Send image message

Generate some performance data by sending images in your chat app.

  1. After signing in to your chat app, click the image upload button 13734cb66773e5a3.png.
  2. Select an image file using the file picker.
  3. Try sending multiple images (a few samples are stored in public/images/) so that you can test the distribution of custom metrics and custom attributes.

New messages should display in the app's UI along with your selected images.

11. Monitor the dashboard

After deploying your web app and sending image messages as a user, you can review performance data in the performance monitoring dashboard (in the Firebase console).

Access your dashboard

  1. In the Firebase console, select the project that has your Friendly Chat app.
  2. In the left panel, locate the Quality section, and click Performance.

Review on-device data

After performance monitoring has processed your app's data, you'll see tabs along the top of the dashboard. Make sure to check back later if you don't see any data or tabs yet.

  1. Click the On device tab.
  • The Page loads table shows the various performance metrics that performance monitoring automatically collects while your page is loading.
  • The Durations table shows any custom traces that you've defined in your app's code.
  1. Click saveImageMessage in the Durations table to review specific metrics for the trace.

e28758fd02d9ffac.png

  1. Click Aggregate to review the distribution of image sizes. You can see the metric you added to measure the image size for this custom trace.

c3cbcfc0c739a0a8.png

  1. Click Over time which is next to Aggregate in the previous step. You can also view the Duration of the custom trace. Click View more to review the collected data in more detail.

16983baa31e05732.png

  1. In the page which opens, you can segment the duration data by image MIME type by clicking imageType. This specific data was logged because of the imageType attribute you added to your custom trace.

8e5c9f32f42a1ca1.png

Review network data

An HTTP/S network request is a report that captures the response time and payload size of network calls.

  1. Go back to the main screen of the performance monitoring dashboard.
  2. Click the Network tab to see a list of network request entries for your web app.
  3. Browse through them to identify slow requests and start working on a fix to improve your app's performance!

26a2be152a77ffb9.png

12. Congratulations!

You have enabled the Firebase SDK for performance monitoring and collected automatic traces and custom traces to measure the real-world performance of your chat app!

What we've covered:

  • Adding the Firebase Performance Monitoring SDK to your web app.
  • Adding custom traces to your code.
  • Recording custom metrics tied to the custom trace.
  • Segmenting performance data using custom attributes.
  • Understanding how to use the performance monitoring dashboard to gain insights into your app's performance.

Learn more: