UNPKG

nano-insights

Version:

A framework-agnostic performance monitoring component to fetch and display web page speed insights using tools like Google PageSpeed Insights.

221 lines (219 loc) 7.78 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __decorateClass = (decorators, target, key, kind) => { var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target; for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result; if (kind && result) __defProp(target, key, result); return result; }; // src/index.ts var index_exports = {}; __export(index_exports, { NanoInsights: () => NanoInsights }); module.exports = __toCommonJS(index_exports); var import_lit = require("lit"); var import_decorators = require("lit/decorators.js"); var NanoInsights = class extends import_lit.LitElement { constructor() { super(); this.projectKey = ""; this.sessionId = typeof localStorage !== "undefined" && localStorage.getItem("nanoInsightsSessionId") || typeof crypto !== "undefined" && crypto.randomUUID && crypto.randomUUID() || Math.random().toString(36).slice(2); if (typeof localStorage !== "undefined") { localStorage.setItem("nanoInsightsSessionId", this.sessionId); } } connectedCallback() { super.connectedCallback(); this.trackWebVitals(); } disconnectedCallback() { super.disconnectedCallback(); } trackWebVitals() { this.trackLCP(); this.trackFID(); this.trackCLS(); this.trackTTFB(); this.trackFCP(); this.trackNavigationTiming(); } trackLCP() { if (!PerformanceObserver) return; const lcpObserver = new PerformanceObserver((entryList) => { const entries = entryList.getEntries(); const lastEntry = entries[entries.length - 1]; if (document.readyState === "complete") { const lcp = lastEntry.startTime; this.sendToApi({ metric_type: "web_vital", metric_name: "LCP", metric_value: lcp, metric_unit: "ms" }); lcpObserver.disconnect(); } }); lcpObserver.observe({ type: "largest-contentful-paint", buffered: true }); } trackFID() { if (!PerformanceObserver) return; const fidObserver = new PerformanceObserver((entryList) => { const entries = entryList.getEntries(); entries.forEach((entry) => { const fidEntry = entry; if (fidEntry.processingStart) { const fid = fidEntry.processingStart - fidEntry.startTime; this.sendToApi({ metric_type: "web_vital", metric_name: "FID", metric_value: fid, metric_unit: "ms" }); } }); }); fidObserver.observe({ type: "first-input", buffered: true }); } trackCLS() { if (!PerformanceObserver) return; let clsValue = 0; let clsEntries = []; const clsObserver = new PerformanceObserver((entryList) => { const entries = entryList.getEntries(); entries.forEach((entry) => { const layoutShiftEntry = entry; if (layoutShiftEntry.hadRecentInput === false && typeof layoutShiftEntry.value === "number") { clsValue += layoutShiftEntry.value; clsEntries.push(entry); } }); }); clsObserver.observe({ type: "layout-shift", buffered: true }); const reportCLS = () => { if (clsEntries.length > 0) { this.sendToApi({ metric_type: "web_vital", metric_name: "CLS", metric_value: clsValue, metric_unit: "" }); } }; ["visibilitychange", "beforeunload"].forEach((type) => { window.addEventListener(type, reportCLS, { once: true }); }); } trackTTFB() { window.addEventListener("load", () => { if (performance && performance.getEntriesByType) { const navEntries = performance.getEntriesByType("navigation"); if (navEntries.length > 0) { const navEntry = navEntries[0]; const ttfb = navEntry.responseStart; this.sendToApi({ metric_type: "web_vital", metric_name: "TTFB", metric_value: ttfb, metric_unit: "ms" }); } } }); } trackFCP() { if (!PerformanceObserver) return; const fcpObserver = new PerformanceObserver((entryList) => { const entries = entryList.getEntries(); entries.forEach((entry) => { const fcp = entry.startTime; this.sendToApi({ metric_type: "web_vital", metric_name: "FCP", metric_value: fcp, metric_unit: "ms" }); fcpObserver.disconnect(); }); }); fcpObserver.observe({ type: "paint", buffered: true }); } trackNavigationTiming() { window.addEventListener("load", () => { if (performance && performance.getEntriesByType) { const navEntries = performance.getEntriesByType("navigation"); if (navEntries.length > 0) { const navEntry = navEntries[0]; this.sendToApi({ metric_type: "navigation_timing", dns_lookup: navEntry.domainLookupEnd - navEntry.domainLookupStart, tcp_connection: navEntry.connectEnd - navEntry.connectStart, server_response: navEntry.responseEnd - navEntry.responseStart, dom_interactive: navEntry.domInteractive - navEntry.responseEnd, dom_complete: navEntry.domComplete - navEntry.domInteractive, page_load: navEntry.loadEventEnd - navEntry.loadEventStart, total_page_load: navEntry.loadEventEnd }); } } }); } sendToApi(data) { fetch("https://www.nanosights.dev/api/tags/insights", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(__spreadValues({ projectKey: this.projectKey, sessionId: this.sessionId, userAgent: navigator.userAgent, referrer: document.referrer, url: window.location.href, page_title: document.title, page_path: window.location.pathname, timestamp: (/* @__PURE__ */ new Date()).toISOString() }, data)) }); } }; __decorateClass([ (0, import_decorators.property)({ type: String }) ], NanoInsights.prototype, "projectKey", 2); NanoInsights = __decorateClass([ (0, import_decorators.customElement)("nano-insights") ], NanoInsights); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { NanoInsights });