Design Editor Performance
SkillDocs & knowledgeGives your agent the rules and budgets for keeping the design editor canvas fast and memory-safe.
Then ask your AI: use the Design Editor Performance skill
Details
Instructions available. Your AI can read the instructions. Execution depends on the setup they require.
Account requirements not reviewed. Check the skill instructions before use; Ahel provides instructions and does not run this skill.
No other account needed.
Add it as a step in a pipeline you build on Ahel, or connect Ahel to Claude, ChatGPT, Cursor, Claude Code or Codex and ask your AI to use it.
About this skill
What each screen costs on Design's canvas, the budgets that bound it, and how to prove a change keeps them. Use when changing culling, previews, live editors, zoom/pan/drag, DesignEditor hooks or caches, or when Design lags, flashes, or grows memory.
What this skill tells your AI
The instructions your AI receives, as published by builderio/agent-native in templates/design/.agents/skills/design-editor-performance/SKILL.md and read by Ahel’s review.
The general rules (closure chains, cache budgets, view swaps, measuring after
GC) are in the root performance skill, §11. This is what they mean on the
board, where one user session holds dozens of multi-megabyte screens.
What a screen costs
| Shown as | Runs in | Costs | Bounded by |
|---|---|---|---|
| Live editor | same-origin iframe, main thread | ~20 MB and ~380 ms of main thread to boot | 32 in the pool, 4 booting at once, 3 kept warm through a zoom-out |
| Static preview | sandboxed srcdoc iframe, preview process | its ~2 MB srcdoc string in the main heap; the preview process renders one at a time | 64, nearest first, then screens already seen |
| Placeholder | nothing | nothing | everything else |
A screen gets an editor at ≥240 px on screen and loses it below 180 px, only
once the camera has rested 250 ms; hovering promotes after 300 ms. The pool
sizes and thresholds live in multi-screen/culling.ts; the timings and the
warm count are constants at the top of MultiScreenCanvas.tsx.
Rules for changes here
- Decide in
multi-screen/culling.ts, wire inMultiScreenCanvas.tsx. The selection functions are pure; prove a policy change inMultiScreenCanvas.culling.test.tsor the boot-budget component test, not in a browser. - Swaps hand off; they never blank.
staticPreviewHandoffByIdkeeps a painted preview over an editor until that editor's own ready signal (the 8-second boot timeout frees a boot slot but proves nothing was drawn), and a demoted editor until its preview has painted. The preview slot stays ahead of{screenContent}in the DOM: that order puts it under a running editor and keeps the iframe from being re-inserted, which would reload it. - A screen already seen keeps its preview (
retainedIds). Unmounting one rebuilds it from blank when the camera returns, which users read as the board "rebuilding itself". - Previews are parsed off the main thread before they mount. The canvas
hands the workers the screens it is about to mount with
wantPreviewParses, which replaces its last list, and admission waits for each result. Workers take one job at a time, so a pan never buries the screens now in view. Don't parse a screen on mount. - In the editor's hooks (
design-editor/domains/use-editor-*.ts), never capture a heavy value. AuseCallbackoruseMemothat closes over a projection, tree, layer model or file content pins that render, and every render chained behind it. Take trees and node maps fromcachedCodeLayerTree/cachedCodeLayerNodeById(shared/code-layer.ts), and read the latest value through a ref. - Layer models are built on demand (
derive/layer-model-coverage.ts). Don't add anisNeededcondition that keeps a screen's model for the rest of the session; that is how the board's heap passed a gigabyte. - A command that knows its result before the server answers starts the work
during the round trip.
duplicate-screen.tsannotates and parses the copy whilecreate-fileis in flight. - Drag isolation lasts only for the drag.
isolateMovingPreviewIframesgives a moving screen's iframes their own layer and removes it on drop.
Proving a change
- A count in a unit or component test, in the fast lanes. The existing
ones show the shapes that work:
code-layer.recent-documents.test.ts(documents retained),memoize-by-content(characters cached), the culling tests (previews retained, warm editors), and the boot-budget tests (preview survives a promotion, demoted editor waits for paint). pnpm perf:runtime-budget, against a production build started withAUTH_DISABLED=1. It seeds the 48-screen stress board, runs four rounds of select, text edit, fill color, duplicate, a zoom cycle and screen visits, and compares withscripts/runtime-budget.json. It exits 0 within budget, 1 over budget, and 2 when a step did not take effect. It runs as theRuntime budgetcheck of the Design E2E workflow, on the same pull requests that workflow already runs for. The gates (heap, blanked screens, live editors) each carry their reason in the JSON; editor churn and frame times are reported only, because shared runners are too noisy for a fixed limit. When a change improves a gated number, lower itsmaxin the same PR.- When the budget fails or a report comes in, read
references/measuring.mdfor the local setup, the traps that faked results, and how to find what holds memory.
Signals
- GitHub stars
- 7k
- Forks
- 645
- Last commit
- Oct 2026
Ahel review
K1binfo
installs-packages (in references/measuring.md)
Automated review, not a security audit. Ruleset v1+k2.
Advanced
- Item type
- skill
- Key
design-editor-performance- Source
- github.com/builderio/agent-native
github.com/builderio/agent-native
Related picks
Skill · mattpocock
The pick for TypeScripttypescript-providers
Skill · composiohq
The pick for TypeScripte2e-testing
Skill · thedaviddias
The pick for End-to-end testinge2e-environment-preflight
Skill · sno-ai
The pick for End-to-end testingreact-component-performance
Skill · davila7
The pick for Reactreact-doctor
Skill · millionco
The pick for React