I've been doing a lot of gamedev and performance tuning in JS, and I do a fair bit of object pooling, but I don't think I've ever found a case where I was able to measure any actual impact on performance from it. It seems like either modern JS engines (well, v8) are incredibly good at dealing with small short-lived objects, or maybe my specific use cases aren't heavy enough for pooling to be meaningful.
Yeah, I suspect this is one of those things where when you Google it, people are mostly like "why would you ever need pooling in JS," but then it turns out pooling is used under the hood in a lot of game frameworks.
I know Ecsy[1] is using it, which makes sense because that's targeted at apps building for WebVR which really cannot afford GC pauses, so I guess it must have some merit.
I guess I could try monkey-patching immer to have it pull from a pool when creating new objects? Theoretically if it just used nominal typing (re: classes) to pick objects out of the pool and overwrite all the fields on it, as I assume it normally would do with a brand-new object, this could work out okay. Could just do pooling on the top-level component objects and deal with GC on any nested objects to simplify things (especially because nested objects probably wouldn't have classes associated with them).
1) Isn't that tick rate not frame rate? Is there really a tangible benefit to rendering 140fps over 60? I always read that beyond 60 had huge diminishing returns and was hard to detect as a human.
2) Is it really necessary for anything beyond a competitive shooter with bullets flying around? Outside of the bullets, fighting games are as or more precise than the average shooter and 60fps continues to be the standard there and I don't think >60 tick rate would bring any big value to a fighting game. A 60fps game with no buffer can already yield situations that are close to or beyond human execution (see: Melee)
I'm not actually sure requestAnimationFrame() in a browser ever gets you >60 fps. At that point, honestly, you'd probably need an independent render thread (doing some degree of interpolation) and stick to a 60fps logic tick. Which you can theoretically do in JS using web workers, though I know message-passing incurs some serious overhead in that case.
Depends on the browser, but at least in Firefox and Chrome it should match actual refresh rate if the graphics stack plays properly. (i.e. I don't know if it does if GPU acceleration doesn't fully work)
requestAnimationFrame absolutely supports higher than 60 FPS. You can also do all rendering off the main thread with OffscreenCanvas, though you can certainly hit 144 Hz or higher without doing that.
And the new Edge? Of browsers from major vendors at least, I thought Edge was worth mentioning since it recently overtook Firefox in desktop market share.
Phaser 3 (and its predecessor Phaser 2) provide helper code for managing object pools[1]. I can imagine any non-toy project takes advantage of pooling for speed when it can.
You should do this in both GC'd and non-GC'd languages. Obviously C/C++/etc give you more options for arenas and the like. If you have a well bounded upper limit there's a while lot of good reasons to preallocate(locality of data, GC pressure, etc).
Some engines I used to work with would assert() on malloc/free if it happened outside certain safe regions of execution.
I'm pretty sure most JavaScript games use object pooling extensively. GC is definitely an issue if you want to hit 60fps. Even for non-games actually.