
Pixijs Performance
Profile and fix PixiJS v8 FPS jank, draw calls, GPU memory, and culling using documented destroy, GC, batching, and pooling patterns.
Overview
pixijs-performance is an agent skill most often used in Ship (also Build frontend) that guides profiling and optimization of PixiJS v8 apps for FPS, draw calls, GPU memory, and culling.
Install
npx skills add https://github.com/pixijs/pixijs-skills --skill pixijs-performanceWhat is this skill?
- Profile-first workflow: browser DevTools Performance and GPU profiling before micro-optimizations
- Destroy patterns: cacheAsTexture toggle, releaseGlobalResources, container.destroy({ children: true })
- GCSystem via Application init: gcMaxUnusedTime and gcFrequency (textureGC.* deprecated since 8.15.0)
- CullerPlugin, cullable, cullArea for offscreen culling; object pooling and batching rules
- BitmapText for dynamic text; cross-links to pixijs-scene-container and scene-core skills
- textureGC.* properties deprecated since PixiJS 8.15.0—use gcMaxUnusedTime and gcFrequency on Application init
Adoption & trust: 1.4k installs on skills.sh; 206 GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your PixiJS v8 app stutters, draw calls spike, or GPU memory climbs because destroy, GC, batching, or culling are misconfigured.
Who is it for?
Indie game or interactive UI devs on PixiJS v8 who have a reproducer for jank or leaks and want agent-guided fixes tied to official APIs.
Skip if: Greenfield projects with no performance symptom yet, or teams not using PixiJS (use your engine’s profiling skill instead).
When should I use this skill?
Profiling or optimizing PixiJS v8 for FPS, draw calls, or GPU memory; triggers include jank, batching, GCSystem, PrepareSystem, Culler, cacheAsTexture, memory leak, destroy patterns.
What do I get? / Deliverables
After profiling, you apply the matching PixiJS v8 pattern—destroy, pool, batch, cache, or cull—and align GC init with current 8.15 APIs.
- Identified bottleneck from profiling
- Applied destroy/pool/batch/cache/cull changes in code
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Performance tuning is canonical on the ship/perf shelf once a PixiJS app exists, even though profiling often starts during active frontend build. Subphase perf matches FPS, draw-call batching, memory leaks, and PrepareSystem/GC tuning called out in triggers.
Where it fits
Choose render groups and text strategy before shipping a particle-heavy scene.
Profile GPU memory after level transitions and apply destroy plus GC init tuning.
Triage production reports of mobile FPS collapse with culling and BitmapText swaps.
How it compares
PixiJS-specific perf playbook—not a generic Lighthouse or React memoization skill.
Common Questions / FAQ
Who is pixijs-performance for?
Frontend and game developers using PixiJS v8 who can run Chrome DevTools and edit TypeScript render loops.
When should I use pixijs-performance?
When triggers hit—FPS, jank, draw calls, batching, object pool, GCSystem, PrepareSystem, Culler, cacheAsTexture, memory leak, destroy patterns—or during ship perf passes on an existing canvas.
Is pixijs-performance safe to install?
The skill is MIT-licensed documentation for code changes in your repo; confirm install source safety via Prism Security Audits on this page.
SKILL.md
READMESKILL.md - Pixijs Performance
Profile before optimizing. PixiJS handles a lot of content well out of the box; browser DevTools Performance + GPU profiling should be your first move. Once you've found the bottleneck, apply the targeted pattern below (destroy, pool, batch, cache, or cull). ## Quick Start ```ts container.cacheAsTexture(true); container.updateCacheTexture(); container.cacheAsTexture(false); container.destroy({ children: true }); import { CullerPlugin, extensions } from "pixi.js"; extensions.add(CullerPlugin); offscreenContainer.cullable = true; offscreenContainer.cullArea = new Rectangle(0, 0, 256, 256); // Tune GC via init options (ms). The `textureGC.*` properties are // deprecated since 8.15.0 — use these on the Application init instead. await app.init({ gcMaxUnusedTime: 60_000, gcFrequency: 30_000 }); ``` **Related skills:** `pixijs-scene-container` (destroy options), `pixijs-scene-core-concepts` (render groups, layers, culling), `pixijs-scene-text` (BitmapText for dynamic content), `pixijs-assets` (atlasing), `pixijs-custom-rendering` (custom batchers). ## Core Patterns ### Proper destroy with cleanup ```ts import { Sprite, Assets } from "pixi.js"; const texture = await Assets.load("character.png"); const sprite = new Sprite(texture); // Destroy sprite only (preserve texture for reuse) sprite.destroy(); // Destroy sprite AND its texture sprite.destroy({ children: true, texture: true, textureSource: true }); ``` When done with a loaded asset entirely: ```ts Assets.unload("character.png"); ``` This removes it from the cache and unloads the GPU resource. ### Application destroy/recreate cycle ```ts import { Application } from "pixi.js"; // Correct destroy that cleans global pools app.destroy({ releaseGlobalResources: true }); const newApp = new Application(); await newApp.init({ width: 800, height: 600 }); ``` Without `releaseGlobalResources: true`, pooled objects (batches, textures) from the old app leak into the new one, causing flickering and corruption. ### Texture garbage collection PixiJS auto-collects unused textures and GPU resources via `GCSystem`. Defaults: checks every 30 seconds, removes resources idle for 60 seconds. These are time-based (milliseconds). ```ts import { Application } from "pixi.js"; const app = new Application(); await app.init({ gcActive: true, gcMaxUnusedTime: 120000, // idle time before cleanup in ms (default: 60000) gcFrequency: 60000, // check interval in ms (default: 30000) }); ``` For manual control: ```ts texture.source.unload(); // immediate GPU memory release ``` ### PrepareSystem for GPU upload Upload textures and graphics to GPU before rendering to avoid first-frame hitches: ```ts import "pixi.js/prepare"; import { Application, Assets } from "pixi.js"; const app = new Application(); await app.init(); // Don't render until assets are uploaded app.stop(); const texture = await Assets.load("large-scene.png"); // Upload to GPU ahead of time await app.renderer.prepare.upload(app.stage); // Now rendering won't hitch on first frame app.start(); ``` `prepare.upload()` accepts a Container (uploads all textures, text, and graphics in the subtree) or individual resources. ### cacheAsTexture for performance `cacheAsTexture()` renders a container's subtree to a single texture, reducing draw calls for complex static content. Internally it creates a render group and caches the result. **When to use:** - Many static childre