agentleFS
NVIDIAKnown publisherNVIDIA/elements/.agents/skills/guidance-webgpu-performance/SKILL.md

guidance-webgpu-performance

Skill115 starsChanged 55 days agoApache-2.0View on GitHub

Diagnose and improve browser WebGPU rendering performance, including frame pacing, draw and state-submission overhead, buffer uploads, shaders, and JavaScript work on the render critical path. Use for slow or stuttering GPU-backed interfaces, rendering regressions, CPU/GPU bottleneck analysis, renderer performance changes, or WebGPU resource, timing, diagnostic, and lifecycle test suites; do not use for general page-load, build performance, or CPU-only benchmark work.

The file

Show its rules and text

We split this skill into the rules it gives an agent

19 rules. About 0 are common, 15 are distinctive, and 4 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈15

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Read the repository AGENTS.md and the affected project's DEVELOPMENT.md.

    line 12
  2. Very specific:

    Before adding or changing a benchmark, inspect the affected package's package.json, local Vitest benchmark configuration, existing …

    line 14
  3. Distinctive:

    Read the performance diagnostic playbook when classifying a bottleneck, selecting instrumentation, or proposing an optimization.

    line 15
  4. Very specific:

    Read the reusable WebGPU test suite guide when adding or reviewing a *.test.webgpu.ts suite, choosing a test mode, or deciding whether a …

    line 16
  5. Distinctive:

    Use independent CPU and GPU evidence plus controlled perturbations.

    line 30
  6. Distinctive:

    Use diagnostic toggles that preserve most of the pipeline while removing one class of work.

    line 35
  7. Distinctive:

    If the evidence remains ambiguous, propose the smallest next experiment instead of recommending a large rewrite.

    line 38
  8. Distinctive:

    Treat an ordinary Vitest benchmark as a CPU microbenchmark unless its configured environment and measured callback show otherwise.

    line 44
  9. Distinctive:

    Follow the affected package's established patterns:

    line 46
  10. Distinctive:

    Create representative typed-array sources outside the timed callback when source creation is not under test.

    line 49
  11. Distinctive:

    Place construction inside the callback only when allocation or initialization is intentionally part of the measurement.

    line 50
  12. Distinctive:

    Use scaling series such as record count, changed percentage, and consumer fan-out to identify complexity and crossover points.

    line 52
  13. Very specific:

    Run commands from the affected project through mise and only when its DEVELOPMENT.md defines the script:

    line 56
  14. Distinctive:

    Keep baseline and candidate environment, workload, benchmark options, and worktree state comparable.

    line 64
  15. Distinctive:

    Use the shared Node-hosted Vitest configuration and Playwright runner when an investigation must exercise the production WebGPU renderer …

    line 68
  16. Distinctive:

    Keep these evidence classes separate:

    line 71
  17. Distinctive:

    Prefer reducing repeated work on the confirmed limiting path:

    line 81
  18. Distinctive:

    Treat advanced staging rings, indirect drawing, shader or compute rewrites, data-layout changes, and WebAssembly as experiments with added …

    line 89
  19. Distinctive:

    When the user asks only for diagnosis, report findings without changing code.

    line 95

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Optimize WebGPU Performance

Find the limiting resource before changing the renderer. Produce a reproducible diagnosis that separates JavaScript preparation, browser/API submission, data transfer, and GPU execution, then make only changes supported by measurements.

Required context

  1. Read the repository AGENTS.md and the affected project's DEVELOPMENT.md.
  2. Inspect the render loop, update path, buffer and texture ownership, shader code, and resource lifecycle involved in the representative workload.
  3. Before adding or changing a benchmark, inspect the affected package's package.json, local Vitest benchmark configuration, existing *.test.bench.ts files, and any shared configuration they import. Do not assume another project's harness applies unchanged.
  4. Read the performance diagnostic playbook when classifying a bottleneck, selecting instrumentation, or proposing an optimization.
  5. Read the reusable WebGPU test suite guide when adding or reviewing a *.test.webgpu.ts suite, choosing a test mode, or deciding whether a performance task belongs in CI.

Establish the performance question

Define the workload and target before measuring:

  • Separate initialization, steady rendering, interactive updates, streaming updates, picking/readback, and cleanup. Do not combine them into one unexplained metric.
  • Record object and primitive counts, update frequency and size, draw/pass counts, canvas pixel dimensions, device-pixel ratio, transparency, anti-aliasing, and relevant renderer settings.
  • Choose the user-visible metric: frame budget and tail latency, update latency, throughput, startup time, or memory. FPS alone can hide missed frames behind the display's refresh-rate ceiling.
  • Preserve correctness and representative visual output. A faster result that omits required work is not an optimization.
  • Inspect git status --short and preserve unrelated changes. Record when measurements include a dirty worktree.

Classify before optimizing

Use independent CPU and GPU evidence plus controlled perturbations. Do not infer a GPU bottleneck from low FPS or a CPU bottleneck from a busy render callback alone.

  1. Measure frame intervals and the JavaScript phases that prepare data, update scene state, encode commands, and submit work.
  2. Measure GPU pass duration asynchronously when the API and adapter expose timer queries. Treat the absence of timer-query support as a measurement limitation, not as zero GPU cost.
  3. Vary one dimension at a time: object or draw count, changed-record count, upload bytes, primitive count, canvas pixels, transparency, or pass count.
  4. Use diagnostic toggles that preserve most of the pipeline while removing one class of work. Compare render-disabled, update-frozen, upload-bypassed, reduced-resolution, and reduced-shader-cost cases as applicable.
  5. Classify the evidence as JavaScript/GC, API submission or state churn, transfer/synchronization, vertex/geometry, fragment/fill, shader compilation, resource allocation, or mixed/unknown.

