An utility library for collecting user-centric performance metrics.
Features:
npm install uxm@next
Collect user-centric metrics and send data to your API (1.5Kb):
import { collectMetrics, createApiReporter, getDeviceInfo } from 'uxm'
const report = createApiReporter('/api/collect', { initial: getDeviceInfo() })
collectMetrics(['fcp', 'lcp', 'fid', 'cls'], ({ metricType, value }) => {
report({ [metricType]: value })
})
At the end of the session (on visibilitychange
event), your API receives a POST request (using sendBeacon
) with data for core UX metrics and a device information, like:
{
"fcp": 1409,
"fid": 64,
"lcp": 2690,
"cls": 0.025,
"url": "https://example.com/",
"memory": 8,
"cpus": 2,
"connection": { "effectiveType": "4g", "rtt": 150, "downlink": 4.25 }
}
Explore examples for building a robust real-user monitoring (RUM) logic. Size of each example is controlled using size-limit.
Metrics are the core of uxm
(uxm
is a 3-letter acronym that stands for User eXperience Metrics).
It focuses on metrics, that captures a user experience, instead of measuring technical details, that are easy to manipulate. This metrics are more representetive for a user, and the final purpose of a good frontend is to create a delightful user experience.
Each metric follows the structure:
metricType
<[string]> - a metric acronym, ex: lcp
, fid
, or cls
.value
<number> - a numeric value of a metric, ex: 1804
for lcp
, 4
for fid
, or 0.129
for cls
.detail
<object> - an extra detail specific for an each metric, like elementSelector
for lcp
, event name
for fid
, or totalEntries
for cls
.with an exception for collectLoad
(it does not have a 3-letters acronym, and considered a legacy.)
Use a per-metric function for more granular control of the callback behavior and saving a bundle size.
This metrics are only available in Chromium-based browsers (Chrome, Edge, Opera).
The best way to understand a metric is to read web.dev/metrics and check the source.
The method is a shortcut for calling collectFcp
, collectFid
, collectLcp
, and collectCls
.
import { collectMetrics } from 'uxm'
const report = createApiReporter('/api/collect')
// pass a metric 3-letter acronym
collectMetrics(['fcp', 'fid'], (metric) => {
report({ [metric.metricType]: metric.value })
})
// or a metric options using an object and `type`
collectMetrics([{ type: 'lcp', maxTimeout: 1000 }], (metric) => {
report({ lcp: metric.value })
})
callback
<function> a callback with FcpMetric:
metricType
<"fcp"
>value
<number> a time when the user can see anything on the screen – a fast FCP helps reassure the user that something is happening.Collect First Contentful Paint (FCP) using paint
entries.
callback
<function> a callback with FidMetric
:
import { collectFid } from 'uxm'
collectFid((metric) => {
console.log(metric)
// { metricType: "fid", value: 1, detail: { duration: 8, startTime: 2568.1, processingStart: 2568.99, processingEnd: 2569.02, name: "mousedown" }
})
callback
<function> a callback with LcpMetric
:
metricType
<"lcp"
>value
<number> a time when the page's main content has likely loaded – a fast LCP helps reassure the user that the page is useful.detail
<object>elementSelector
<[string]> CSS selector of an element, that is triggered the most significant paintsize
<number> size (height
x width
) of the largest elementoptions
<object> (Optional)
maxTimeout
<number> The longest delay between largest-contentful-paint
entries to consider the LCP. Defaults to 10000
ms.Collect Largest Contentful Paint (LCP) using largest-contentful-paint
entries.
A callback triggers when a user interacts with a page, or after maxTimeout
between entries, or on "visibilitychange"
event.
import { collectLcp } from 'uxm'
collectLcp((metric) => {
console.log(metric) // { metricType: "lcp", value: 2450, detail: { size: 8620, elementSelector: "body > h1" } }
})
callback
<function> a callback with ClsMetric
:
import { collectCls } from 'uxm'
collectCls(
(metric) => {
console.log(metric) // { metricType: "cls", value: 0.0893, detail: { totalEntries: 2, sessionDuration: 2417 } }
},
{ maxTimeout: 1000 }
)
callback
<function> a callback with ClsMetric
:
import { collectLoad } from 'uxm'
collectLoad(({ value: load, detail: { domContentLoaded, timeToFirstByte } }) => {
console.log({ timeToFirstByte, domContentLoaded, load })
})
alpha
)Made with ❤️ by Treo.