Why does my PixiJS game stutter?
PixiJS is fast. That's why a stutter in a Pixi game is so annoying: the renderer can push tens of thousands of sprites, so when a frame drops, something else is going on. Myaku finds out what.
Add it to your game
npm install -D myaku<!-- index.html: before your game's script -->
<script type="module">import "myaku/auto";</script>
<script type="module" src="/src/main.ts"></script>That's all. Myaku hooks into PixiJS 8 through the same hook Pixi's own devtools use (__PIXI_APP_INIT__), so when your Application starts, myaku finds it on its own. Nothing to pass, nothing to wrap.
Ticker or renderer?
The first question with a slow Pixi frame is whether your game logic or the drawing took the time. Myaku answers it with two spans:
update: everything in your ticker listeners, the code you add withapp.ticker.add(…)render: Pixi's renderer drawing the stage
We checked this on a PixiJS 8 game by adding a ticker listener that busies itself for 3 ms: myaku reported update at 3 ms a frame, and render at 0.2 ms.
So a verdict on a slow frame reads like:
Frame 4,410 took 31 ms (budget 25 ms). The game's frame code ran 29 ms. Spans: update 27 ms, render 1.6 ms.
Your logic is the problem, not Pixi. To find which part, time your own systems:
import { myaku } from "myaku";
const profiler = myaku();
app.ticker.add((ticker) => {
profiler.span("movement", () => moveEntities(ticker.deltaMS));
profiler.span("collisions", () => checkCollisions());
});The usual PixiJS suspects
upload: new textures mid-play.Texture.from(canvas),Textobjects whose text changes every frame,RenderTextures created on the fly, or the first draw of a sprite whose texture wasn't uploaded yet. Myaku counts uploads and bytes per frame. Upload textures up front with the prepare plugin (import "pixi.js/prepare", thenrenderer.prepare.upload(…)), and preferBitmapTextfor text that changes often.gc: allocation per frame. NewPoints andRectangles in the ticker,filter/mapover display lists,getBounds()(which allocates) in hot loops. Reuse objects.compile: filters on first use. A new filter or custom shader compiles when first drawn. Warm it up behind a loading screen.- Lots of draw calls. If the frame is slow but your code was quick, myaku's verdict mentions draw calls when there are many. Fewer textures (atlases) and fewer blend mode and filter switches let Pixi batch more.
throttled: not your game. A covered or minimised window gets throttled by the browser, and myaku says so.
Numbers you can share
window.__MYAKU__.report() is plain JSON: p50, p95 and p99 frame times, hitches per minute, the worst hitches with verdicts, and the average cost of update, render and your own spans.
Get started with Myaku → · Spans and engines · Reading verdicts