API reference
The exported functions, classes and types of @mark1russell7/lag, @mark1russell7/lag/worker, @lag/load and @lag/report.
Note
This page lists the public API of each package. The TSDoc comment of each export gives the details. The links go to the source on GitHub.
Install
npm install @mark1russell7/lag
The package has three entry points:
| Entry point | What it contains |
|---|---|
@mark1russell7/lag | The exports of the sections from Setup to Utilities. |
@mark1russell7/lag/worker | createLagWorker() and the worker module that it starts. Refer to the section @mark1russell7/lag/worker. |
@mark1russell7/lag/event-line.js | formatEventLine(), which makes the line of each event. |
@lag/load and @lag/report are private packages of the repository. They are not on npm.
Setup
setupAllMonitors(deps)
function setupAllMonitors(deps : AllMonitorDeps) : AllMonitorHandles;
The function starts each monitor whose dependencies are in deps, and gives the handles. The necessary dependencies are logger, clock, meter, the four timer functions, document and window. All other dependency groups are optional. Refer to the quick start.
AllMonitorHandles has these members:
| Member | What it does |
|---|---|
registry | The MonitorRegistry with the handle of each monitor. registry.get(name) gives one handle. |
stop() | Stops all monitors in the reverse sequence of their start. |
flush() | Records the values that the monitors keep until a checkpoint (the page-view vitals). Connect it to the before-flush hook of the exporter. |
conditions, vitals, driftLag, workerMonitor, pageViewContext and the other accessors | The monitor of one handle, or undefined if the monitor did not start. |
createBrowserDeps(window, options)
function createBrowserDeps(globals : BrowserGlobals, options : BrowserDepsOptions) : AllMonitorDeps;
The function gets the dependencies from the browser globals. It examines each optional API and binds each browser function to its object.
| Option | Default | What it does |
|---|---|---|
logger, meter | necessary | The diagnostic logger and the OpenTelemetry meter. |
events | none | The event sink (createOtelEventSink). Without it, the monitors send no events. |
spans | none | The span sink (createOtelSpanSink). Without it, the monitors make no spans. |
worker | none | The worker from createLagWorker(). Without it, the worker monitors do not start. |
workerHeartbeatIntervalMs | 1000 | The time between two heartbeats of the worker. |
workerHangReport | none | The OTLP logs URL and the resource for the hang reports of the worker. |
memoryIntervalMs | the monitor default | The time between two memory samples. |
pressureSources | ["cpu"] | The Compute Pressure sources. |
softNavigations | false | When true, each soft navigation starts a new page view (Chromium 151 and later). |
sharedMemory | true | Uses shared memory for the liveness watcher in a cross-origin-isolated page. |
hangJournal | true | Reads the hang journal in IndexedDB, when there is a worker. With false, the worker also writes no records. |
crashReportContext | true | Puts the page-view ID into window.crashReport (Chrome 145 and later). |
peerHangWatch | true | The open pages of the origin watch each other for hangs, through BroadcastChannel and navigator.locks (peer hang watch). |
Factories
Each factory makes one monitor, connects it to its instruments, and gives a MonitorHandle (name, monitor, stop()). Use a factory when you want only some monitors.
| Factory | Monitor | Page |
|---|---|---|
createInstrumentedLifecycle | LifecycleStateMachine | Lifecycle |
createInstrumentedPageViewVitals | PageViewVitals | Page-view vitals |
createInstrumentedPageViewContext | the page-view context | Page-view context |
createInstrumentedDriftLag | DriftLag | DriftLag |
createInstrumentedMacrotaskLag | MacrotaskLag | MacrotaskLag |
createInstrumentedThrottleDetector | TimerThrottleDetector | Timer throttle |
createInstrumentedLoaf | LongAnimationFrameMonitor | Long animation frames |
createInstrumentedEventTiming | EventTimingMonitor | Event Timing |
createInstrumentedLayoutShift | LayoutShiftMonitor | Layout shift |
createInstrumentedFrameTiming | FrameTimingMonitor | Frame timing |
createInstrumentedIdleAvailability | IdleAvailabilityMonitor | Idle availability |
createInstrumentedSchedulingFairness | SchedulingFairnessMonitor | Scheduling fairness |
createInstrumentedMemory | MemoryMonitor | Memory |
createInstrumentedWorkerLag | WorkerLagMonitor | Worker lag |
createInstrumentedSharedLiveness | SharedLivenessMonitor | Shared liveness |
createInstrumentedPeerHangWatch | PeerHangWatch | Peer hang watch |
createInstrumentedComputePressure | ComputePressureMonitor | Compute pressure |
createInstrumentedGCSignal | GCSignalDetector | GC signal |
createInstrumentedClockReliability | ClockReliabilityChecker | Clock reliability |
createInstrumentedClockDrift | ClockDriftMonitor | Clock drift |
createInstrumentedBrowserReports | BrowserReportMonitor | Browser reports |
The building blocks of a factory are createHandle (an error boundary) and validatedRecorder (a sample validator for a record function).
Measurement conditions
| Export | What it does |
|---|---|
createMeasurementConditions(options) | Makes the shared conditions: a ReliabilityTracker, createValidator(), pauseWhileHidden(monitor) and dispose(). The conditions report the stall samples whose windows overlap as one stall episode. |
ReliabilityTracker | Keeps the intervals in which samples are not valid (hidden, frozen, suspend). findOverlap(start, end, reason?) gives an interval that overlaps a window, optionally only of one cause. |
SampleValidator | Discards a sample that overlaps such an interval, and holds a very long sample until it knows if it was a hang or a suspend. |
Refer to measurement validity.
Metrics and events
| Export | What it does |
|---|---|
METRICS, METRIC_CATALOG | Every metric: name, type, unit, monitor, description and permitted attribute values. |
EVENTS, EVENT_CATALOG | Every event: name, monitor, description and attributes. |
createHistogram(meter, definition), createCounter(meter, definition) | Make an instrument from a catalog definition. They fail if the type does not agree. A histogram gets the bucket boundaries of its definition as advice (HISTOGRAM_BOUNDARIES, by unit). An SDK with explicit-bucket histograms uses them. |
Meter, Histogram, Counter, Attributes | The meter port. An OpenTelemetry Meter fits it. |
createNoopMeter() | A meter that records nothing. |
EventSink, EventOptions, createNoopEventSink(), withEventContext(sink, context) | The event port, the options of an event (time, the time of the occurrence in Unix milliseconds), a sink that sends nothing, and a sink that adds context attributes to each event. |
createOtelEventSink(logger, options?) | Sends each event as an OpenTelemetry log record with an event name. The body is the line of the event: the name and the sorted key=value pairs (formatEventLine in @mark1russell7/lag/event-line.js). The time of the occurrence becomes the time of the record. The options are maxTimeOffsetMs (refer to MAX_EVENT_TIME_OFFSET_MS) and now. |
placeEventTime(time, now, maxOffsetMs?), MAX_EVENT_TIME_OFFSET_MS, EVENT_TIME_ATTRIBUTE | The rule for the time of a record: the time of the occurrence when it is no more than 30 minutes from the time of the call, else the time of the call and the attribute lag.event.time. |
SPANS, SPAN_CATALOG | Every span: name, monitor, description and attributes. |
SpanSink, SpanIdentity, SpanOptions, OpenSpan, createNoopSpanSink() | The span port: a span that stays open until end() (a page view), or a span that ended already (a hang). A span has a parent and links. The times are Unix milliseconds. |
createOtelSpanSink(tracer, api) | Sends each span through an OpenTelemetry tracer. api is the module @opentelemetry/api. A span that the sampler did not sample gets the identity sampled: false, and the spans in it are not sampled either. |
createPageViewSpans(spans, clock), PageViewSpans | The span of each page view. setupAllMonitors() makes it when the dependencies have spans. |
createOtelLoggerAdapter(logger), createTeeLogger(...loggers) | Send the diagnostic messages to OpenTelemetry logs, or to more than one logger. |
encodeOtlpLogs(...) | Makes the OTLP/HTTP JSON body of log records. The worker uses it for its hang reports. |
Page views and Web Vitals
| Export | What it does |
|---|---|
PageViewVitals | The Web Vitals of each page view. getView(), getValues(), subscribe(listener), flush(), stop(). |
ViewCollector | The vitals of one page view, with the rules of web-vitals. |
describeNode(node) | The short CSS selector of a DOM node, as web-vitals makes it. |
rateVital(name, value), VITAL_THRESHOLDS | The rating good, needs-improvement or poor. |
PageSource, createPageSource(document, performance) | The navigation entry, the prerender state, the hidden times and the URL of the document. |
Clocks
| Export | What it does |
|---|---|
createAbsoluteClock(performance) | The absolute time of the context. It reads timeOrigin one time. |
ClockDriftMonitor | Finds suspends and clock steps from the wall clock and the absolute clock. |
WorkerClockSync | The NTP-style clock sync with the worker. |
ClockReliabilityChecker | The resolution of performance.now(). |
Worker
| Export | What it does |
|---|---|
WorkerLagMonitor | The main-thread half of the worker monitor: acknowledgements, the clock sync, the context, the watchdog. stop() keeps the listener for hang-ended, and dispose() removes it. |
createWorkerHandler(deps) | The worker half: the heartbeats, the hang detection and the hang journal. @mark1russell7/lag/worker operates it. |
MainToWorkerMessage, WorkerToMainMessage and the message types | The worker protocol. Refer to architecture. |
HangJournal, createIndexedDbHangJournal(indexedDB), createMemoryHangJournal() | The storage of hangs in progress: put(), remove(), list() and take(). take() removes and gives a stale record in one atomic operation. |
HangReportMarks, createStorageHangReportMarks(localStorage), HANG_REPORT_MARK_PREFIX, StorageLike | The marks of the hangs that a page reported itself or for another page. The journal reader skips the record of a marked hang. The marks are synchronous, thus a closing page can write them. |
PEER_CLAIM_HOLD_MS, AbortControllerLike, AbortSignalLike, AbortControllerConstructor | The time for which the peer hang watch holds the claim of a report (60 s), and the parts of AbortController with which it cancels its waiting lock requests. |
findAbandonedHangs(records, now, ownPageId) | The records of pages that did not survive their hang. now is a wall-clock time, as the times of the records are. |
SharedLivenessMonitor, LivenessWatcher, createLivenessBeacon, beatingSetTimeout | The shared-memory liveness watcher. |
createForwardingMeter, createMeterReceiver | Send the records of a meter from one context to another context, in batches. Each batch has the ID of its sender (senderId) and the definitions of its new instruments. Thus one receiver can get the records of many senders, also when its listener starts late. |
Utilities
| Export | What it does |
|---|---|
createMessageTaskQueue(MessageChannel) | Starts each callback in a new message task. |
RateLimiter, stripUrlParameters(url) | Limit the number of events, and remove the query and the fragment of a URL. |
createRandomId() | A random ID of 32 hexadecimal digits. |
MonitorRegistry, MonitorHandle | The registry of handles. |
LagMonitor, LagLogger | The base class of the timer monitors, and the logger of sustained lag. LagLogger measures its periods in time: the sum of the intervals of the measurements (LagMeasurement.intervalMs). |
@mark1russell7/lag/worker
This entry point is separate from the main entry point, because only this module starts a Worker. The worker module uses relative imports only. Thus the bundler of the app makes one file for the worker (refer to the quick start).
| Export | What it does |
|---|---|
createLagWorker() | Starts the module worker and gives a LagWorker. |
LagWorker | A WorkerLike with terminate(). The caller owns the worker. |
@lag/load
| Export | What it does |
|---|---|
createRng(seed) | A seeded random number generator, so that a workload is the same at each run. |
uniform, constant, normal, exponential, powerLaw, bimodal, mixture, evolutionary, burst, sample | Distributions of durations. |
syncBusyWait, syncCompute, gcPressure, microtaskFlood, macrotaskFlood, promiseChain, layoutThrash, longAnimationFrame, sleep | Generators of main-thread load. |
runWorkload(options) | Operates a workload and gives a WorkloadResult. |
lightLoad, moderateLoad, heavyLoad, burstyLoad, evolutionaryLoad, kitchenSink | Ready workload profiles. |
@lag/report
| Export | What it does |
|---|---|
RunReport, SuiteResult, TestCaseResult, CoverageReport, MutationReport, Measurement, BudgetResult, RunIndex, RunSummary | The data format of a test run. SCHEMA_VERSION gives its version. |
fromVitestJson, fromIstanbulSummary, fromStrykerReport | Convert the reports of Vitest, Istanbul and Stryker. |
countStatuses, summarizeRun | Summaries for the results viewer. |