@azlib/inspector
v0.2.0
Published
Use `@azlib/inspector` to diagnose UI performance issues during local development and map findings back to the most useful available code location.
Downloads
98
Readme
Inspector
Use @azlib/inspector to diagnose UI performance issues during local development and map findings back to the most useful available code location.
What it is designed for:
- bounded inspection sessions around one interaction, region, or time window
- ranked findings with evidence and severity
- exact, approximate, or unavailable source locations without overstating precision
- React-specific enrichment through an optional adapter
- framework-agnostic DOM inspection through browser-native performance signals
- Vite and Webpack source hint injection configured from the consumer bundler
Configure source hints through Vite in the consumer project:
import { defineConfig } from "vite";
import { inspectorVitePlugin } from "@azlib/inspector";
export default defineConfig({
plugins: [inspectorVitePlugin()],
});The plugin runs in Vite dev mode and injects data-azlib-inspector-source attributes into JSX and TSX opening tags. Those attributes let DOM inspection report approximate source locations without adding hand-written annotations to each component.
You can change the emitted attribute or restrict the files the plugin touches:
inspectorVitePlugin({
attributeName: "data-ui-source",
include: /src\/features\/.*\.tsx$/,
});Configure source hints through Webpack in the consumer project:
const { inspectorWebpackPlugin } = require("@azlib/inspector");
module.exports = {
plugins: [inspectorWebpackPlugin()],
};The Webpack plugin adds @azlib/inspector/webpack-loader as a pre-loader for JSX and TSX modules. It accepts the same source-hint options as the Vite plugin:
const { inspectorWebpackPlugin } = require("@azlib/inspector");
module.exports = {
plugins: [
inspectorWebpackPlugin({
attributeName: "data-ui-source",
include: /src\/features\/.*\.tsx$/,
}),
],
};Initial public surface:
import { createInspector } from "@azlib/inspector";
const inspector = createInspector();
const session = inspector.startInspection({ targetKind: "dom" });
// reproduce the UI interaction here
const result = inspector.stopInspection(session);React inspection starts with the optional adapter:
import { createInspector, createReactInspectionAdapter } from "@azlib/inspector";
const reactAdapter = createReactInspectionAdapter({
renderSamples: [
{
actualDurationMs: 92,
componentName: "SlowResults",
observedAt: performance.now(),
source: { column: 10, filePath: "src/SlowResults.tsx", line: 44 },
},
],
});
const inspector = createInspector({}, [reactAdapter]);
const session = inspector.startInspection({ targetKind: "react" });
const result = inspector.stopInspection(session);React findings use exact source locations only when development metadata is available. When metadata is missing, findings remain useful but their source location is marked as approximate or unavailable.
Framework-agnostic DOM inspection uses browser-facing signals and optional source hints:
import { createDomInspectionAdapter, createInspector } from "@azlib/inspector";
const domAdapter = createDomInspectionAdapter({
samples: [
{
durationMs: 72,
observedAt: performance.now(),
signalType: "long-task",
source: { column: 3, filePath: "src/search.ts", line: 28, symbolHint: "renderResults" },
target: { label: "Search results", selectorHint: "#results" },
},
],
});
const inspector = createInspector({}, [domAdapter]);
const session = inspector.startInspection({ targetKind: "dom" });
const result = inspector.stopInspection(session);DOM source hints are approximate because they usually identify the nearest annotated UI element or render function, not the exact statement responsible for the slowdown. Third-party widgets can still produce findings, but their ownership is reported as third-party and their source location may be unavailable.
Source hints can also be parsed manually when you need to bridge an annotated DOM element into a diagnostic sample:
import { readElementSourceHint } from "@azlib/inspector";
const source = readElementSourceHint(document.querySelector("#results")!);Scope inspection to keep findings focused:
const session = inspector.startInspection({
scope: { mode: "region", regionHint: "#results" },
targetKind: "dom",
});
const result = inspector.stopInspection(session);Supported scope modes are full-surface, region, interaction, and time-window. When no evidence matches the selected scope, the result status is no-findings with a clear message instead of a silent empty payload.
This package is intended for development and test workflows. Source locations depend on available framework or source metadata, so some findings may only provide approximate hints.
