Real-user monitoring (RUM) is the performance industry's way to measure real user traffic. SpeedCurve's RUM product is called LUX. If you're not currently a LUX customer, you can follow the simple LUX Getting Started Guide to start a free trial.
Using LUX in a typical separate-page website is pretty easy because each page view has a well-defined start and end (navigationStart and loadEventEnd). There's a little more work involved to make LUX work in a single-page application (SPA) because the definition of a "page view" varies depending on the SPA's implementation.
There are three main LUX APIs involved in making LUX work with your SPA:
LUX.init - Call this function at the beginning of the SPA page transition (but not on the initial page load). For example, if the user clicked a button that causes a SPA transition, you would call LUX.init immediately after the button is clicked.
LUX.send - Call this function at the end of the SPA page transition. For example, you would call LUX.send after all JSON responses have been received and the DOM has been updated.
LUX.auto - This variable tells LUX whether to gather the initial performance metrics as part of window.onload. The default is true and that value works in most cases for SPAs. But in some cases even the initial page view is handled by the SPA code and can occur after window.onload. If this is the case for your site, you would set LUX.auto to false and make sure to call LUX.send when that initial page view is complete.
Using page labels in a SPA
In a SPA, page labels can be set at any point before LUX.send is called.
Using customer data in a SPA
Customer data can be added at any point in a SPA, and it will be associated with the current page view. Customer data values are persisted across all SPA page views.
Using custom metrics (user timing marks & measures) in a SPA
For the initial page load, user timing marks and measures in a SPA work the same as they do in a regular web application. For subsequent SPA pages, measures continue to work the same but marks are taken relative to the previous LUX.init call.