perf
Skill96 starsChanged 36 days agoMITView on GitHub
Speed and memory performance rules for Rust crates, the Node addon, webui-framework, and webui-router.
We split this skill into the rules it gives an agent
18 rules. 0 are common, 3 are distinctive, and 15 are very specific to this project.
0
Common
Most of the 14 edited versions we read keep these.
3
Distinctive
This author's own choices. Worth a look.
15
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 12
Use this skill when modifying any performance-sensitive code across the stack.
- Very specific: line 18
No
format!()in writer output: Use sequential writer.write() calls. - Very specific: line 19
No
.to_string()onCow: Write Cow<str> directly to avoid defeating zero-copy. - Very specific: line 21
No redundant scans: Use first_part.len() == path.len() instead of path.contains('.').
- Very specific: line 22
No
String::from(ch)in escape loops: Use ch.encode_utf8(&mut buf) with a [u8. - Very specific: line 23
No
format!in hex parsing: Use direct arithmetic ((hi_nibble << 4) | lo_nibble) instead of u8::from_str_radix(&format!(...)). - Very specific: line 25
No silent
unwrap_ordefaults: If binding_stack.pop() returns None, that's a protocol error - propagate it, don't mask it. - Very specific: line 30
No cloning large state trees: Use evaluate_with_resolver with a closure.
- Very specific: line 32
No cloning
Stringvalues for read-only access: Use s.as_str() for Value::String branches. - Very specific: line 33
Pre-allocate buffers: Use Vec::with_capacity / String::with_capacity when size is known or estimable.
- Very specific: line 36
No deep-cloning protocol or state per request: Use Arc<T> with clone-on-write or snapshot swapping.
- Very specific: line 46
Path-indexed targeted updates: When an @observable changes, only bindings referencing that property are visited - not the entire template.
- Very specific: line 47
DOM cloning over innerHTML: Use cloneNode(true) from cached template fragments.
- Very specific: line 51
No
for..inon objects: Use Object.keys() with an indexed for loop — faster and prototype-safe without needing Object.hasOwn. - Very specific: line 57
No per-update array allocations: Avoid .filter(), .map(), .slice() in the update hot path.
- Very specific: line 70
No
for..inon objects: Use Object.keys() with an indexed for loop. - Distinctive: line 121
When making a performance-related change, report:
- Distinctive: line 123
Allocation count delta: if measurable
“Common” is measured: kept by at least 6 in 10 of the 14 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Performance
WebUI's value proposition is speed and low memory usage. Every change to core Rust crates, @microsoft/webui-framework, or @microsoft/webui-router must be evaluated through two lenses: throughput (how fast) and memory (how little).
Server memory is not cheap. Client memory is not unlimited. Every allocation that can be avoided is a win on both sides.
Use this skill when modifying any performance-sensitive code across the stack.
Rust - speed rules
These apply to webui-handler, webui-state, webui-expressions, webui-parser, webui-protocol, webui-ffi, and webui-node.
- No
format!()in writer output. Use sequentialwriter.write()calls.format!allocates a temporaryStringevery invocation. - No
.to_string()onCow. WriteCow<str>directly to avoid defeating zero-copy. - No
collect::<Vec<_>>()on splits. Iteratepath.split('.')directly. Collecting allocates aVecfor sequential access. - No redundant scans. Use
first_part.len() == path.len()instead ofpath.contains('.'). - No
String::from(ch)in escape loops. Usech.encode_utf8(&mut buf)with a[u8; 4]stack buffer, or batch contiguous safe chars into a single write. - No
format!in hex parsing. Use direct arithmetic ((hi_nibble << 4) | lo_nibble) instead ofu8::from_str_radix(&format!(...)). - No per-request template re-parsing. Pre-parse at protocol load time and reuse.
- No silent
unwrap_ordefaults. Ifbinding_stack.pop()returnsNone, that's a protocol error - propagate it, don't mask it. - Keep cold error/diagnostic construction off the hot path. Mark error builders
#[cold]/#[inline(never)]so they don't inline into hot functions and perturb their code layout. Adding cold error code with no hot-path work has regressed parse benches ~4-5% purely via layout - keep per-element fast-paths inlinable and push the cold fallback out-of-line. Seeskills/diagnostics/SKILL.md§7.
Rust - memory rules
- No cloning large state trees. Use
evaluate_with_resolverwith a closure. Cloning duplicates the entire JSON tree in memory. - No cloning HashMaps for scope. Save/restore only the overwritten key on loop iteration. A HashMap clone copies every entry.
- No cloning
Stringvalues for read-only access. Uses.as_str()forValue::Stringbranches; only create owned strings forNumber/Boolvia a scratch buffer orCow. - Pre-allocate buffers. Use
Vec::with_capacity/String::with_capacitywhen size is known or estimable. For HTML output, 4096 bytes is a reasonable starting point. - Prefer
&strand slices over owned types. Pass by reference when the callee only reads. Move clone decisions to the caller. - Use
Cow<'_, str>when a value is sometimes borrowed, sometimes owned. Avoids unconditional allocation. - No deep-cloning protocol or state per request. Use
Arc<T>with clone-on-write or snapshot swapping. - Cap memory for untrusted inputs. File reads during discovery must have size limits. A 100MB HTML file should not cause OOM.
TypeScript - @microsoft/webui-framework rules
These apply to packages/webui-framework (the client-side Web Component runtime).
Speed
- Single-pass hydration. The framework walks the DOM once to connect all bindings. No multi-pass scanning.
- Path-indexed targeted updates. When an
@observablechanges, only bindings referencing that property are visited - not the entire template. - DOM cloning over innerHTML. Use
cloneNode(true)from cached template fragments. Never useinnerHTMLfor component creation. - Direct event listeners. Attach
@eventbindings to the bound element, never a shared render root.$wireEventsruns once per block instance, so delegating stacks one listener per block on the same node and fires all of them per dispatch — O(N) for no reduction in listener count. - Microtask coalescing. Multiple property changes within the same synchronous block batch into a single DOM update via
queueMicrotask. - Cursor-based repeat reconciliation.
<for>block updates use a diff algorithm that only callsinsertBeforeon nodes that actually moved. Append/prepend/remove are O(1). - No
for..inon objects. UseObject.keys()with an indexedforloop — faster and prototype-safe without needingObject.hasOwn. Applies tosetState,setInitialState, and any code iterating user-provided objects.
Memory
- No framework in the GC. Minimize object allocations during reactive updates. Reuse binding objects, don't recreate them.
- Template cache is
WeakMap-keyed. Parsed template DOMs are cached per metadata object. When metadata is released (e.g., viaRouter.gc()), the cache entry becomes GC-eligible. - No per-update array allocations. Avoid
.filter(),.map(),.slice()in the update hot path. Use index-based iteration. - Strip SSR markers after hydration. Comment nodes used as markers are removed from the DOM once wiring is complete - they don't persist as memory overhead.
- Scope frames are stack-allocated.
<for>loop item variables use a linked-list scope chain, not cloned Maps or Objects.
TypeScript - @microsoft/webui-router rules
These apply to packages/webui-router (the client-side SPA router).
Speed
- Server does route matching. The client does not re-match routes. The server returns the matched
chainarray; the client diffs old vs new and mounts only changed components. - Lazy loading via dynamic import. Route component JS is fetched only on first navigation to that route.
- Chain diffing, not full remount. Navigating between sibling routes preserves parent components. Only the changed level is remounted.
- No
for..inon objects. UseObject.keys()with an indexedforloop.for..inwalks the prototype chain (slow) and requires anObject.hasOwnguard to be safe —Object.keysis both faster and prototype-safe in one call:// ✗ Bad: slow, prototype-unsafe without guard for (const key in obj) { ... } // ✗ Still bad: correct but slower than Object.keys for (const key in obj) { if (Object.hasOwn(obj, key)) { ... } } // ✓ Good: fast, prototype-safe, no guard needed const keys = Object.keys(obj); for (let i = 0; i < keys.length; i++) { ... }
Memory
- Release unused templates.
Router.gc()clears cached component templates for routes the user hasn't visited recently. Active route components are never released. - Inventory bitmask prevents duplicate downloads. The server tracks which component templates the client already has via a bitmask. Re-navigation never re-sends templates.
- Minimal state per navigation. Route-scoped state means the JSON partial contains only what the active route needs, not the full app state.
Measuring
Server benchmarks
cargo bench -p microsoft-webui --bench contact_book_bench # full run
cargo bench -p microsoft-webui --bench contact_book_bench -- --test # quick validation
cargo bench -p microsoft-webui --bench server_request_bench # high-level request helper
cargo xtask bench all # all Rust crates
cargo xtask bench node-addon # Node/V8/N-API boundaryCompare Render/1000 P50 before and after. For Node changes, save with
--save-baseline before and compare with --baseline before. Verify output
Bytes is unchanged (same HTML = correct behavior).
Client performance
window.addEventListener('webui:hydration-complete', () => {
for (const entry of performance.getEntriesByType('measure')) {
if (entry.name.startsWith('webui:hydrate:')) {
console.log(`${entry.name}: ${entry.duration.toFixed(1)}ms`);
}
}
});What to report
When making a performance-related change, report:
- Before/after benchmark numbers (P50 latency, throughput)
- Allocation count delta if measurable
- Output size unchanged (proves correctness)
- Memory profile for memory-related changes (heap snapshots, RSS delta)
Other versions20 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 20
- alamenai/terrae★ 245same name
- OutThisLife/brooklyn-skills★ 207same name
- zeuikli/claude-code-workspace★ 155same name
- epicsagas/epic-harness★ 19same name
- jmylchreest/aide★ 19same name
- QAInsights/perf-skills★ 16same name
- fullymiddleaged/Clawness★ 4same name
- umararshad4/honey-stack★ 4same name
- JustinK33/foreman★ 3same name
- wangqiqi/cursor-ai★ 3same name
10 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
Used alongsideProjects with it also use scaffold, test and 10 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
MicrosoftSkillscaffold
Also in 3 projects that use this
Microsoft AzureSkilltest
Also in 6 projects that use this
0xSeroSkillsecurity
Also in 4 projects that use this
GitHubSkillrefactor
Surgical code refactoring to improve maintainability without changing behavior. Covers extracting functions, renaming variables, breaking down god functions, improving type safety, eliminating code smells, and applying design patterns. Less drastic than repo-rebuilder; use for gradual improvements.
Also in 6 projects that use this
AnthropicSkilldebug
Structured debugging session — reproduce, isolate, diagnose, and fix. Trigger with an error message or stack trace, "this works in staging but not prod", "something broke after the deploy", or when behavior diverges from expected and the cause isn't obvious.
Also in 7 projects that use this
Microsoft AzureSkilldesign
Design rules and conventions for the API Center Portal. Use when editing detail pages, card components, badges, layout, navigation, sidebars, or headers. Covers badge styling, metadata placement, page navigation patterns, and layout alignment.
Also in 5 projects that use this
- +1 more from Azure
In this repository11 other files it gives its agents.
- .github/copilot-instructions.mdCopilot instructions
- webui-referenceSkill
- bump-versionSkill
- code-reviewSkill
- create-exampleSkill
- diagnosticsSkill
- docs-syncSkill
- prSkill
- quality-gateSkill
- testingSkill
- webui-devSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

