Skip to content
Back to skills

Map Perf

ASecurity

Measure topology-map drag, pan, and zoom with a deterministic harness that proves it grabbed a real node instead of silently panning the background.

  • 141 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 2, 2026
developmentrustshellbashnodeperformance

Works with

  • cursor

Security analysis

A100/100

Scanned September 26, 2026

npx -y skills add wlsdks/ontology-atlas --skill map-perf --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Map Perf?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Map Perf
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/wlsdks-map-perf-ontology-atlas/badge)](https://www.skillsdirectory.com/skills/wlsdks-map-perf-ontology-atlas)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: map-perf
description: Measure topology-map drag, pan, and zoom with a deterministic harness that proves it grabbed a real node instead of silently panning the background.
when_to_use: Use when pnpm design:route includes map-perf, or when node drag, pan, zoom, or the map frame loop is reported slow.
---

# Map performance

Run when `pnpm design:route` includes `map-perf`. It proves the changed topology
gesture's work cost; add the separate `motion` change fact when temporal output
also changed.

A node drag and a background pan look the same from outside; a node-drag report
was once dismissed six times while the harness was panning the background.

## Why grabbing a node is difficult

| | Node drag | Background pan |
|---|---|---|
| Cursor | `grabbing` | `grabbing` |
| Visible motion | one node | whole map |
| Physics | reheats through `heatRef` | remains idle |
| Measured cost at 3,000 nodes | about 140 ms/frame | about 2 ms/frame |

A pointer cursor is not proof of a grab. If `sim.hasNode()` is false, capture
fails silently and becomes a pan.

## Instrumentation: `?e2e=1`

The query enables a test-only `window.__atlasMap` surface:

```js
window.__atlasMap.nodes()
// [{ id, kind, label, x, y, draggable, hidden, radius, agentFocus }]

window.__atlasMap.interaction()
// { kind: "node" | "pan" | "idle", nodeId }
// Call during the gesture. A "pan" result invalidates the sample.

window.__atlasMap.backing()
// { width, height, dpr }
```

It also exposes `edges()`, `edgeAt()`, `camera()`, `selection()`, and `chips()`.
Implementation: the final effect in
`src/widgets/ontology-map/ui/use-topology-loop.ts`.

## Procedure

```bash
pnpm build && npx serve out -l 4173
node scripts/perf-node-drag.mjs
```

Discard output unless the harness explicitly reports a successful node grab.

## Four rules

1. Use real CDP mouse input through `page.mouse.*`. Synthetic PointerEvents are
   untrusted, cannot capture the pointer, and become pans.
2. Run headed. Headless rendering lacks display vsync and compositor
   backpressure; it measured 44fps where the real device measured 7fps. Only JS
   work cost transfers reliably.
3. Report `work`, not frame `gap`. Gap includes refresh rate and CDP round trips
   (about 24ms); work is time owned by Atlas.
4. Measure a control group such as `synth=31` beside `synth=3000`. The observed
   139.9ms versus 1.0ms exposes size-dependent cost directly.

## On-screen meter

Settings → Map background → Frame meter shows fps, worst frame, and jank count.
The worst frame matters more than average fps; one run had a 16.7ms median and a
150ms worst frame. Turning the meter off stops its measurement loop.

## Common traps

- Never reuse a fixed Chrome profile directory; a previous process can close the
  page and produce `Target page has been closed`. The harness uses a unique profile.
- Add `guides=off`; first-run overlays intercept input and create false 0.1ms work.
- fps changes in refresh-rate steps. Improvements below 8ms may appear only in
  `work`.

## Prefer browser-free measurement for pure physics

ForceAtlas2 cost is more accurately isolated without a browser:

```js
import Graph from "graphology";
import forceAtlas2 from "graphology-layout-forceatlas2";
// Vary n and measure forceAtlas2.assign(g, { iterations: 3, settings }).
```

Measured 2026-07-31: n=800 took 5.6ms; n=3000 took 79.4ms, or 34.5ms with
Barnes–Hut. Cost grows roughly quadratically.

## Final proof

The harness measures Chrome, while the installed app uses WKWebView. After the
fix is clear in Chrome, measure once more in the installed app according to
`.claude/rules/surfaces.md` when the route includes desktop-shell. Include the
`/design-build` §0-B render-loop packet showing the visible gesture state; it
proves target/state identity and does not replace the work measurement or a
routed motion recording.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.