### Measure Single Page App User Action (HTML, JavaScript) Source: https://support.speedcurve.com/docs/custom-metrics This example measures a specific user action within a Single Page Application (SPA), such as clicking an 'Update' button. It uses performance marks to define the start and end of the action, and performance.measure to calculate the duration, providing a more accurate metric than window.onload for SPAs. ```html ``` -------------------------------- ### Utilize Built-in Script Variables Source: https://support.speedcurve.com/docs/synthetic-scripting-guide Examples of using dynamic variables such as %URL%, %HOST%, %ORIGIN%, and %TEST_ID% to parameterize test scripts based on site settings and test execution context. ```text // URL being tested is https://speedcurve.com navigate %URL% // URL being tested is https://speedcurve.com setDnsName %HOST% dns.example // URL being tested is https://speedcurve.com/blog setCookie %ORIGIN% foo=bar // URL being tested is https://speedcurve.com setHeader Foo: Bar %HOST_REGEX% // URL being tested is https://redirect.speedcurve.com setDnsName %HOSTR% dns.example // URL being tested is https://speedcurve.com navigate %URL%/?tag=%TEST_ID% ``` -------------------------------- ### HTML Example: Using data-sctrack for Interaction Naming Source: https://support.speedcurve.com/docs/rum-js-api This HTML snippet demonstrates the usage of the `data-sctrack` attribute to define custom interaction names for various elements. It shows how the attribute on an element or its ancestors influences the interaction name captured by SpeedCurve RUM. ```html
``` -------------------------------- ### LUX.init() Source: https://support.speedcurve.com/docs/rum-js-api Initializes a new page view, primarily used for tracking Single Page Application (SPA) transitions. ```APIDOC ## POST LUX.init() ### Description Call this function at the beginning of an SPA page transition to start tracking a new page view. ### Parameters None ``` -------------------------------- ### Get Session ID with LUX.getSessionId() Source: https://support.speedcurve.com/docs/rum-js-api Returns the current session identifier as a string. This ID can be used to correlate SpeedCurve RUM data with other analytics platforms, such as Google Analytics. ```javascript const sessionId = LUX.getSessionId(); gtag("set", { session_id: sessionId }); ``` -------------------------------- ### Measure Hero Image Render Time with Custom Metrics (HTML, JavaScript) Source: https://support.speedcurve.com/docs/custom-metrics This snippet demonstrates how to measure the render time of a hero image using custom performance marks. It captures the greater of the image's onload event mark and an inline script mark, providing an accurate render time even when image downloads are slow or blocked by other resources. ```html
```
--------------------------------
### Simulate user navigation and interactions with SpeedCurve scripts
Source: https://support.speedcurve.com/docs/user-flows
These scripts demonstrate how to control data logging, navigate between pages, and trigger UI interactions using the 'exec' and 'execAndWait' commands. They are designed to isolate performance metrics to specific parts of a user flow.
```SpeedCurve Script
// Turn data logging off
logData 0
// Navigate to the start page
navigate https://speedcurve.com/blog/
// Clear screen for accurate visual metrics
exec document.body.style.display = 'none'
// Turn data logging back on
logData 1
// Trigger navigation
execAndWait document.querySelector('.post-title a').click()
```
```SpeedCurve Script
// Turn data logging off
logData 0
// Navigate to product page
navigate https://shop.speedcurve.com/products/1234
// Add to cart and navigate
exec document.querySelector('.add-to-cart').click()
navigate https://shop.speedcurve.com/cart
// Proceed to checkout
exec document.querySelector('.checkout-as-guest').click()
// Turn data logging back on
logData 1
// Submit checkout
execAndWait document.querySelector('.checkout-submit').click()
```
```SpeedCurve Script
// Turn data logging off
logData 0
// Navigate to start page
navigate https://speedcurve.com/blog/
// Turn data logging back on
logData 1
// Load next page via Ajax
execAndWait document.querySelector('.next-page').click();
```
--------------------------------
### HTML Element Timing Attribute Example
Source: https://support.speedcurve.com/docs/using-element-timing
This snippet shows how to apply the `elementtiming` attribute to an HTML element. This attribute is crucial for the Element Timing API to identify and monitor specific DOM elements for rendering.
```html
```
--------------------------------
### Enable Back-Forward Cache Tracking with LUX.js
Source: https://support.speedcurve.com/docs/rum-js-api
Enables tracking of pages restored from the back-forward cache (bfcache) by initializing a new page view on restore. Recommended to use with LUX.sendBeaconOnPageHidden or a lower LUX.maxMeasureTime. This feature is experimental and may decrease metric values.
```javascript
LUX = window.LUX || {};
LUX.newBeaconOnPageShow = true;
```
--------------------------------
### Get Debug Data with LUX.getDebug()
Source: https://support.speedcurve.com/docs/rum-js-api
Retrieves encoded debug data for the current session. Use the RUM Debug Parser to interpret the data. This is useful for troubleshooting RUM implementation. The output can be copied directly to the browser console.
```javascript
LUX.getDebug()
// Copy the debug logs to the clipboard
copy(LUX.getDebug())
```
--------------------------------
### Troubleshoot RUM with LUX API
Source: https://support.speedcurve.com/docs/rum-snippet
Use these JavaScript functions in the browser console to verify RUM status and override sampling settings. LUX.getDebug() provides diagnostic logs, while LUX.forceSample() ensures the current session is captured for testing.
```javascript
/* Check debug logs for beacon status and sampling info */
LUX.getDebug();
/* Force the current session to be sampled for testing */
LUX.forceSample();
/* Manually trigger a beacon send if LUX.auto is false */
LUX.send();
```
--------------------------------
### Measure Anti-Flicker Duration for Google Optimize
Source: https://support.speedcurve.com/docs/custom-metrics-for-anti-flicker-snippets
Uses a MutationObserver to watch for class changes on the document element, signaling when the Google Optimize anti-flicker class is removed. It records start, end, and duration marks using the User Timing API.
```javascript
(function (node, selector, name) {
performance.mark(name + '-start');
const callback = function (mutationsList, observer) {
for (const mutation of mutationsList) {
if (mutation.attributeName === 'class' &&
!mutation.target.classList.contains(selector) &&
mutation.oldValue.includes(selector)) {
performance.mark(name + '-end');
performance.measure(name + '-duration', name + '-start', name + '-end');
observer.disconnect();
break;
}
}
}
const observer = new MutationObserver(callback);
observer.observe(node, { attributes: true, attributeOldValue: true });
})(document.documentElement, 'async-hide', 'anti-flicker');
```
--------------------------------
### Configure WAF to Allow SpeedCurve via User Agent (CloudFlare)
Source: https://support.speedcurve.com/docs/adding-speedcurve-to-your-waf-or-bot-manager-allowlist
This guide explains how to create a firewall rule in CloudFlare's WAF to allow SpeedCurve traffic. It involves setting a rule to match requests where the User Agent contains 'PTST/SpeedCurve' and setting the action to 'Allow'.
```CloudFlare WAF
Rule Name: SpeedCurve
Field: User Agent
Operator: contains
Value: PTST/SpeedCurve
Action: Allow
```
--------------------------------
### Numeric Metrics Parsing
Source: https://support.speedcurve.com/docs/using-server-timing
Explains how numeric metrics are extracted from the 'desc' field in server-timing headers and the limitations.
```APIDOC
## Numeric Metrics Parsing
### Description
Numeric metrics, similar to size metrics, derive their value from the `desc` field within server-timing headers. The system attempts to parse these values, recording them numerically where possible. Negative values are not supported and will not be parsed correctly.
### Method
N/A (This describes a data parsing convention, not a specific HTTP endpoint)
### Endpoint
N/A
### Parameters
N/A
### Request Example
```
server-timing: items_in_cart;desc=3
server-timing: items_in_cart;desc=3items
```
### Response
#### Success Response (200)
N/A (This describes a data parsing convention)
#### Response Example
For `server-timing: items_in_cart;desc=3`, the numeric value recorded is `3`.
For `server-timing: items_in_cart;desc=3items`, the numeric value recorded is `3`.
#### Error Handling
Negative values in the `desc` field are not supported. For example, `server-timing: items_in_cart;desc="-1"` will not be parsed as `-1`.
```
--------------------------------
### Initialize LUX Global Object
Source: https://support.speedcurve.com/docs/rum-js-api
Standard pattern to safely initialize the LUX global object before setting configuration properties, ensuring compatibility with asynchronous script loading.
```javascript
LUX = window.LUX || {};
```
--------------------------------
### Add Custom Data using LUX.addData API
Source: https://support.speedcurve.com/docs/customer-data
This snippet demonstrates how to use the LUX.addData API to capture specific website data. It shows examples of adding business metrics, performance data, A/B test information, and user details. The total custom data is limited to 500 characters per page view.
```javascript
LUX.addData(name, value);
```
```javascript
LUX.addData('cartsize', 128);
LUX.addData('jsonresptime', 744);
LUX.addData('abtest_buttoncolor', 'blue');
LUX.addData('username', 'steve_souders');
```
--------------------------------
### A/B Test User Bucketing with SpeedCurve RUM API
Source: https://support.speedcurve.com/docs/ab-testing-rum
This PHP snippet demonstrates how to split users into two buckets for an A/B test using SpeedCurve's RUM addData API. It randomly assigns users to either fetch JSONP dynamically (control bucket, JsonpMarkup=no) or via markup (test bucket, JsonpMarkup=yes). This segmentation allows for performance comparison between the two approaches.
```php
if ( rand(0,1) ) {
echo "\n"; // request JSONP dynamically
echo "\n";
}
else {
echo "\n";
echo "\n";
}
```
--------------------------------
### Initialize RUM for SPAs with LUX.init()
Source: https://support.speedcurve.com/docs/rum-js-api
Initializes RUM for Single Page Applications (SPAs). This function should be called at the beginning of each SPA 'page view' transition. It is necessary for SPAs because RUM does not automatically detect page changes in the same way it does for traditional web pages.
```javascript
LUX.init();
// start SPA page transition
```
--------------------------------
### Add RUM Snippet and Set Sample Rate
Source: https://support.speedcurve.com/docs/setup-guide
This snippet should be added to the HEAD element of your HTML pages as early as possible to ensure comprehensive data collection. The sample rate can be adjusted to match your desired plan, with a default of 100%.
```html
```
--------------------------------
### LUX.auto Configuration
Source: https://support.speedcurve.com/docs/rum-js-api
Controls whether the RUM beacon is automatically sent on the window load event. If set to false, LUX.send() must be called manually.
```APIDOC
## LUX.auto
### Description
If set to false, the beacon is not sent on the window load event. This is useful for pages where content loads after the window load event. You must call `LUX.send()` manually if `LUX.auto` is set to false.
### Method
Property Assignment
### Endpoint
N/A (Client-side JavaScript configuration)
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Request Example
```javascript
LUX = window.LUX || {};
LUX.auto = false;
```
### Response
#### Success Response (200)
N/A
#### Response Example
N/A
```
--------------------------------
### Configure Fastly VCL for Server-Timing
Source: https://support.speedcurve.com/docs/collecting-custom-data-from-your-cdn
This snippet shows how to set the Server-Timing header within Fastly VCL. It maps internal variables like time.start.msec and server.datacenter to the header value.
```VCL
set resp.http.Server-Timing = "time-start-msec;dur=" time.start.msec ",time-elapsed;dur=" time.elapsed.msec ",fastly-pop;desc=" server.datacenter ",hit-state;desc=" fastly_info.state;
```