performance: true is not a supported useAnalytics() option. Keep page analytics and performance collection separate so sites only load the features they use.
Collect Web Vitals estimates
Section titled “Collect Web Vitals estimates”import { trackWebVitals } from "@owleye/analytics/performance";
const vitals = trackWebVitals("owl_your_tracking_id");
// When the app is torn down:vitals.stop();Call this in browser code only after your site’s analytics decision allows collection. It does not start page-view tracking. An equivalent API is trackPerf(id).observeVitals().
The collector observes LCP, INP, CLS, FCP, and TTFB where browser APIs support them. Measurements are labelled approximate: true: the collector does not implement the full reference CLS session-window or INP percentile algorithms. Treat the console’s percentiles as preliminary field signals, not Lighthouse scores or a Core Web Vitals compliance assessment.
stop() discards pending measurements and removes observers/listeners. While observation is active, hiding or leaving the page flushes lifecycle values. Stopping does not retract requests already started or delete previous measurements. Repeated observation shares the active collector for the same Tracking ID and endpoint; own cleanup at the application root.
Web Vitals describe the document lifetime, not separate SPA screens. Delayed values retain the original document URL from browser navigation timing, or the observation-start URL when that timing is unavailable. They are not relabeled with a later SPA page. A document title is omitted when observation starts after navigation and the original title is unknown.
Track custom timings
Section titled “Track custom timings”import { trackPerf } from "@owleye/analytics/performance";
const timings = trackPerf("owl_your_tracking_id");const end = timings.start("report_generation", { format: "pdf" });try { await generateReport(); end({ status: "ok" });} catch (error) { end({ status: "error" }); throw error; // Preserve your application's error handling.}end() is idempotent. The span retains the browser page captured by start(), even when it ends after navigation. Each call accepts at most ten primitive fields; avoid secrets and personal identifiers. Custom timings are stored in the separate performance dataset with a duration_ms value. On Pro and Business, Web Vitals and custom timings do not consume the monthly event allowance. Request and ingestion safety limits still apply. Ordinary event lists exclude these measurements. Ask the AI assistant for sample counts, averages, and percentiles by recorded timing name. The Web Vitals page only reports web_vital_* measurements; it does not chart custom operation durations.
Plain HTML
Section titled “Plain HTML”Use the performance CDN bundle; it starts observation when loaded. In the console, open Web Vitals, choose a range and metric, and check sample counts. An empty report may mean no measurements, unsupported browser APIs, blocked tracking, or the wrong date range.
Using script tags
Section titled “Using script tags”See CDN tracking examples for script tags, campaign attributes, global JavaScript controllers, and manual custom data.
Measurement storage
Section titled “Measurement storage”New measurements go to owleye_performance in ClickHouse. An internal read view also includes retained legacy measurements in owleye_events. Both feed the managed service’s reporting path; Architecture explains the data flow.