Skip to main content

App performance

We provide two out-of-the-box solutions for tracking app performance metrics:

  • Plugins for automatic performance tracking on web
  • Timing events, available in most Snowplow trackers, for manual tracking

Automatic tracking on web

The JavaScript tracker provides two configurable plugins that track performance automatically.

Use the web vitals plugin to track key user-centric performance metrics, and the performance navigation timing plugin to capture detailed navigation timing data.

Web vitals

This plugin tracks web performance metrics categorized as Web Vitals.

This table shows which versions of the trackers can use the web vitals plugins:

TrackerSupportedSince versionAuto-trackingNotes
Web3.13.0
React NativeTracker can't access the required browser APIs
Google Tag ManagerNot directly supported, but you can load it as an external plugin

To process raw web vitals event data, use the core web vitals module in the Snowplow Unified Digital dbt package.

web_vitals

Event
Schema for a web vitals tracking event. For more information on web vitals you can visit https://web.dev/vitals/.
Schema URIiglu:com.snowplowanalytics.snowplow/web_vitals/jsonschema/1-0-0
Example
json
{
"schema_name": "web_vitals",
"cls": 0.05,
"fcp": 0,
"fid": "36:00.0",
"inp": "36:00.0",
"lcp": 1908,
"navigationType": "navigate",
"ttfb": 228.9
}
Properties and schema
PropertyDescription
cls (Cumulative Layout Shift)
number
Optional. A unitless metric for measuring visual stability because it helps quantify how often users experience unexpected layout shifts. For more information https://web.dev/cls/.
fid (First Input Delay)
number
Optional. A metric for measuring load responsiveness because it quantifies the experience users feel when trying to interact with unresponsive pages. Measured in milliseconds. For more information https://web.dev/fid/.
lcp (Largest Contentful Paint)
number
Optional. A metric for measuring perceived load speed because it marks the point in the page load timeline when the page's main content has likely loaded. Measured in milliseconds. For more information https://web.dev/lcp/.
fcp (First Contentful Paint)
number
Optional. A metric for measuring perceived load speed because it marks the first point in the page load timeline where the user can see anything on the screen. Measured in milliseconds. For more information https://web.dev/fcp/.
inp (Interaction to Next Paint)
number
Optional. A metric that assesses responsiveness. INP observes the latency of all interactions a user has made with the page, and reports a single value which all (or nearly all) interactions were below that value. For more information https://web.dev/inp/.
ttfb (Time To First Byte)
number
Optional. A DOMHighResTimeStamp referring to the time in milliseconds between the browser requesting a page and when it receives the first byte of information from the server. For more information https://web.dev/ttfb/.
navigationType
string
Optional. The navigation type recognised from the Navigation Timing API https://www.w3.org/TR/navigation-timing-2/. E.g. 'navigate', 'reload', 'back-forward', 'back-forward-cache', 'prerender', 'restore'.
Warehouse query
sql
select
unstruct_event_com_snowplowanalytics_snowplow_web_vitals_1_0_0
from
PIPELINE_NAME.events events
where
events.collector_tstamp > timestamp_sub(current_timestamp(), interval 1 hour)
and events.event = 'unstruct'
and events.event_name = 'web_vitals'
and events.event_vendor = 'com.snowplowanalytics.snowplow'

Performance navigation timing

This plugin will add Performance Navigation Timing entities to all tracked events.

This table shows which versions of the trackers can use the performance plugins:

TrackerSupportedSince versionAuto-trackingNotes
Web3.10.0
React NativeTracker can't access the required browser APIs to use these plugins
Google Tag Managerv4Integrates with the performance navigation timing plugin

PerformanceNavigationTiming

