Skip to the content

Overview

What the monitors measure (main-thread lag, hangs, long animation frames, INP and the other Web Vitals), the packages of the project, and how this documentation is organized.

Note

This page is a draft. The content is not complete and can change.

@mark1russell7/lag measures the lag of the main thread in browser apps. Each monitor measures one signal, for example blocked time, queueing delay, frame delays or input latency. The monitors record OpenTelemetry metrics (counters and histograms) and send events with the details. setupAllMonitors() starts each monitor that the browser can support.

The library measures in the field, on the devices of real users. Thus it calibrates each probe against its environment, and it discards each sample that the page lifecycle or the clocks make incorrect. The thesis gives the argument and the evidence.

What the monitors measure

QuestionMonitor
How much of each 100 ms was the main thread busy?DriftLag
How long does a task that arrives at a random time wait?Worker lag
Did the main thread hang, and for how long?Worker lag and the hang journal
How long does an interaction wait for the next paint?Event Timing and page-view vitals
Which script blocked a frame?Long animation frames (Chromium)
Are the frames late?Frame timing
Does the page shift its layout?Layout shift and page-view vitals
Is the device busy, hot or out of memory?Compute pressure, memory, GC signal
Are the timers and the clocks correct?Timer throttle, clock reliability, clock drift

The monitor overview lists all monitors with their browser support and their cost.

The packages

PackageWhat it does
@mark1russell7/lagThe package on npm (npm install @mark1russell7/lag). The monitors, the measurement conditions, the metric catalog, the browser adapter and setupAllMonitors(). It has no DOM or OpenTelemetry dependency: the caller gives each browser API.
@mark1russell7/lag/workerThe second entry point of the package: the Web Worker of the worker-lag monitor. It sends heartbeats, detects hangs and keeps the hang journal.
@lag/loadSynthetic main-thread load for tests and for the playground.
@lag/reportThe data format of the test reports, and the converters from Vitest, Istanbul and Stryker.
@lag/siteThis website.

The linter @mark1russell7/ste-lint examines this site, the READMEs and the TSDoc comments for the writing rules of ASD-STE100. It has its own repository.

The metrics go through otel-ts, the OpenTelemetry setup of the project, to the Grafana stack.

How to read this documentation

  • Quick start: add the monitors to an app.
  • Concepts: the ideas that the monitors use. Read them before you read the numbers on a dashboard.
  • Monitors: one reference page for each monitor.
  • Architecture and API: the parts of the code.
  • Operations: the OpenTelemetry setup, the Grafana stack and the dashboards.
  • Testing: how we test the library, and the results of the latest run.
  • Research: the facts about browsers, clocks and tools that the design uses.

Next steps

Start with the quick start. Then open the playground to see the monitors in this page.

To change this page, edit packages/site/content/docs/index.mdx.

lag: Main-thread responsiveness monitoring for browser apps, exported as OpenTelemetry metrics.

To change a page, edit its file in packages/site/content/. The writing style guide tells you how.

An AI model (Claude, from Anthropic) wrote most of the text and the code of this site and of the library, under the direction of the author. The tests and the STE linter examine them. The writing standard gives the reason for this note.