How to Use React Compiler
freecodecamp.org
freecodecamp.org
I was expecting it to analyse dependencies and create automated useMemo calls around everything. I mean write regular, readable React code someone might write manually.
It does not do that, instead it creates a cache context. Something like a single useRef object and writes imperative code to check if a dependency has changed, look up the previous instance of a variable from the cache and use it etc. Also caches JSX segments and stuff.
This would work much faster I guess and would be easier to extend.
I assumed the svelte / solid / vue way of reactivity was the way forward for granular reactive apps. Avoiding unnecessary rerenders etc but the React compiler does a really good job and you get all the fine grained reactivity benefits for free. Without thinking about it in the code.
Optimizing compilers are neat.
Updating the "done" state of a single todo item nested in a list of todo items still causes an entire list (of possibly hundreds of items) to re-render.
In principle you can solve this with fully normalized state shape but in practice things like MobX (especially when combined with SolidJS) still provide the best ergonomics and separation of concerns with very little compromise.
I'm however excited to see what kind of DX improvements the compiler can bring to the table. Perhaps someone will have a good idea and we'll get something that's at the level of MobX.
If the react compiler is used, 999 of them will return their memoised result. 1 will need to be rendered again.
Which has an overhead but is still a huge gain compared to actually creating vnodes and diffing all render results for all items.
You are right, in case of fine grained reactivity, this could just trigger a render on the specific item. But for that to work, the framework will need to wire up 1000 subscriptions to prop changes, have proxy objects and shit like that. There is a larger initial overhead for that and the memoisation + brute force approach might be better at the end.
Would be interesting to design a realistic benchmark around this. IIRC Michel Weststrate (the author of MobX) had a realistic example based on draggable elements on diagrams, where the diagram link lines needed to be recomputed in realtime as you drag the boxes around.
Another realisitc option would be large dashboards made of tables where lots of data updates come in real time.
Although it’s nice not to worry as much about these optimizations (and I’m certainly not trying to put down the work that went into this compiler), something rubs me the wrong way about so much code generation sitting between the code I wrote and the state management I intended it to do.
I guess it’s because react has bitten me so much in this department in the past. I’m sure it’s smarter than I am, I doubt it’s wrong as often as I am, but it feels like it could potentially obfuscate issues or cause slight quirks that would be really, really difficult to debug. Of course it’s just an initial reaction rather than a rational concern based on an intimate understanding of the compiler.
Having said that, what the compiler does is different from what I expected but much simpler too. It’s easy enough to follow what it’s doing.
I’d like to see performance comparisons between apps with good state management practices without the compiler vs the same apps with no special state management and using the compiler. Is it worth this added complexity if you’re already familiar with React’s foot guns?
Similar trends is in other declarative frameworks even on native such as SwiftUI - its easy to write complex gui but harder to debug and easier to shoot yourself in the foot. Its just harder to reason how declerative code will be executed in all corner cases and you have to trust compiler will do its magic. Overall for me it seems a lot of SwiftUI app feels much slower and even Apple developer from time to time shoot themself in the foot. We are just trading developer experience with performance and debugging.
It's not about managing memoization in an automated way - even though that's also very nice - but rather the ability to compile closures and package them.
This way you can automate hydration.
The main pain point with SPAs is that you're generating huge packages since you have to ship all of your code at once.
Having a compiler gives you the ability to do tree shaking on a per-component basis.
This kind of automatic optimization was one of the reasons they pushed for function-based components ~6 years ago over class-based components. One of the main points was "you'll no longer need to think about shouldComponentUpdate()".
I quite regularly find myself looking over the fence as it were and genuinely can’t believe people would willingly work like that with the insane levels of complexity and nonsense that the React ecosystem has become in recent years.
Looks vaguely like Stockholm Syndrome from the outside
I find that hooks are fine when you want to do simple web-app stuff, like fetch from a db, post some data back. But once your effects get more complicated, like using web sockets, items with retries, play or queue async audio clips that have to be state managed with hooks—the house of cards comes crashing down and they are an absolute nightmare to work with.
They're such an anti-pattern that useRef has to be repurposed from a thing that was meant for holding a reference to an HTML element to a new thing that is used to hold state that doesn't trigger a lifecycle update—and there are many paradigms that you can find yourself in where the only path forward is to use refs, along side and inside of your otherwise lifecycle updated hooks. What kind of cluster f*#& is that.
But all the manual dependency tracking is a real hassle and is crying out for language-level support, to which this compiler brings us a step closer.
Hooks do seem to be gaining some traction in Flutter, FWIW.
And I wouldn't write complex modern applications in anything else, unless there's computationally heavy rendering going on. And even then, I would still try to keep other parts, like slower and not as expensive to render UI, in this paradigm.
I honestly can’t believe everyone willingly marched into this weird hooks land. I’m sure you get used to it but compared to other frameworks it’s such a chore. The more I use React the more I feel like the maintainers deliberately make it different from other stuff so that people get trained in “React” rather than “JS” and it becomes its own world.
/uj