Skip to content

Commit

Permalink
Add performance relayer + documentation (web-vitals) (#9116)
Browse files Browse the repository at this point in the history
Co-authored-by: Brody McKee <mrmckeb@users.noreply.github.com>
Co-authored-by: Ian Schmitz <ianschmitz@gmail.com>
  • Loading branch information
3 people committed Jun 11, 2020
1 parent a2dac9e commit 8fda779
Show file tree
Hide file tree
Showing 10 changed files with 114 additions and 5 deletions.
65 changes: 65 additions & 0 deletions docusaurus/docs/measuring-performance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
id: measuring-performance
title: Measuring Performance
---

By default, Create React App includes a performance relayer that allows you to measure and analyze
the performance of your application using different metrics.

To measure any of the supported metrics, you only need to pass a function into the `reportWebVitals`
function in `index.js`:

```js
reportWebVitals(console.log);
```

This function is fired when the final values for any of the metrics have finished calculating on the
page. You can use it to log any of the results to the console or send to a particular endpoint.

## Web Vitals

[Web Vitals](https://web.dev/vitals/) are a set of useful metrics that aim to capture the user
experience of a web page. In Create React App, a third-party library is used to measure these
metrics ([web-vitals](https://github.com/GoogleChrome/web-vitals)).

To understand more about the object returned to the function when a metric value is calculated,
refer to the [documentation](https://github.com/GoogleChrome/web-vitals/#types). The [Browser
Support](https://github.com/GoogleChrome/web-vitals/#browser-support) section also explains which browsers are supported.

## Sending results to analytics

With the `reportWebVitals` function, you can send any of results to an analytics endpoint to measure and track real user performance on your site. For example:

```js
function sendToAnalytics(metric) {
const body = JSON.stringify(metric);

This comment has been minimized.

Copy link
@ioslh

ioslh May 28, 2021

JSON.stringify(metric) may throw Converting circular structure to JSON error (getLCP, see attached screenshot below), consider add try-catch wrapper to it?

image

const url = 'https://example.com/analytics';

// Use `navigator.sendBeacon()` if available, falling back to `fetch()`
if (navigator.sendBeacon) {
navigator.sendBeacon(url, body);
} else {
fetch(url, { body, method: 'POST', keepalive: true });
}
}

reportWebVitals(sendToAnalytics);
```

> **Note:** If you use Google Analytics, use the `id` value to make it easier to construct metric distributions manually (to calculate percentiles, etc…).
>
> ```js
> function sendToAnalytics({id, name, value}) {
> ga('send', 'event', {
> eventCategory: 'Web Vitals',
> eventAction: name,
> eventValue: Math.round(name === 'CLS' ? value * 1000 : value), // values must be integers
> eventLabel: id, // id unique to current page load
> nonInteraction: true, // avoids affecting bounce rate
> });
> }
>
> reportWebVitals(sendToAnalytics);
> ```
>
> Read more about sending results to Google Analytics [here](https://github.com/GoogleChrome/web-vitals#send-the-results-to-google-analytics).
1 change: 1 addition & 0 deletions docusaurus/website/sidebars.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"adding-a-router",
"adding-custom-environment-variables",
"making-a-progressive-web-app",
"measuring-performance",
"production-build"
],
"Testing": ["running-tests", "debugging-tests"],
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
"strip-ansi": "^6.0.0",
"svg-term-cli": "^2.1.1",
"tempy": "^0.2.1",
"wait-for-localhost": "^3.1.0"
"wait-for-localhost": "^3.1.0",
"web-vitals": "^0.2.2"
},
"husky": {
"hooks": {
Expand Down
3 changes: 2 additions & 1 deletion packages/cra-template-typescript/template.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"@types/react": "^16.9.0",
"@types/react-dom": "^16.9.0",
"@types/jest": "^25.0.0",
"typescript": "^3.8.0"
"typescript": "^3.8.0",
"web-vitals": "^0.2.2"
}
}
}
6 changes: 6 additions & 0 deletions packages/cra-template-typescript/template/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import reportWebVitals from './reportWebVitals';

ReactDOM.render(
<React.StrictMode>
Expand All @@ -15,3 +16,8 @@ ReactDOM.render(
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://cra.link/PWA
serviceWorker.unregister();

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
15 changes: 15 additions & 0 deletions packages/cra-template-typescript/template/src/reportWebVitals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ReportHandler } from 'web-vitals';

const reportWebVitals = (onPerfEntry?: ReportHandler) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
}

export default reportWebVitals;
3 changes: 2 additions & 1 deletion packages/cra-template/template.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"dependencies": {
"@testing-library/jest-dom": "^5.9.0",
"@testing-library/react": "^10.2.1",
"@testing-library/user-event": "^11.3.2"
"@testing-library/user-event": "^11.3.2",
"web-vitals": "^0.2.2"
}
}
}
6 changes: 6 additions & 0 deletions packages/cra-template/template/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import reportWebVitals from './reportWebVitals';

ReactDOM.render(
<React.StrictMode>
Expand All @@ -15,3 +16,8 @@ ReactDOM.render(
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://cra.link/PWA
serviceWorker.unregister();

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
13 changes: 13 additions & 0 deletions packages/cra-template/template/src/reportWebVitals.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const reportWebVitals = (onPerfEntry) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
}

export default reportWebVitals;
4 changes: 2 additions & 2 deletions tasks/e2e-installs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ function exists {
# Check for accidental dependencies in package.json
function checkDependencies {
if ! awk '/"dependencies": {/{y=1;next}/},/{y=0; next}y' package.json | \
grep -v -q -E '^\s*"(@testing-library\/.+)|(react(-dom|-scripts)?)"'; then
grep -v -q -E '^\s*"(@testing-library\/.+)|web-vitals|(react(-dom|-scripts)?)"'; then
echo "Dependencies are correct"
else
echo "There are extraneous dependencies in package.json"
Expand All @@ -62,7 +62,7 @@ function checkDependencies {
# Check for accidental dependencies in package.json
function checkTypeScriptDependencies {
if ! awk '/"dependencies": {/{y=1;next}/},/{y=0; next}y' package.json | \
grep -v -q -E '^\s*"(@testing-library\/.+)|(@types\/.+)|typescript|(react(-dom|-scripts)?)"'; then
grep -v -q -E '^\s*"(@testing-library\/.+)|web-vitals|(@types\/.+)|typescript|(react(-dom|-scripts)?)"'; then
echo "Dependencies are correct"
else
echo "There are extraneous dependencies in package.json"
Expand Down

0 comments on commit 8fda779

Please sign in to comment.