Entity
Schema for page navigation performance entity, based on the PerformanceNavigationTiming interface (see https://w3c.github.io/navigation-timing/)
Schema URIiglu:org.w3/PerformanceNavigationTiming/jsonschema/1-0-0
Properties and schema
PropertyDescription
decodedBodySize
integer
Optional. A number that is the size (in octets) received from the fetch (HTTP or cache) of the message body, after removing any applied content encoding.
encodedBodySize
integer
Optional. A number representing the size (in octets) received from the fetch (HTTP or cache), of the payload body, before removing any applied content encodings.
redirectStart
number
Optional. A DOMHighResTimeStamp that represents the start time of the fetch which initiates the redirect in milliseconds.
redirectEnd
number
Optional. A DOMHighResTimeStamp immediately after receiving the last byte of the response of the last redirect in milliseconds.
fetchStart
number
Optional. A DOMHighResTimeStamp immediately before the browser starts to fetch the resource in milliseconds.
domainLookupStart
number
Optional. A DOMHighResTimeStamp immediately before the browser starts the domain name lookup for the resource in milliseconds.
domainLookupEnd
number
Optional. A DOMHighResTimeStamp representing the time immediately after the browser finishes the domain name lookup for the resource in milliseconds.
connectStart
number
Optional. A DOMHighResTimeStamp immediately before the browser starts to establish the connection to the server to retrieve the resource in milliseconds.
secureConnectionStart
number
Optional. A DOMHighResTimeStamp immediately before the browser starts the handshake process to secure the current connection in milliseconds.
connectEnd
number
Optional. A DOMHighResTimeStamp immediately after the browser finishes establishing the connection to the server to retrieve the resource in milliseconds.
requestStart
number
Optional. A DOMHighResTimeStamp immediately before the browser starts requesting the resource from the server in milliseconds.
responseStart
number
Optional. A DOMHighResTimeStamp immediately after the browser receives the first byte of the response from the server in milliseconds.
responseEnd
number
Optional. A DOMHighResTimeStamp immediately after the browser receives the last byte of the resource or immediately before the transport connection is closed in milliseconds, whichever comes first.
unloadEventStart
number
Optional. A DOMHighResTimeStamp representing the time immediately after the current document's unload event handler starts in milliseconds.
unloadEventEnd
number
Optional. A DOMHighResTimeStamp representing the time immediately after the current document's unload event handler completes in milliseconds.
domInteractive
number
Optional. A DOMHighResTimeStamp representing the time immediately before the user agent sets the document's readyState to 'interactive' in milliseconds.
domContentLoadedEventStart
number
Optional. A DOMHighResTimeStamp representing the time immediately before the current document's DOMContentLoaded event handler starts in milliseconds.
domContentLoadedEventEnd
number
Optional. A DOMHighResTimeStamp representing the time immediately after the current document's DOMContentLoaded event handler completes in milliseconds.
domComplete
number
Optional. A DOMHighResTimeStamp representing the time immediately before the user agent sets the document's readyState to 'complete' in milliseconds.
loadEventStart
number
Optional. A DOMHighResTimeStamp representing the time immediately after the current document's load event handler starts in milliseconds.
loadEventEnd
number
Optional. A DOMHighResTimeStamp representing the time immediately after the current document's load event handler completes in milliseconds.
entryType
string
Optional. The string 'navigation'.
redirectCount
integer
Optional. A number representing the number of redirects since the last non-redirect navigation in the current browsing context.
type
string
Optional. A string representing the navigation type. Either 'navigate', 'reload', 'back_forward' or 'prerender'.
workerStart
number
Optional. Returns a DOMHighResTimeStamp immediately before dispatching the FetchEvent if a Service Worker thread is already running, or immediately before starting the Service Worker thread if it is not already running. If the resource is not intercepted by a Service Worker the property will always return 0.
nextHopProtocol
string
Optional. A string representing the network protocol used to fetch the resource, as identified by the ALPN Protocol ID (RFC7301)
transferSize
integer
Optional. A number representing the size (in octets) of the fetched resource. The size includes the response header fields plus the response payload body.
duration
number
Optional. Returns a timestamp that is the difference between the loadEventEnd and startTime properties.
activationStart
number
Optional. If the document is prerendered, activationStart represents the time between when the prerender was started and the document was actually activated.
deliveryType
string
Optional. Expose information about how a resource was delivered e.g. resources which were delivered from the cache.
serverTiming
array
Optional. Array of PerformanceServerTiming entries.

Manual timing events

Track things like resource load times or other performance measurements using manual timing events.

This table shows the support for timing events across Snowplow tracker SDKs.

TrackerSupportedSince version
Web3.0.0
iOS2.0.0
Android2.0.0
React Native0.1.0
Flutter0.1.0
Roku
Java0.8.0
Golang0.1.0
Python
Ruby
PHP
.NET1.0.0
C++0.3.0
Rust0.1.0
Unity0.1.0
Scala
Lua
Node.js
Google Tag Manager

You can still track timing data using trackers without built-in timing event support. Use custom events with the timing schema.

timing

Event
Schema for a user timing event
Schema URIiglu:com.snowplowanalytics.snowplow/timing/jsonschema/1-0-0
Properties and schema
PropertyDescription
category
string
Required.
variable
string
Required.
timing
number
Required.
label
string
Optional.
Warehouse query
sql
select
unstruct_event_com_snowplowanalytics_snowplow_timing_1_0_0
from
PIPELINE_NAME.events events
where
events.collector_tstamp > timestamp_sub(current_timestamp(), interval 1 hour)
and events.event = 'unstruct'
and events.event_name = 'timing'
and events.event_vendor = 'com.snowplowanalytics.snowplow'

On this page

Want to see a custom demo?

Our technical experts are here to help.