Skip to content

Commit

Permalink
Add an Example for Using startTrackPage and stopTrackPage to Measure …
Browse files Browse the repository at this point in the history
…Duration in an SPA (#104)
  • Loading branch information
siyuniu-ms authored Jul 25, 2024
1 parent 8a90f7c commit bd85877
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 11 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ Please note that it can take up to 10 minutes for new custom metric to appear in

[Azure-Samples/application-insights-react-demo](https://github.com/Azure-Samples/application-insights-react-demo).

### Example of Measuring Page Duration in an SPA
Measuring the duration for a Single Page Application (SPA) can be challenging when the URL does not change. Therefore, we recommend using [startTrackPage](https://microsoft.github.io/ApplicationInsights-JS/webSdk/applicationinsights-analytics-js/classes/AnalyticsPlugin.html#startTrackPage) and [stopTrackPage](https://microsoft.github.io/ApplicationInsights-JS/webSdk/applicationinsights-analytics-js/classes/AnalyticsPlugin.html#stopTrackPage) for accurate duration calculation.

You can find an example in our sample app. After running the app, visit http://localhost:3000/test to see it in action.

## React Router

[react-router]: https://github.com/ReactTraining/react-router/blob/master/FAQ.md#how-do-i-access-the-history-object-outside-of-components
Expand Down
81 changes: 70 additions & 11 deletions sample/applicationinsights-react-sample/src/TestPage.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,87 @@
import React from 'react';
import {SeverityLevel} from '@microsoft/applicationinsights-web';
import { appInsights} from './ApplicationInsightsService';
import React, { useState, useEffect, useRef } from 'react';
import { SeverityLevel } from '@microsoft/applicationinsights-web';
import { appInsights } from './ApplicationInsightsService';
import './App.css';


function TestPage() {
const [time, setTime] = useState(0);
const [isRunning, setIsRunning] = useState(false);
const timerRef = useRef<NodeJS.Timeout | null>(null);
const startTimeRef = useRef<number | null>(null);

function trackException() {
appInsights.trackException({ error: new Error('some error'), severityLevel: SeverityLevel.Error });
}

function trackTrace() {
appInsights.trackTrace({ message: 'some trace', severityLevel: SeverityLevel.Information });
appInsights.trackTrace({ message: 'some trace', severityLevel: SeverityLevel.Information });
}

function trackEvent() {
appInsights.trackEvent({ name: 'some event' });
appInsights.trackEvent({ name: 'some event' });
}

function flush() {
appInsights.flush();
}

function startTrackPageView() {
appInsights.startTrackPage("TestPage");
startClock();
}

function stopTrackPageView() {
appInsights.stopTrackPage("TestPage");
stopClock();
}

function throwError() {
throw new Error("test error");
throw new Error("test error");
}

function ajaxRequest() {
let xhr = new XMLHttpRequest();
xhr.open('GET', 'https://httpbin.org/status/200');
xhr.send();
let xhr = new XMLHttpRequest();
xhr.open('GET', 'https://httpbin.org/status/200');
xhr.send();
}

function fetchRequest() {
fetch('https://httpbin.org/status/200');
fetch('https://httpbin.org/status/200');
}

const startClock = () => {
if (!isRunning) {
setIsRunning(true);
startTimeRef.current = Date.now();
timerRef.current = setInterval(() => {
if (startTimeRef.current !== null) {
setTime(Date.now() - startTimeRef.current);
}
}, 100);
}
};

const stopClock = () => {
if (isRunning && timerRef.current !== null) {
clearInterval(timerRef.current);
setIsRunning(false);
}
};

const resetClock = () => {
setTime(0);
}

useEffect(() => {
return () => {
if (timerRef.current !== null) {
clearInterval(timerRef.current);
}
};
}, []);



return (
<div className="App">
<h1>Test Page</h1>
Expand Down Expand Up @@ -67,6 +113,19 @@ function TestPage() {
<div>Test track Throw Error</div>
<button onClick={throwError}>Autocollect an Error</button>
</div>
<div>
<div>Start Track Page View</div>
<button onClick={startTrackPageView}>Start Track Page View</button>
</div>
<div>
<div>Stop Track Page View</div>
<button onClick={stopTrackPageView}>Stop Track Page View</button>
</div>
<div>
<div>Clock</div>
<h1>Time: {(time / 1000).toFixed(3)}s</h1>
<button onClick={resetClock}>Reset clock</button>
</div>
</div>
)
}
Expand Down

0 comments on commit bd85877

Please sign in to comment.