If the evidence remains ambiguous, propose the smallest next experiment instead of recommending a large rewrite.

Use repository CPU benchmarks correctly

Discover the affected project's test:bench script, benchmark config, and *.test.bench.ts files before extending them. The repository's shared Vitest library benchmark configuration recognizes src/**/*.test.bench.ts, but the package's local config and DEVELOPMENT.md determine how to run it and what environment it uses.

Treat an ordinary Vitest benchmark as a CPU microbenchmark unless its configured environment and measured callback show otherwise. Timing data generation, validation, packing, dirty-range handling, or calls that prepare upload bytes does not measure GPUQueue.writeBuffer, command execution, shaders, presentation, or frame pacing.

Follow the affected package's established patterns:

  • Preserve its benchmark options so baseline and candidate results remain comparable. If the package has no precedent, choose explicit warmup, duration, and iteration settings and document them.
  • Create representative typed-array sources outside the timed callback when source creation is not under test.
  • Place construction inside the callback only when allocation or initialization is intentionally part of the measurement.
  • Compare steady-state reuse with replacement or growth, partial with full commits, and ordinary with worst-case data when those paths differ.
  • Use scaling series such as record count, changed percentage, and consumer fan-out to identify complexity and crossover points.
  • Consume results or state transitions so the benchmark exercises the measured path.
  • Name benchmarks with the workload size and operation. Add a paired reference when the result is otherwise difficult to interpret.

Run commands from the affected project through mise and only when its DEVELOPMENT.md defines the script:

mise exec -- pnpm run test:bench
mise exec -- pnpm run test:bench -- --outputJson=benchmark.json
mise exec -- pnpm run test:bench -- --compare=benchmark.json

Keep baseline and candidate environment, workload, benchmark options, and worktree state comparable. Use browser instrumentation for any claim about GPU execution or end-to-end rendering.

Use repository WebGPU test tooling

Use the shared Node-hosted Vitest configuration and Playwright runner when an investigation must exercise the production WebGPU renderer without adding the Vitest browser client to the measured page. Import the configuration, runner, utilities, and types from @internals/vite/webgpu; do not use the root package export or runner deep imports in new consumers.

Keep these evidence classes separate:

  • check mode uses headless software WebGPU for deterministic API-call, resource, upload, interaction, and cleanup invariants. Only this mode belongs in ordinary hosted CI, and it must not contain timing budgets.
  • measure, diagnostic, and lifecycle modes require a native adapter and belong on a controlled local or dedicated GPU runner. Reject software fallback before interpreting results.
  • test:bench remains a CPU/browser microbenchmark workflow. Use it for local baseline/candidate comparisons, but keep it out of required PR CI unless the repository adopts controlled runners and an explicit baseline policy.

The consuming package owns its workload page, representative profiles, assertions, budgets, production-boundary rules, and scripts. The shared tooling owns browser and server lifecycle, adapter selection, external WebGPU observation, environment capture, DevTools traces, memory snapshots, statistics helpers, and artifact writing. See the reusable suite guide for the workload contract, observer limitations, Wireit setup, and validation rules.

Select evidence-backed changes

Prefer reducing repeated work on the confirmed limiting path:

  • For JavaScript cost, look for per-frame allocation, repeated conversion or validation, matrix and bounds work, duplicate fan-out, cache invalidation, and avoidable DOM/reactive work.
  • For submission cost, reduce redundant state changes and API crossings; batch compatible draws or use instancing when the workload has enough repeated geometry to justify it.
  • For upload cost, reuse capacity, merge dirty ranges, batch compatible uploads, separate data by update frequency, and avoid creating upload views or typed arrays in hot loops.
  • For GPU cost, test culling, level of detail, overdraw and transparency, render resolution, attachment formats, anti-aliasing, texture sampling, and shader work according to the measured scaling behavior.
  • For initialization cost, reuse pipelines and resources, avoid duplicate compilation, and consider creation-time mapping only for static data.

Treat advanced staging rings, indirect drawing, shader or compute rewrites, data-layout changes, and WebAssembly as experiments with added complexity. Require evidence that a simpler change cannot meet the target.

Also inspect bind-group and pipeline reuse, write frequency, buffer-offset alignment, command/pass structure, shader compilation, texture and attachment churn, and asynchronous mapping or readback behavior.

Verify and report

When the user asks only for diagnosis, report findings without changing code. When the user asks for an improvement, implement the smallest supported change and verify:

  1. the targeted baseline/candidate measurement under the same conditions;
  2. an integration measurement that exercises the real browser renderer when the claim extends beyond CPU preparation;
  3. relevant correctness, visual, and project tests from DEVELOPMENT.md;
  4. memory, variance, and another workload size when the change can trade one regime for another.

Report the workload, environment, measurements and spread, bottleneck classification, evidence, change or recommendation, confidence, and remaining uncertainty. State explicitly whether each result is a CPU microbenchmark, JavaScript frame measurement, GPU timer result, or end-to-end observation.

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.