>> Offloading a lot of DOM work to React makes it even lighter.
What exactly does this mean? The only thing that ever changes, as I mentioned, is the src of the image tags in these kinds of tiled maps. How do you get better performance for updating the src attributes in a grid of images of constant size (256x256 tiles or whatever) other than img.src = ''? That's literally the only DOM manipulation being done, there is no "magic".
Also you can reduce a lot of your mouse event handling stuff down to a single "reactive" (haha) callback by doing something like this: https://github.com/mikolalysenko/mouse-event. Instead of binding a bunch of different handlers, the browser's mouse events API is still bizarre after all these years. Should just be a single event that gets sent the state of control input.