4 ms·
The "No. There is no additional overhead. Components participate in a unified renderloop outside of React. It outperforms Threejs in scale due to Reacts schedul
by vvanders 5y ago
The "No. There is no additional overhead. Components participate in a unified renderloop outside of React. It outperforms Threejs in scale due to Reacts scheduling abilities." made me do a serious double-take.
If you want to go fast in this space then you need to care about data layout and how the system is structured end-to-end. Calling a function per object is going to hit a wall regardless of how you schedule.
Hundreds/Thousands of updates is not small but it's also not massively impressive either. I've done ~2,800 node scene graphs on underpowered ARM chips back in '09 at 60FPS including rendering. You have to use NEON, and be aware of your caches. No scheduling magic is going to change that unless you're just deferring work which sounds like what may be happening there.
FWIW I've also done this in Java via FlatBuffers(which uses ByteBuffer internally) to keep data coherency when driving animations frames so it doesn't require dropping down to C/C++/Rust(although C#'s value types do make it easier).
- brundolf 5y agoIt's interesting because in normal React usage, the overhead of generating and throwing away a bunch of objects on each update is dwarfed by the cost of updates to the DOM But in Three.JS the actual updates to the tree should be cheap, right? There's no reflow, you're just setting values in memory to be used by the next render frame. If so, that changes the calculus. There's also the fact that in an app, it's rare for actual state updates (and therefore React renders) to happen on every frame; usually it's only on interactions. Maybe the occasional animation (if it can't be handled by native CSS animations). Whereas in graphical contexts like this, it's much more likely you'll have lots of objects in continuous motion (and therefore continuous re-renders). I can see the productivity gains being worth it for a lot of simpler use-cases, but I'm skeptical about the performance claims when you start to get into complex scenes with lots of entities.
- vvanders 5y agoYeah, I can totally see the argument that it's a programming model that's well understood and you can get a productivity boost from that. However I don't think you can say that doesn't come with a cost, otherwise it would have been pretty widely adopted across the industry.
- brundolf 5y ago> otherwise it would have been pretty widely adopted across the industry I'm not sure that's a fair explanation for why. It's totally possible to come up with new paradigms that are useful even though nobody's thought of them before. I would think the main issue will be around JavaScript's tendency (cultural, syntactic, etc) to casually create and release objects all over the place, constantly. There's nothing intrinsically wrong with this, but it seems problematic for this use-case. Example: JavaScript doesn't have named function parameters, because instead you just create and destructure an object: function foo({ param1, param2, param3 }) { } foo({ param1: 'a', param2: 'b', param3: 'c' }) The syntax encourages this, the React docs encourage this. JSX itself does this for every element you render. And for normal JavaScript usecases it works just fine. But when you're running this logic every frame, I would guess it will limit you at a certain point. Despite that, I think people are onto something with the broader idea of coding a 3D scene declaratively. I'm just skeptical that React or its norms are the right path to doing it at scale.
- vvanders 5y agoHierarchical component based designs have been around in game-dev for ages. I first used them in '05 but I remember prior art even before then. It was pretty common to have a declarative way to define components(usually through a scripting language like Lua or sometimes custom DSL). I agree on the performance aspect, any inner-loop stuff always was down in a native language or heavily JIT'd path, but even then data layout drove it even more which usually required structuring the upstream systems ahead of the core logic. It's the reason why there's no "one-size fits all" game engine. They all make very discrete trade-offs in terms of entity counts, open world vs constrained layout and the like.
- tylerhou 5y agoPractically, if that function is somewhat hot, I wouldn't be surprised if V8 omitted the allocation altogether when generating optimized bytecode — internally, properties on objects already have an "order," so V8 could push each property into the stack in that order/reverse order (depending on calling convention). And if it doesn't yet, that's not a difficult optimization to make.
- short_sells_poo 5y agoI can't take a 3d rendering framework seriously if it gets bogged down at updating 2000 untextured and non-interacting cubes @ 60 FPS. What on earth is all that time spent on? Doing ~2000 3x3 matrix ops should take a modern processor a few hundred usec surely? To put the silliness of the 2000 number in context, look here at a showcase of the Unity ECS system from years (!) ago: https://software.intel.com/content/www/us/en/develop/articles/get-started-with-the-unity-entity-component-system-ecs-c-sharp-job-system-and-burst-compiler.html https://software.intel.com/content/www/us/en/develop/article... Their starting setup achieves 16000 textured and complex (relatively) models @ 30fps. Which is already much more than the "optimized" thing is achieving here. And it doesn't "cheat" by pretending to be fast via simply not doing to updates that are expected. And once they apply the various optimizations with memory layout etc... they get to 150000 (!) textured models moving about on screen @ 30 fps. So let's say 75000 @ 60fps, which is more than 35x as many objects, and the objects are much more complex. Am I missing something? Why is "2000 cubes @ 60fps" extraordinary?
- Jasper_ 5y agoYou have to remember that this 700ms overhead is not the renderer. It's just setting fields on the underlying Three.JS Cube objects. The Three.JS renderer runs fine, and I don't even consider Three.JS to be a fast renderer. So yes, the overhead of React-Three-Fiber's tree reconciliation is seemingly massive. No, I do not have any answers for what it is doing. Nor do I have any guesses.
- short_sells_poo 5y agoThanks for clarifying. 700ms overhead is massive. It sounds like the approach is just deeply suboptimal for any sort of high performance and complicated 3d scenes. Perhaps that was not their objective...
- mlsarecmg 5y agothere were multiple versions of that test, the fist had nothing to do with the subject matter, the ones that people refer to (spinning cubes) had an artificial delay that was added to simulate cpu stress.
- hitekker 5y agoThe claim that a general purpose web frontend framework adds no overhead to GPU intensive animation is indeed bizarre. The author seems to believe his own marketing that his framework is the end-all-be-all.