From 1fe34a3400294a6aff36a95c339bd6fb977ffff5 Mon Sep 17 00:00:00 2001 From: Chunwai Li Date: Tue, 16 Sep 2025 14:41:35 -0500 Subject: [PATCH 1/5] Reflect SPA changes --- .../browser-apis/createtracer.mdx | 2 +- .../new-relic-browser/browser-apis/end.mdx | 2 +- .../new-relic-browser/browser-apis/ignore.mdx | 2 +- .../browser-apis/interaction.mdx | 63 ++++++++++++++--- .../new-relic-browser/browser-apis/save.mdx | 4 +- .../get-started/browser-spa-v2.mdx | 14 +++- ...ntroduction-single-page-app-monitoring.mdx | 17 ++--- .../use-spa-data/spa-data-collection.mdx | 67 ++++++++----------- .../use-spa-data/view-spa-data-browser-ui.mdx | 3 +- .../manage-data/manage-data-retention.mdx | 2 +- .../events-reported-browser-monitoring.mdx | 8 +-- src/nav/browser.yml | 6 +- 12 files changed, 117 insertions(+), 73 deletions(-) diff --git a/src/content/docs/browser/new-relic-browser/browser-apis/createtracer.mdx b/src/content/docs/browser/new-relic-browser/browser-apis/createtracer.mdx index 817bb7493d8..4a4289de835 100644 --- a/src/content/docs/browser/new-relic-browser/browser-apis/createtracer.mdx +++ b/src/content/docs/browser/new-relic-browser/browser-apis/createtracer.mdx @@ -17,7 +17,7 @@ freshnessValidatedDate: never --- - The `createTracer` method in the SPA API has been deprecated. The recommended way to trace the duration of a task is to capture a performance [mark](https://developer.mozilla.org/en-US/docs/Web/API/Performance/mark) and/or [measure](https://developer.mozilla.org/en-US/docs/Web/API/Performance/measure). Future browser agent versions will capture marks and measures automatically, at which point support for `createTracer` will cease. + The `createTracer` method in the SPA API has been deprecated. The recommended way to trace the duration of a task is to capture a performance [mark](https://developer.mozilla.org/en-US/docs/Web/API/Performance/mark) and/or [measure](https://developer.mozilla.org/en-US/docs/Web/API/Performance/measure) for measuring callback execution time. In SPA v2+, this method has become a dummy method that no longer work to tie JS execution to interactions or keep them open--it effectively does nothing! ## Syntax diff --git a/src/content/docs/browser/new-relic-browser/browser-apis/end.mdx b/src/content/docs/browser/new-relic-browser/browser-apis/end.mdx index a811cd80955..0028d8e99f5 100644 --- a/src/content/docs/browser/new-relic-browser/browser-apis/end.mdx +++ b/src/content/docs/browser/new-relic-browser/browser-apis/end.mdx @@ -45,7 +45,7 @@ Ends the SPA interaction at the current time. ## Description -This SPA method will end the browser interaction at the current time. Any subsequent callbacks or requests will not be included as part of the SPA interaction. +This SPA method will end the browser interaction at the current time. Any subsequent network requests that start after this method is called will not be included as part of the current SPA interaction. In SPA v2.1+, this can also be used to terminate an interaction in a pending state that's monitoring for any long task in a 5s window. ## Return values diff --git a/src/content/docs/browser/new-relic-browser/browser-apis/ignore.mdx b/src/content/docs/browser/new-relic-browser/browser-apis/ignore.mdx index 74e9b6b7377..4a6c7d63152 100644 --- a/src/content/docs/browser/new-relic-browser/browser-apis/ignore.mdx +++ b/src/content/docs/browser/new-relic-browser/browser-apis/ignore.mdx @@ -57,7 +57,7 @@ This method returns the same API object created by `interaction()`. ```js router.addRoute('/uninteresting-route', () => { newrelic.interaction() // Get handle to current interaction. - .ignore(); // Ignore this interaction to ensure it will not be saved. + .ignore(); // Ignore this interaction to ensure it will not be saved, even if it has fulfilled the default heuristic that makes it valid. renderUninterestingRoute(); // Render route. }); ``` diff --git a/src/content/docs/browser/new-relic-browser/browser-apis/interaction.mdx b/src/content/docs/browser/new-relic-browser/browser-apis/interaction.mdx index a49d4d447ea..3535746838b 100644 --- a/src/content/docs/browser/new-relic-browser/browser-apis/interaction.mdx +++ b/src/content/docs/browser/new-relic-browser/browser-apis/interaction.mdx @@ -19,14 +19,15 @@ freshnessValidatedDate: never ## Syntax ```js -newrelic.interaction() +newrelic.interaction([JSON object $options]) ``` -Returns a new API object that is bound to the current SPA interaction. +Returns a new handle object that is bound to the current SPA interaction, or a new interaction if one does not exist. ## Requirements * Browser Pro+SPA agent (v963 or higher) +* The `$options` parameter requires v1.285.0+ * If you're using npm to install the browser agent, you must enable the `spa` feature when instantiating the `BrowserAgent` class. In the `features` array, add the following: ```js @@ -46,26 +47,68 @@ Returns a new API object that is bound to the current SPA interaction. ## Description -The [SPA monitoring](/docs/browser/single-page-app-monitoring/get-started/introduction-single-page-app-monitoring) `interaction()` call returns a new API object that is bound to the current interaction. +The [SPA monitoring](/docs/browser/single-page-app-monitoring/get-started/introduction-single-page-app-monitoring) `interaction()` call returns a new handle that is bound to the current interaction. -* **New interaction:** If the API calls it when New Relic is not currently monitoring an interaction, a new interaction is created. -* **New object:** If the API calls it again within the same interaction, a new object referencing the current interaction is created. +* **New interaction:** If this function is called and no interaction is open or in-progress, then a new [custom](/docs/browser/single-page-app-monitoring/use-spa-data/spa-data-collection#api-custom-events) interaction is created. + * A custom interaction will still follow the default heuristic and close automatically on the next complete soft navigation, _unless_ `waitForEnd` is specified. +* **New object:** If this function is called while an interaction is ongoing, a new handle referencing the current interaction is created. + * Multiple handles can point to the same interaction. Each `.interaction` call creates a new handle. + * The handle will point to the open interaction, whether it began from an user event like a `click` or from a previous api-triggered `.interaction` call. + * This function cannot replace its own effect or that of an user event. That is, it cannot overwrite any existing open interaction with a new api-driven interaction. ## Parameters -The parameters depend on the specific SPA interaction API call. + + + + + + + + + + + + + +
+ Parameter + + Description +
+ `$options` + + _JSON object_ + + Optional. Specified options that affects the behavior of the interaction. Optional properties: + + * `waitForEnd` - If `true`, the interaction is forcibly kept open until the `.end` method is called on its handle. Defaults to `false`. Once an interaction is earmarked with this, it cannot be undone. +
## Return values -This method returns an API object that is bound to a specific [`BrowserInteraction` event](/docs/insights/explore-data/attributes/browser-default-attributes-insights#browserinteraction-attributes). Each time this method is called for the same `BrowserInteraction`, a new object is created, but it still references the same interaction. +This method returns an native JS object that points to a potential [`BrowserInteraction` event](/docs/insights/explore-data/attributes/browser-default-attributes-insights#browserinteraction-attributes). Each time this method is called for the same `BrowserInteraction` while it has not yet ended, a new object is created, but it still references the same interaction. ## Examples -SPA API methods can be used on `newrelic.interaction()`. The methods can also be used on a handle you assign with a variable. For example: +SPA API methods can/must be used on `newrelic.interaction()`. You can assign the returned value or handle to another variable for later use. For example: ```js -myInteraction = newrelic.interaction(); +let myInteraction = newrelic.interaction(); +... myInteraction.save(); ``` -The named handle can be saved and used from outside an interaction, but methods will have no effect after the interaction has ended. +While the named handle can be saved and used from outside an interaction, note that SPA methods will have no effect after the interaction has ended. + +Interaction duration can also be customized using this method: + +```js +// Say an interaction is already open from a user click. +const userInteraction = newrelic.interaction({ waitForEnd: true }); // grabs the current interaction in-progress & keep it open +// URL changes & DOM is modified. Because of those condition being met, interaction will be saved but is kept open. +fetch('myurl.com/endpoint').then(() => userInteraction.end()) // associate this request to the interaction before completing this BrowserInteraction + +const myCustomIxn = newrelic.interaction({ waitForEnd: true }) // create a new api-triggered interaction +// This interaction will be kept open indefinitely until `.end` is called, and no new interaction will start, custom or otherwise. AjaxRequest will continue to buffer under this interaction until it is closed. +``` \ No newline at end of file diff --git a/src/content/docs/browser/new-relic-browser/browser-apis/save.mdx b/src/content/docs/browser/new-relic-browser/browser-apis/save.mdx index 805a4e660ac..94d73c43e9a 100644 --- a/src/content/docs/browser/new-relic-browser/browser-apis/save.mdx +++ b/src/content/docs/browser/new-relic-browser/browser-apis/save.mdx @@ -46,7 +46,7 @@ Ensures a SPA browser interaction will be saved when it ends. ## Description -This SPA method ensures a browser interaction will be saved when it ends. Normally an interaction is only saved and sent to New Relic if it is an initial page load or if it results in a URL or hash change. You must call this method to override this behavior and guarantee the interaction will be recorded. +This SPA method ensures a browser interaction will be saved when it ends. Normally an interaction is only saved and sent to New Relic if it is the initial page load or if it is a route change subject to the [default heuristic](/docs/browser/single-page-app-monitoring/use-spa-data/spa-data-collection#browser-interaction). You must call this method to override this behavior and guarantee the interaction will be recorded. ## Return values @@ -59,7 +59,7 @@ window.addEventListener('scroll', () => { if (atBottomOfPage()) { newrelic.interaction() // Start monitoring this interaction. .setName('loadNextPage') // Set name of interaction. - .save(); // Ensure that this interaction will be saved as a BrowserInteraction event when it ends. + .save(); // Ensure that this interaction will be saved as a BrowserInteraction event when it ends, even if URL change and DOM modification did not occur. loadNextPage(); // Start loading the next page. } }); diff --git a/src/content/docs/browser/single-page-app-monitoring/get-started/browser-spa-v2.mdx b/src/content/docs/browser/single-page-app-monitoring/get-started/browser-spa-v2.mdx index 01bfc2d66dd..82e46460bed 100644 --- a/src/content/docs/browser/single-page-app-monitoring/get-started/browser-spa-v2.mdx +++ b/src/content/docs/browser/single-page-app-monitoring/get-started/browser-spa-v2.mdx @@ -1,13 +1,23 @@ --- -title: Browser SPA monitoring 2.0 +title: Browser SPA monitoring 2.1 metaDescription: "The new browser SPA monitoring capability is a streamlined way to monitor your users' experience and app performance." freshnessValidatedDate: 2024-09-04 --- - This feature is in public preview. It will eventually replace the existing browser SPA experience. + This feature is deploying (slowly) via feature flag, with an eventual goal of replacing the existing browser SPA experience by default. (There is no option to select which new SPA version you get. You'll always simply receive the latest.) +## SPA 2.1 + +Long task consideration is introduced as a replacement for old SPA's extensive callback tracking and to somewhat backfill the `jsDuration`, `timeToSettle` and `timeToLastCallbackEnd` attributes of AjaxRequest event(s) associated with a BrowserInteraction. + +For _select_ native browser objects wrapped by the agent's `nrWrapper`, their callbacks will be timed. Those over 50ms in duration (long task) can extend a BrowserInteraction. In 2.0, the feature followed a soft navigation heuristic to determine when an interaction occurred naturally. Now, the interaction will additionally wait and extend its duration until a period of no long task for 5 seconds, and its end time will be re-adjusted accordingly. + +In 2.0, AjaxRequest associated with interactions did not report or track any callback timing, so the aforementioned 3 attributes were nullified. Now, `XMLHttpRequest` (but not `fetch`) that is part of an interaction and has event listeners which result in long tasks will have those 3 attributes set to reflect long callbacks. + +## SPA 2.0 + For customers monitoring browser single page applications (SPA), we're excited to announce an overhaul of our SPA monitoring functionality, meant to address numerous pain points: * Unusable latest versions: Frequent conflicts with third-party libraries and unreliable interaction capture plagued the existing agent, often rendering the latest version unusable. diff --git a/src/content/docs/browser/single-page-app-monitoring/get-started/introduction-single-page-app-monitoring.mdx b/src/content/docs/browser/single-page-app-monitoring/get-started/introduction-single-page-app-monitoring.mdx index d0c9ff54eab..492107e260e 100644 --- a/src/content/docs/browser/single-page-app-monitoring/get-started/introduction-single-page-app-monitoring.mdx +++ b/src/content/docs/browser/single-page-app-monitoring/get-started/introduction-single-page-app-monitoring.mdx @@ -13,11 +13,11 @@ redirects: freshnessValidatedDate: never --- -New Relic offers single-page application (SPA) monitoring to give you deeper visibility and actionable insights into real user interactions with single-page apps or any app that uses AJAX requests. +New Relic offers single-page application (SPA) monitoring to give you deeper visibility and actionable insights into real user interactions with single-page apps. -In addition to monitoring route changes automatically, our SPA API allows you to monitor virtually anything that executes inside the browser. Developers and their teams can use the API to: +The SPA feature monitors [soft navigations](https://developer.chrome.com/docs/web-platform/soft-navigations-experiment#what_is_a_soft_navigation) automatically, and our SPA API allows you to modify the interactions. Developers and their teams can use the API to: -* Create faster, more responsive, highly interactive apps. +* Track user journeys through URL paths on their SPA. * Monitor the throughput and performance that real users are experiencing. * Troubleshoot and resolve problems within the context of the page load. * [Query your data](/docs/using-new-relic/data/understand-data/query-new-relic-data) to assist with business decisions. @@ -33,7 +33,7 @@ For compatibility information about SPA-related features, see [SPA requirements] ## Analyze throughput and performance data [#spa-data] -Improving on traditional industry standards for measuring page load timing, we give you a complete picture of the activity, both synchronous and asynchronous, associated with page loads and route changes. +`BrowserInteraction` events drives the UI page views tab whenever SPA is enabled. Both the initial page load (hard nav) and route changes (soft navs) are shown. - When a user initiates a page load or route change, New Relic begins to monitor all subsequent JavaScript, and ends the timing once all AJAX events are complete. This provides a more accurate view of when a page is actually ready for a user compared to the traditional method of ending the timing when the window load event is fired. + When a user initiates an interaction event, New Relic tracks the time until the url path changes and the next frame is repainted. When SPA monitoring is enabled, the [**Page views** page](/docs/browser/single-page-app-monitoring/browser-ui/view-spa-data-new-relic-browser) in browser shows event-driven data about application usage levels (throughput) and user experience (performance), including: @@ -100,7 +99,9 @@ Here is a summary of SPA monitoring features: - [Metrics and events](/docs/query-your-data/explore-query-data/data-explorer/introduction-data-explorer) supports three SPA-specific event types: [`BrowserInteraction`](/docs/insights/new-relic-insights/decorating-events/browser-default-attributes-insights#browserinteraction-attributes), [`AjaxRequest`](/docs/insights/new-relic-insights/decorating-events/browser-default-attributes-insights#ajaxrequest-attributes), and [`BrowserTiming`](/docs/insights/insights-data-sources/default-events-attributes/browser-default-events-attributes-insights#browsertiming-attributes). You can query these events in the [query builder](/docs/query-your-data/explore-query-data/query-builder/use-advanced-nrql-mode-specify-data) to analyze your app's performance and make business decisions. + [Metrics and events](/docs/query-your-data/explore-query-data/data-explorer/introduction-data-explorer) supports two SPA-specific event types: [`BrowserInteraction`](/docs/insights/new-relic-insights/decorating-events/browser-default-attributes-insights#browserinteraction-attributes) and [`AjaxRequest`](/docs/insights/new-relic-insights/decorating-events/browser-default-attributes-insights#ajaxrequest-attributes), which may be associated with the former when using the SPA agent. You can query these events in the [query builder](/docs/query-your-data/explore-query-data/query-builder/use-advanced-nrql-mode-specify-data) to analyze your app's performance and make business decisions. + + Previously, [`BrowserTiming`](/docs/insights/insights-data-sources/default-events-attributes/browser-default-events-attributes-insights#browsertiming-attributes) also existed but is now deprecated. @@ -110,7 +111,7 @@ Here is a summary of SPA monitoring features: - Use [SPA API](/docs/browser/new-relic-browser/browser-agent-spa-api) to obtain the specific data you need, such as custom naming, custom timing, `finishline` API, or other custom attributes. + Use [SPA API](/docs/browser/new-relic-browser/browser-agent-spa-api) to obtain the specific data you need, such as custom naming, custom timing, or other custom attributes. diff --git a/src/content/docs/browser/single-page-app-monitoring/use-spa-data/spa-data-collection.mdx b/src/content/docs/browser/single-page-app-monitoring/use-spa-data/spa-data-collection.mdx index 1532534b30d..4404bf4d6b2 100644 --- a/src/content/docs/browser/single-page-app-monitoring/use-spa-data/spa-data-collection.mdx +++ b/src/content/docs/browser/single-page-app-monitoring/use-spa-data/spa-data-collection.mdx @@ -15,78 +15,69 @@ redirects: - /docs/browser/single-page-app-monitoring/use-spa-data/understand-collection-asynchronous-spa-data freshnessValidatedDate: never --- - This document explains how browser collects and stores your asynchronous single page app (SPA) data. This will give you a better understanding of the [SPA data you see in the browser UI](/docs/browser/single-page-app-monitoring/browser-ui/view-spa-data-new-relic-browser). This will also help you more easily add custom monitoring with the [SPA API](/docs/browser/single-page-app-monitoring/use-spa-data/use-spa-api). ## Browser interactions [#browser-interaction] -At the heart of SPA monitoring is the concept of the **browser interaction**. New Relic defines a browser interaction as anything that occurs in the app user's browser; for example: +At the heart of SPA monitoring is the concept of the **browser interaction**. New Relic defines a browser interaction, otherwise called a soft navigation, as the following sequence of events, drawing from [Google's heuristics](https://github.com/WICG/soft-navigations?tab=readme-ov-file#heuristics): -* A user interaction that leads to a page load or route change -* A scheduled, dynamic update to an app's widget +1. An user interaction occurs. We look specifically for `click`, `keydown` or `submit` events. The `popstate` event from the History API will also start an interaction. +2. The URL changes in any way, whether it's the path or hash. +3. Any changes, including to node attributes or text, occurs anywhere on the document DOM tree. -A browser interaction includes not just the initial triggering event, but also the activity caused by that event, such as AJAX requests and both synchronous and asynchronous JavaScript. By tracking not just the cause but also the effects of a browser interaction, we help you understand how users experience your application's views and route changes. +Following these steps, browser interactions are considered finished on the next repaint frame. They will also associate XHR and fetch requests started within their span. v2.1 introduced another step: -All apps are different and have different monitoring needs. That's why we include default monitoring as well as the ability to set up custom monitoring for any browser interactions you choose. +4. Monitor for long running callbacks for a period of 5 seconds. If any are detected, extend the interaction and repeat. -## Types of SPA data reporting [#spa-data] +In this way, interactions will fully end when there's a silent period for long tasks. For extensions, any AjaxRequest and JavascriptError that occurred during the period up to the end of the observed long task will also become associated with the interaction. The duration of the interaction will not include those last 5 seconds. Step 4 may also be short-circuited or bypassed in some cases. + + + The `popstate` event trigger is handled in a special way compared to the other UI event triggers because of its peculiarity in the browser. In short, a `popstate` that occurs within 500 ms after an other UI event like click will be merged into that existing interaction, whose trigger remains unchanged (e.g. 'click'). However, two back-to-back popstates will never be merged this way. Popstate-as-trigger interactions typically come from browser actions (back/forward button) and code (programmatic change to URL). + -Three major categories of single page app data can be reported to New Relic: +## Types of SPA data reporting [#spa-data] -* Initial page loads -* Route changes -* Custom browser interactions created via the [SPA API](/docs/browser/single-page-app-monitoring/use-spa-data/use-spa-api) +@@ -39,54 +38,39 @@ Three major categories of single page app data can be reported to New Relic: Each of these creates a `BrowserInteraction` event. If one or more AJAX requests are part of an interaction, then associated `AjaxRequest` events are also created. These events and their attributes can be queried in the [query builder](/docs/query-your-data/explore-query-data/query-builder/use-advanced-nrql-mode-specify-data). + + Default or non-custom interactions do not wait for network requests to finish or load. They are tied to interactions on an as-is basis, meaning only if they are done before the interaction is harvested by the scheduler. It is entirely possible for slow or long duration requests that started as part of an interaction to miss this time window. Manually holding the interaction open until any cared-about request has return is possible through the API. + + ## Initial page loads -An **initial page load** is a traditional URL change, stemming from a complete load or reload of a URL. This is indicated in the browser when a page load event fires (the `window.onload` event). Initial page loads appear along with route changes in [the browser UI](/docs/browser/single-page-app-monitoring/browser-ui/view-spa-data-new-relic-browser). +An **initial page load** is a traditional URL change, stemming from a complete load or reload of a URL. This is indicated in the browser when a page load event fires (the `window.onload` event) and also called a hard navigation. Initial page loads appear along with route changes in [the browser UI](/docs/browser/single-page-app-monitoring/browser-ui/view-spa-data-new-relic-browser). ## Route changes SPA users experience dynamic route changes in a similar way to page loads. Visitors to a site or app generally do not care **how** a new view was delivered; they simply know that when they perform an action, a new view appears. For this reason, we treat route changes in a similar way to page loads in the UI. -In order to optimally monitor single page applications, we start monitoring many browser interactions that could theoretically lead to route changes. +In order to optimally monitor single page applications, we start monitoring any interaction that could theoretically lead to route changes. -* If these interactions do **not** lead to route changes, browser initiates monitoring but then discards them. -* If these interactions **do** lead to a route change, browser saves the interaction sequence as a `BrowserInteraction` event, including information about both synchronous and asynchronous activity. +* If these interactions do **not** complete the heuristic steps defined above, agent initiates monitoring but then discards them. +* If these interactions **do** follow all steps, agent saves the sequence as a completed `BrowserInteraction` event. -An interaction is considered a route change and saved as a `BrowserInteraction` event when one of the following occurs: +An interaction is considered a route change and saved as a `BrowserInteraction` event if the URL changes between the start and end. URL changes are tracked in two ways: -* The URL hash changes (usually using `window.location.hash`). -* A `popstate` event fires during a callback associated with an interaction. -* A `pushState` or `replaceState` API is called. +* The `popstate` event. Changing the url programmatically, such as setting `window.location.hash` will trigger this event. +* `pushState` or `replaceState` is called. SPAs commonly use these History API methods to update the URL. Route changes appear along with initial page loads in the [browser UI](/docs/browser/single-page-app-monitoring/browser-ui/view-spa-data-new-relic-browser). -We receive and save hash fragments from route change URLs. If you use hashes to pass private or sensitive data, that data may be visible to your New Relic account users. For more information about data collection and reporting, see [Security for browser](/docs/browser/new-relic-browser/performance-quality/security-new-relic-browser). +Note that the agent reports hash fragments from route change URLs. If you use hashes to pass private or sensitive data, that data may be visible to your New Relic account users. For more information about data collection and reporting, see [Security for browser](/docs/browser/new-relic-browser/performance-quality/security-new-relic-browser). ## Custom monitoring [#api-custom-events] -You can use the [SPA API](/docs/browser/new-relic-browser/browser-agent-spa-api) to set up custom monitoring of browser interactions that are not monitored by default. You can also use the API to disable default monitoring. +All apps are different and have different monitoring needs. You can use the [SPA API](/docs/browser/new-relic-browser/browser-agent-spa-api) to customize your browser interactions or self define the way it's captured. -Custom events are saved as `BrowserInteraction` events and have the following attributes: +Custom events are saved as `BrowserInteraction` events and have the following difference in attributes: * The `category` attribute will have the value `Custom`. * The `trigger` attribute will have the value `api`. (This is the default value but can be changed with the API.) -## Difference from traditional page load timing [#page-load-timing-diff] - -To provide optimized data for single page app monitoring, we measure page load timing in a new way: by wrapping low level browser functions, both synchronous and asynchronous. This gives a fuller depiction of how long it takes to complete the changes required for a new view. - -This is different from the traditional method for page load timing. [Traditional page load timing](/docs/browser/new-relic-browser/page-load-timing-resources/page-load-timing-process) uses the firing of the `window.onload` event to determine when a page is loaded. This is not an optimal way to measure view change timing because web apps often have asynchronous code that runs for a significant amount of time after the `window.onload` event occurs. - - - Browser's standard, non-SPA **Page views** page displays different page load times than when SPA monitoring is enabled. Because SPA monitoring is measuring all asynchronous activity, the SPA load times will generally be longer than standard page load times. - - -The traditional `window.onload` page load timing still appears on the SPA **Page views** page. When you select a specific page load event, **Window onload** appears as a red line in the page load time chart. You can also select **Switch to standard page views** to return to traditional load timing displays. - -## Timers [#spa-timers] - -The agent monitors all asynchronous calls, including timers. Timers with durations shorter than one second are wrapped. Timers longer than one second are not wrapped because usually they are meant for [non-web transactions](/docs/apm/transactions/intro-transactions/monitor-background-processes-other-non-web-transactions), such as background work or polling that is unrelated to a user interaction. +The API allows you to dictate when to start such custom interaction and when to end it, if the above heuristic does not fit your user base or app. ## Events and attributes [#event-data-structure] -We save browser interactions that lead to route changes and page loads as `BrowserInteraction` events, and AJAX requests as `AjaxRequest` events. You can query these events in the [query builder](/docs/query-your-data/explore-query-data/query-builder/use-advanced-nrql-mode-specify-data). +We save browser interactions that lead to route changes and page loads, or are created through API, as `BrowserInteraction` events, and AJAX requests as `AjaxRequest` events. You can query these events in the [query builder](/docs/query-your-data/explore-query-data/query-builder/use-advanced-nrql-mode-specify-data). diff --git a/src/content/docs/browser/single-page-app-monitoring/use-spa-data/view-spa-data-browser-ui.mdx b/src/content/docs/browser/single-page-app-monitoring/use-spa-data/view-spa-data-browser-ui.mdx index b40f54abae8..e4bbab9346f 100644 --- a/src/content/docs/browser/single-page-app-monitoring/use-spa-data/view-spa-data-browser-ui.mdx +++ b/src/content/docs/browser/single-page-app-monitoring/use-spa-data/view-spa-data-browser-ui.mdx @@ -111,6 +111,7 @@ Here are details on the specific performance data displayed for both page loads * **JS Duration** is the sum of all JavaScript execution time during the interaction, which is synchronous by definition. * The remaining time is called **Waiting time** and is derived by subtracting JS duration from the total duration. + * For SPA v2.1+, JS duration only @@ -146,7 +147,7 @@ The **Historical performance** and **Breakdown** details a - The **Breakdowns** tab lists the various components individually timed as part of an [interaction](/docs/browser/single-page-app-monitoring/understand-spa-data-structure#browser-interactions). By default, all XHRs are captured and timed. You can also use the [SPA API](/docs/browser/new-relic-browser/browser-agent-spa-api) to include additional elements for a route change or page load. + The **Breakdowns** tab lists the various components individually timed as part of an [interaction](/docs/browser/single-page-app-monitoring/understand-spa-data-structure#browser-interactions). XHRs that _started_ within the span of a `BrowserInteraction` is timed and listed here. diff --git a/src/content/docs/data-apis/manage-data/manage-data-retention.mdx b/src/content/docs/data-apis/manage-data/manage-data-retention.mdx index 85bb91c7668..9502c8699fe 100644 --- a/src/content/docs/data-apis/manage-data/manage-data-retention.mdx +++ b/src/content/docs/data-apis/manage-data/manage-data-retention.mdx @@ -611,7 +611,7 @@ In this section are details about a few different types of data, including some All browser namespaces have the same default retention period. Here are details about the events in each browser namespace: * `Browser` namespace: `PageView`, `PageAction` - * `Browser events` namespace: `AjaxRequest`, `BrowserInteraction`, `BrowserTiming` + * `Browser events` namespace: `AjaxRequest`, `BrowserInteraction`, `BrowserTiming (deprecated)` * `Browser JS errors` namespace: `JavaScriptError` * `Browser page view timing` namespace: `PageViewTiming` diff --git a/src/content/docs/data-apis/understand-data/event-data/events-reported-browser-monitoring.mdx b/src/content/docs/data-apis/understand-data/event-data/events-reported-browser-monitoring.mdx index e5af264bf9f..cac009108db 100644 --- a/src/content/docs/data-apis/understand-data/event-data/events-reported-browser-monitoring.mdx +++ b/src/content/docs/data-apis/understand-data/event-data/events-reported-browser-monitoring.mdx @@ -67,11 +67,11 @@ Select an event name in the following table to see its attributes. - [`BrowserInteraction` (SPA)](/attribute-dictionary/?event=BrowserInteraction) + [`BrowserInteraction`](/attribute-dictionary/?event=BrowserInteraction) - `BrowserInteraction` contains several PageView attributes as well as attributes that are specific to single-page apps (SPA) + `BrowserInteraction` contains several PageView attributes as well as attributes that are specific to single-page apps (SPA). @@ -87,11 +87,11 @@ Select an event name in the following table to see its attributes. - [`BrowserTiming` (SPA)](/attribute-dictionary/?event=BrowserTiming) + [`BrowserTiming` (deprecated)](/attribute-dictionary/?event=BrowserTiming) - `BrowserTiming` is a custom event that captures SPA timing data for browser interactions started using the custom [createTracer](/docs/browser/new-relic-browser/browser-agent-spa-api/createtracer-browser-spa-api) SPA API method. `BrowserTiming` contains many of the same attributes used by other events, especially `AjaxRequest`. (deprecated) + `BrowserTiming` is a custom event that captures SPA timing data for browser interactions started using the custom [createTracer](/docs/browser/new-relic-browser/browser-agent-spa-api/createtracer-browser-spa-api) SPA API method. `BrowserTiming` contains many of the same attributes used by other events, especially `AjaxRequest`. *That method is no longer used as part of SPA v2+, so it and this custom event are deprecated and should not be used.* diff --git a/src/nav/browser.yml b/src/nav/browser.yml index 32336c47dc2..63f65535ae2 100644 --- a/src/nav/browser.yml +++ b/src/nav/browser.yml @@ -130,15 +130,13 @@ pages: pages: - title: Introduction to SPA monitoring path: /docs/browser/single-page-app-monitoring/get-started/introduction-single-page-app-monitoring - - title: Install SPA monitoring - path: /docs/browser/single-page-app-monitoring/get-started/install-single-page-app-monitoring - title: Browser SPA monitoring 2.0 label: Preview path: /docs/browser/single-page-app-monitoring/get-started/browser-spa-v2 + - title: Install SPA monitoring + path: /docs/browser/single-page-app-monitoring/get-started/install-single-page-app-monitoring - title: View SPA data in Browser UI path: /docs/browser/single-page-app-monitoring/use-spa-data/view-spa-data-browser-ui - - title: SPA monitoring features - path: /docs/browser/new-relic-browser/browser-pro-features/spa-monitoring - title: SPA data collection path: /docs/browser/single-page-app-monitoring/use-spa-data/spa-data-collection - title: Query SPA data From 961fef4c015fddee38cd0a46b595745c9ef27796 Mon Sep 17 00:00:00 2001 From: Chunwai Li Date: Mon, 29 Sep 2025 10:42:37 -0500 Subject: [PATCH 2/5] Update src/content/docs/browser/new-relic-browser/browser-apis/interaction.mdx Co-authored-by: sujitnewrelic --- .../docs/browser/new-relic-browser/browser-apis/interaction.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/browser/new-relic-browser/browser-apis/interaction.mdx b/src/content/docs/browser/new-relic-browser/browser-apis/interaction.mdx index 3535746838b..b8e679f7cf1 100644 --- a/src/content/docs/browser/new-relic-browser/browser-apis/interaction.mdx +++ b/src/content/docs/browser/new-relic-browser/browser-apis/interaction.mdx @@ -77,7 +77,7 @@ The [SPA monitoring](/docs/browser/single-page-app-monitoring/get-started/introd _JSON object_ - Optional. Specified options that affects the behavior of the interaction. Optional properties: + Optional: Specifies options that affect the behavior of the interaction. * `waitForEnd` - If `true`, the interaction is forcibly kept open until the `.end` method is called on its handle. Defaults to `false`. Once an interaction is earmarked with this, it cannot be undone. From af3b0b29caf80341108f0535dfd5d4dff3e6bca3 Mon Sep 17 00:00:00 2001 From: Chunwai Li Date: Mon, 29 Sep 2025 10:43:33 -0500 Subject: [PATCH 3/5] Update src/content/docs/browser/new-relic-browser/browser-apis/interaction.mdx Co-authored-by: sujitnewrelic --- .../docs/browser/new-relic-browser/browser-apis/interaction.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/browser/new-relic-browser/browser-apis/interaction.mdx b/src/content/docs/browser/new-relic-browser/browser-apis/interaction.mdx index b8e679f7cf1..337567e43d1 100644 --- a/src/content/docs/browser/new-relic-browser/browser-apis/interaction.mdx +++ b/src/content/docs/browser/new-relic-browser/browser-apis/interaction.mdx @@ -79,7 +79,7 @@ The [SPA monitoring](/docs/browser/single-page-app-monitoring/get-started/introd Optional: Specifies options that affect the behavior of the interaction. - * `waitForEnd` - If `true`, the interaction is forcibly kept open until the `.end` method is called on its handle. Defaults to `false`. Once an interaction is earmarked with this, it cannot be undone. + * `waitForEnd` - Default is `false`. To forcibly keep the interaction open until the `.end` method is called on its handle, set it to `true`. After an interaction is earmarked with this, it cannot be undone. From 1ae07b5092c302f5347ed33e59fbb57364d76c09 Mon Sep 17 00:00:00 2001 From: Chunwai Li Date: Mon, 29 Sep 2025 11:52:20 -0500 Subject: [PATCH 4/5] Apply suggestions from code review Co-authored-by: sujitnewrelic --- .../new-relic-browser/browser-apis/interaction.mdx | 4 ++-- .../get-started/browser-spa-v2.mdx | 7 ++++--- .../use-spa-data/spa-data-collection.mdx | 14 ++++++++++---- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/content/docs/browser/new-relic-browser/browser-apis/interaction.mdx b/src/content/docs/browser/new-relic-browser/browser-apis/interaction.mdx index 337567e43d1..a13b3e97c25 100644 --- a/src/content/docs/browser/new-relic-browser/browser-apis/interaction.mdx +++ b/src/content/docs/browser/new-relic-browser/browser-apis/interaction.mdx @@ -91,7 +91,7 @@ This method returns an native JS object that points to a potential [`BrowserInte ## Examples -SPA API methods can/must be used on `newrelic.interaction()`. You can assign the returned value or handle to another variable for later use. For example: +SPA API methods must be used on `newrelic.interaction()`. You can assign the returned value or handle to another variable for later use. For example: ```js let myInteraction = newrelic.interaction(); @@ -101,7 +101,7 @@ myInteraction.save(); While the named handle can be saved and used from outside an interaction, note that SPA methods will have no effect after the interaction has ended. -Interaction duration can also be customized using this method: +Interaction duration can also be customized using the following method: ```js // Say an interaction is already open from a user click. diff --git a/src/content/docs/browser/single-page-app-monitoring/get-started/browser-spa-v2.mdx b/src/content/docs/browser/single-page-app-monitoring/get-started/browser-spa-v2.mdx index 82e46460bed..8b03f637842 100644 --- a/src/content/docs/browser/single-page-app-monitoring/get-started/browser-spa-v2.mdx +++ b/src/content/docs/browser/single-page-app-monitoring/get-started/browser-spa-v2.mdx @@ -5,16 +5,17 @@ freshnessValidatedDate: 2024-09-04 --- - This feature is deploying (slowly) via feature flag, with an eventual goal of replacing the existing browser SPA experience by default. (There is no option to select which new SPA version you get. You'll always simply receive the latest.) + We’re rolling out this feature in phases using a feature flag to replace the existing browser SPA experience by default. There won’t be an option to choose which new SPA version you receive; you’ll always get the latest version automatically. + ## SPA 2.1 -Long task consideration is introduced as a replacement for old SPA's extensive callback tracking and to somewhat backfill the `jsDuration`, `timeToSettle` and `timeToLastCallbackEnd` attributes of AjaxRequest event(s) associated with a BrowserInteraction. +Long task consideration has been introduced to replace the extensive callback tracking used in older Single Page Applications (SPA). It also serves to backfill `jsDuration`, `timeToSettle` and `timeToLastCallbackEnd` attributes of AjaxRequest event(s) associated with a BrowserInteraction. For _select_ native browser objects wrapped by the agent's `nrWrapper`, their callbacks will be timed. Those over 50ms in duration (long task) can extend a BrowserInteraction. In 2.0, the feature followed a soft navigation heuristic to determine when an interaction occurred naturally. Now, the interaction will additionally wait and extend its duration until a period of no long task for 5 seconds, and its end time will be re-adjusted accordingly. -In 2.0, AjaxRequest associated with interactions did not report or track any callback timing, so the aforementioned 3 attributes were nullified. Now, `XMLHttpRequest` (but not `fetch`) that is part of an interaction and has event listeners which result in long tasks will have those 3 attributes set to reflect long callbacks. +Previously, in version 2.0, AjaxRequest associated with interactions did not report or track callback timing, resulting in nullified values for the three attributes mentioned above. With the current update, `XMLHttpRequest` (but not `fetch`) that is part of an interaction and includes event listeners causing long tasks will have `jsDuration`, `timeToSettle`, and `timeToLastCallbackEnd` attributes updated to reflect the timing of long callbacks. ## SPA 2.0 diff --git a/src/content/docs/browser/single-page-app-monitoring/use-spa-data/spa-data-collection.mdx b/src/content/docs/browser/single-page-app-monitoring/use-spa-data/spa-data-collection.mdx index 4404bf4d6b2..74859bedc9e 100644 --- a/src/content/docs/browser/single-page-app-monitoring/use-spa-data/spa-data-collection.mdx +++ b/src/content/docs/browser/single-page-app-monitoring/use-spa-data/spa-data-collection.mdx @@ -29,10 +29,14 @@ Following these steps, browser interactions are considered finished on the next 4. Monitor for long running callbacks for a period of 5 seconds. If any are detected, extend the interaction and repeat. -In this way, interactions will fully end when there's a silent period for long tasks. For extensions, any AjaxRequest and JavascriptError that occurred during the period up to the end of the observed long task will also become associated with the interaction. The duration of the interaction will not include those last 5 seconds. Step 4 may also be short-circuited or bypassed in some cases. +Interactions will fully conclude when there is a 5-second period without any long tasks. During the extension period leading up to the end of the last observed long task, any AjaxRequest and JavascriptError that occur will also be associated with the interaction. Importantly, the duration of the interaction will not include the final 5 seconds of inactivity. + +Note that step four may be short-circuited or bypassed in certain scenarios. - The `popstate` event trigger is handled in a special way compared to the other UI event triggers because of its peculiarity in the browser. In short, a `popstate` that occurs within 500 ms after an other UI event like click will be merged into that existing interaction, whose trigger remains unchanged (e.g. 'click'). However, two back-to-back popstates will never be merged this way. Popstate-as-trigger interactions typically come from browser actions (back/forward button) and code (programmatic change to URL). +The `popstate` event trigger is managed uniquely compared to other UI event triggers due to its specific behavior in browsers. When a `popstate` event occurs within 500 milliseconds after another UI event like a click, it will be merged into the existing interaction initiated by that event, without changing the interaction's original trigger (e.g., 'click'). However, two consecutive `popstate` events will never be merged in this manner. + +Interactions with `popstate` as their trigger typically originate from browser actions, such as using the back or forward button, or from code-related actions like programmatically changing the URL. ## Types of SPA data reporting [#spa-data] @@ -42,7 +46,9 @@ In this way, interactions will fully end when there's a silent period for long t Each of these creates a `BrowserInteraction` event. If one or more AJAX requests are part of an interaction, then associated `AjaxRequest` events are also created. These events and their attributes can be queried in the [query builder](/docs/query-your-data/explore-query-data/query-builder/use-advanced-nrql-mode-specify-data). - Default or non-custom interactions do not wait for network requests to finish or load. They are tied to interactions on an as-is basis, meaning only if they are done before the interaction is harvested by the scheduler. It is entirely possible for slow or long duration requests that started as part of an interaction to miss this time window. Manually holding the interaction open until any cared-about request has return is possible through the API. +Default or non-custom interactions do not wait for network requests to complete. They are associated with interactions on an as-is basis, meaning that only requests completed before the interaction is harvested by the scheduler are tied to it. If a network request has a slow or long duration and starts as part of an interaction, it may fall outside this time window and not be associated with the interaction. + +Alternatively, you can manually extend the duration of an interaction to ensure it remains open until any important network request returns by using the API. ## Initial page loads @@ -76,7 +82,7 @@ Custom events are saved as `BrowserInteraction` events and have the following di * The `category` attribute will have the value `Custom`. * The `trigger` attribute will have the value `api`. (This is the default value but can be changed with the API.) -The API allows you to dictate when to start such custom interaction and when to end it, if the above heuristic does not fit your user base or app. +The API allows you to dictate when to start and stop such custom interaction, if the above heuristic does not fit your user base or app. ## Events and attributes [#event-data-structure] From 04f5ff770216eca3f475f473b04cee285d9a4803 Mon Sep 17 00:00:00 2001 From: PallaviWrite Date: Fri, 3 Oct 2025 20:07:42 +0530 Subject: [PATCH 5/5] updated suggested changes --- .../browser/new-relic-browser/browser-apis/createtracer.mdx | 2 +- src/content/docs/browser/new-relic-browser/browser-apis/end.mdx | 2 +- .../use-spa-data/spa-data-collection.mdx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/docs/browser/new-relic-browser/browser-apis/createtracer.mdx b/src/content/docs/browser/new-relic-browser/browser-apis/createtracer.mdx index 4a4289de835..535e2784747 100644 --- a/src/content/docs/browser/new-relic-browser/browser-apis/createtracer.mdx +++ b/src/content/docs/browser/new-relic-browser/browser-apis/createtracer.mdx @@ -17,7 +17,7 @@ freshnessValidatedDate: never --- - The `createTracer` method in the SPA API has been deprecated. The recommended way to trace the duration of a task is to capture a performance [mark](https://developer.mozilla.org/en-US/docs/Web/API/Performance/mark) and/or [measure](https://developer.mozilla.org/en-US/docs/Web/API/Performance/measure) for measuring callback execution time. In SPA v2+, this method has become a dummy method that no longer work to tie JS execution to interactions or keep them open--it effectively does nothing! + The `createTracer` method in the SPA API has been deprecated. The recommended way to trace the duration of a task is now to use performance [marks](https://developer.mozilla.org/en-US/docs/Web/API/Performance/mark) and/or [measures](https://developer.mozilla.org/en-US/docs/Web/API/Performance/measure) for measuring callback execution time. This method is now inactive and no longer functions to link JavaScript execution with interactions or keep them open. ## Syntax diff --git a/src/content/docs/browser/new-relic-browser/browser-apis/end.mdx b/src/content/docs/browser/new-relic-browser/browser-apis/end.mdx index 0028d8e99f5..95039fcdf72 100644 --- a/src/content/docs/browser/new-relic-browser/browser-apis/end.mdx +++ b/src/content/docs/browser/new-relic-browser/browser-apis/end.mdx @@ -45,7 +45,7 @@ Ends the SPA interaction at the current time. ## Description -This SPA method will end the browser interaction at the current time. Any subsequent network requests that start after this method is called will not be included as part of the current SPA interaction. In SPA v2.1+, this can also be used to terminate an interaction in a pending state that's monitoring for any long task in a 5s window. +This SPA method will end the browser interaction at the current time. Any subsequent network requests that begin after this method is called will not be included as part of the current SPA interaction. In SPA v2.1 and later, this method can also be used to terminate an interaction in a pending state that monitors for any long task in a 5-second window. ## Return values diff --git a/src/content/docs/browser/single-page-app-monitoring/use-spa-data/spa-data-collection.mdx b/src/content/docs/browser/single-page-app-monitoring/use-spa-data/spa-data-collection.mdx index 74859bedc9e..6d016c9b5d2 100644 --- a/src/content/docs/browser/single-page-app-monitoring/use-spa-data/spa-data-collection.mdx +++ b/src/content/docs/browser/single-page-app-monitoring/use-spa-data/spa-data-collection.mdx @@ -27,7 +27,7 @@ At the heart of SPA monitoring is the concept of the **browser interaction* Following these steps, browser interactions are considered finished on the next repaint frame. They will also associate XHR and fetch requests started within their span. v2.1 introduced another step: -4. Monitor for long running callbacks for a period of 5 seconds. If any are detected, extend the interaction and repeat. +4. For SPA version 2.1 and later, the monitor checks for long-running callbacks for a maximum of 5 seconds. If a long-running callback is identified, the system extends the current interaction and reruns the monitor. Interactions will fully conclude when there is a 5-second period without any long tasks. During the extension period leading up to the end of the last observed long task, any AjaxRequest and JavascriptError that occur will also be associated with the interaction. Importantly, the duration of the interaction will not include the final 5 seconds of inactivity.