Why you shouldn't build (some) games in react (or other declarative UI frameworks)
With React's popularity still staying strong, it's only natural it's used in a wide veriaty of situations. Animations and visual effects, interfactes for industrial machinery, router config etc. Recently, I've also seen a number of games try to use react. The result is... mixed.
What is react good at?
React translates state to UI. You just say this number should be 100 and it will set the visual UI to 100. It does this very efficiently, autmatically deciding what should be updated and what not. Modifying DOM elements is very expensive so it makes sense to have a lot of complex code to limit these, even if the code itself is also expensive.
This is great for most apps. The basic layout rarely changes, only changing some numbers or labels here and there, occasionally adding or removing a element. React is great for this, and it's efficiency really pays off.
In most apps, the layout is a lot more complex than the state. React also really helps here. In a typical layout mostly consists of elements that have fixed places always with just a occasional place where dynamic content is inserted. React is also great for this, since you can define much HTML in one component and just use dynamic elements and other components where nececairy.
What do games do?
Games are different:
- State is complex, typically you need to store the position of many loose objects. Each will also have many other attributes like health, AI, etc.
- HTML is simple, most objects will just be a
<img>
tag with atransform
attribute. Maybe with some divs for a health bar or for a label. - Mostly everything updates at once. Every object moves when the player moves, enemies move, even background objects animate.
- Weak hirarchy. Many objects directly in a single big parent
- Objects need to update themselves outisde of render
React is very bad at this.
- Because most objects have a lot of hidden state it won't be able to tell if a object even needs a update.
- All it's logic to find the "minimal" update is wasted if everything needs to update.
- There is no clear distinct update and render step. You need to build this yourself but the component hirarchy makes this very difficult.
Thse disadvantages don't apply to every game. Incremental games can make very good use of react since they only update a little at a time. Even more complex games can potentially use React just for the UI and HUD. However, any game with many moving objects or a moving background will experience severe performance issues.
HTML is bad for games
Many of the issues with react apply to HTML in general. Browsers need to update the layout every time a element is updates which is very slow. Avoiding these updates is one of react's machinery strength. Even without react you will find it's really hard/impossible to get a game to run at a reasonable speed by maninipulating DOM elements.
Use canvas
Luckly, we have canvas. Canvas has many advantages for games:
- Updates are fast. In fact there is no difference between moving and not moving a object since you need to draw everything every frame anyway.
- Good support for moving POV: You can use matrix transforms to "move" the camera so you don't need to keep track of the camera location in every object.
- Allows good code layout: The traditional layout of every object having a
draw
andupdate
method works again, and also efficiently. You can also implement a ECS system if you so desire. - Better support for shapes. In HTML everything is a rectangle secretly. While there are ways to embed other shapes in rectangles they are complex and slow down performance even more. Canvas supports a wide veriaty of shapes.
In general, canvas is designed for games or game-like applications with many moving objects, animations, moving field of view, etc. So use it.