use-web-vitals
Standard [good, poor] thresholds: values up to the first bound are "good", values above the second are "poor".
| Package | @vizejs/composable/use-web-vitals |
| Own the source | vize lib pull composable:use-web-vitals |
| Runtime exports | WEB_VITALS_THRESHOLDS, rateMetric, useWebVitals |
| Gzip budget | 4608 B |
Usage
import { WEB_VITALS_THRESHOLDS, rateMetric, useWebVitals } from "@vizejs/composable/use-web-vitals";
Runtime contract
| Utility | Category | Stability | SSR | Hydration | Cleanup | Targets | Host globals | Uses |
|---|---|---|---|---|---|---|---|---|
useWebVitals |
performance | experimental | deterministic-fallback | caller-managed | caller, reactive-scope | web, desktop | window |
tryOnScopeDispose, usePerformanceObserver |
rateMetric |
performance | experimental | safe | stable | none | web, server, worker, native, desktop, terminal | — | — |
API
WEB_VITALS_THRESHOLDS
Standard [good, poor] thresholds: values up to the first bound are "good", values above the second are "poor". Times are milliseconds; CLS is unitless.
const WEB_VITALS_THRESHOLDS
rateMetric
Rate a metric value with WEB_VITALS_THRESHOLDS.
function rateMetric(name: WebVitalName, value: number): WebVitalRating
useWebVitals
Measure LCP, CLS, INP, FCP and TTFB locally, without dependencies. - LCP: last candidate before the first input or hidden page. - CLS: largest session window (shifts < 1 s apart, window ≤ 5 s), ignoring shifts after recent input. - INP: per-interaction maximum duration; the highest after ignoring one per 50 interactions (a p98 approximation over the 10 longest). The interaction count only includes interactions above durationThreshold. - FCP: first-contentful-paint before the page was first hidden. - TTFB: navigation responseStart - activationStart, clamped at 0. Values are not adjusted for prerender activation except TTFB. Observers and listeners are released when the owning reactive scope stops; outside a scope the caller owns stop(). Server rendering: nothing is observed, metrics is {} and supported is false.
function useWebVitals(options: UseWebVitalsOptions = {}): WebVitalsControls
const { metrics, onMetric } = useWebVitals();
onMetric((metric) => navigator.sendBeacon("/vitals", JSON.stringify(metric)));
Types
WebVitalMetric
Snapshot of one metric.
| Member | Type | Description |
|---|---|---|
name |
WebVitalName |
Metric name. |
value |
number |
Current value (milliseconds, or the unitless CLS score). |
rating |
WebVitalRating |
Rating of value. |
delta |
number |
Change since the value last reported through onMetric (the full value before that). |
entries |
number |
Number of performance entries that make up value. |
id? |
string |
Identifier stable for this metric during the page load. |
WebVitalsDocumentHost
Minimal document consumed by useWebVitals.
| Member | Type | Description |
|---|---|---|
visibilityState |
string |
Current visibility ("visible" or "hidden"). |
addEventListener |
(type: WebVitalsDocumentEvent, listener: (event: { readonly timeStamp: number }) => void, options?: { readonly capture?: boolean }) => void |
Subscribe to a document event. |
removeEventListener |
(type: WebVitalsDocumentEvent, listener: (event: { readonly timeStamp: number }) => void, options?: { readonly capture?: boolean }) => void |
Unsubscribe from a document event. |
UseWebVitalsOptions
Options for useWebVitals.
| Member | Type | Description |
|---|---|---|
PerformanceObserver? |
MaybeRef<PerformanceObserverHost | null | undefined> |
PerformanceObserver constructor for alternate runtimes and tests. |
document? |
MaybeRefOrGetter<WebVitalsDocumentHost | null | undefined> |
Document whose visibility finalizes metrics and whose first input stops LCP. |
reportAllChanges? |
boolean |
Report every change through onMetric instead of only final values. |
durationThreshold? |
number |
Minimum Event Timing duration considered for INP, in milliseconds. |
WebVitalsControls
Reactive state and actions returned by useWebVitals.
| Member | Type | Description |
|---|---|---|
supported |
ComputedRef<boolean> |
Whether at least one metric can be observed. |
metrics |
Readonly<ShallowRef<WebVitalsRecord>> |
Metrics measured so far, replaced on each change. |
onMetric |
(listener: (metric: WebVitalMetric) => void) => () => void |
Subscribe to reported metrics. FCP and TTFB are reported once measured; LCP once finalized (first input or hidden page); CLS and INP whenever the page becomes hidden with a changed value. With reportAllChanges, every change is reported. |
stop |
() => void |
Stop every observer and listener. Repeated calls are safe. |