11 ms·
What am I missing? You gave two examples: The first is replacing useMemo with some inline code that does the same thing, so, as far as I can tell that literall
by BigJono 2y ago
What am I missing? You gave two examples:
The first is replacing useMemo with some inline code that does the same thing, so, as far as I can tell that literally saves just one function call to useMemo but none of the actual work it does? How could that possibly have a performance impact?
The second is de-inlining (or whatever the proper word is) map(x => foo(x)) to save function definitions on each loop. I don't understand why a "React compiler" would be able to do this if a JS JIT compiler can't, what guarantee does it have that a JS compiler doesn't? This should be done by V8 or not at all.
Even though you have a whole paragraph on the cognitive load of an extra compilation step at the end of your post, which is bang on, IMO you don't even come CLOSE to explaining why this trade off is worth it.
I've been telling people for nine years that React is the best of the declarative DOM libraries because it has a simple line-for-line transform instead of a big complicated compilation step. It looks to me like we're just throwing that all in the bin for absolutely fuck all.
- ramesh31 2y ago>It looks to me like we're just throwing that all in the bin for absolutely fuck all. Welcome to the last 5 years of React development. React was "finished" with 17, but it's now a zombie project being filled with increasingly absurd feature sets serving as a promotion tool for bored Meta devs.
- meiraleal 2y agoFor me the start of the decline was actually React 16.8 with hooks.
- a_wild_dandan 2y agoNo accounting for taste, I suppose. For me, hooks were when React got amazing.
- ttfkam 2y agoNo accounting for taste, I suppose. For me, class components were absolutely horrid and hooks simply made it less horrid by comparison. I guess anything can seem amazing after you've been stuck in knee-deep mud.
- Izkata 2y agoHooks were how they re-added necessary functionality to function components that class components already had. They definitely didn't think it through.
- TonyAlicea10 2y agoThe big time/cognitive savings is in not having to manually keep track of what should be in the dependency array, which is what you have to do with useMemo. I don't explain why the trade off is worth it because I'm not convinced the trade off is worth it. I'm explaining because devs using React will need to know, I'm not trying to convince that it's the right choice.
- jhardy54 2y agoHow does this compare with ubiquitous lint rules that require hook dependency arrays to be exhaustive?
- naught0 2y agoPersonally, I semi-regularly encounter instances where this rule must be ignored else I achieve an infinite re-render loop. Other times, it can be ignored, like when you use a stable value in the body of the memo or effect, like state setters from `useState`. In practice this leads to ignoring the rule, disabling the rule with a comment (and potentially forgetting to add vital dependencies when the function is updated), or adding a bunch of unnecessary noise to the dep array.
- jhardy54 2y agoCan you give an example? In my experience these cases are often trivial to fix, and React provides some solid documentation on how to solve these: https://react.dev/learn/removing-effect-dependencies https://react.dev/learn/removing-effect-dependencies There absolutely might be cases that can’t be solved, so I’m hoping to break out of my bubble and learn what they are!
- beedrillzzzzz 2y agoFairly common: triggering a side-effect that uses some state value, only when a different piece of state changes. useEffect(() => { doSomething(someState) }, [otherState])
- codeflo 2y agoI mean, if you don't understand how specialized inlined code could be faster than a generic function, or how not creating temporary arrays could be faster than creating them, then it's clear that you can't see that there could be any benefit. I can't judge the React compiler yet, but in general, compilation steps don't cause cognitive load if they work. How many different levels of interpretation and compilation does V8 do? And do you care? Do you have to? No, and that's the point. Whether React Compiler reaches the same level of "it just works", we'll have to see.
- afavour 2y ago> How many different levels of interpretation and compilation does V8 do? This part is key to the OPs objection. They’re saying that V8 is a very capable optimizer (which it is), so why can’t it optimize the things React Compiler optimizes? It’s a fair question. > compilation steps don't cause cognitive load if they work Personally I disagree. Any source code transformation adds cognitive load because my original source code now doesn’t match the source in the browser. Source maps are the traditional answer to that but if React is rewriting logic (like getting rid of arrays) you’re not going to be able to maintain a 1:1 source map.
- a_wild_dandan 2y ago> They’re saying that V8 is a very capable optimizer (which it is), so why can’t it optimize the things React Compiler optimizes? Because capable != exhaustive? All compiled languages can benefit from further optimizations. I genuinely don't understand the issue here. Help!
- andybak 2y agoI think OP is questioning whether these are optimizations or whether they are just redundant. I don't know the answer - I don't use React personally.
- jampekka 2y agoI guess it's continuing the trend of patching over hacks with more hacks to try to work around fundamental design errors. useMemo has the problem of having to specify dependencies manually and making fine grained updates difficult. Letting go of the unworkable pretension of effect-free components would solve these self-inflicted wounds, like is done in e.g. SolidJS.
- solatic 2y ago> a whole paragraph on the cognitive load of an extra compilation step... IMO you don't even come CLOSE to explaining why this trade off is worth it You're missing the whole context about how React is a library with a huge enterprise sponsor (Meta) who uses it to build some of the biggest web frontends in the world (Facebook etc.) where most of their engineering talent, like most enterprises, will trend to be juniors in order to save money. Juniors will not naively get the dependency array for useMemo correct, period. With enough juniors banging away on enough PRs, especially if PRs are not reviewed by the most senior talent to save time, this becomes a problem at scale. The need to introduce extra compilation steps, especially when a codebase the size of Facebook already has (I'm sure) distributed build caching, is more or less immaterial compared to the savings of getting more PRs to be correct when first raised for review.
- jampekka 2y agoIt's rather amazing and telling of our economic system that over a trillion dollar company can't make their main product work properly.
- sabbaticaldev 2y agoAnd that people tell mom-and-pop shops to use too, because Facebook uses it
- jampekka 2y agoPeople probably tell the shops to use it because they don't know anything else and lack fundamental understanding of programming which makes switching frameworks quite hard. I.e. job security for "React programmers".
- throwAGIway 2y agoShow me a better one... And please don't say Vue or svelte because these are just the same thing a little differently.
- Tarean 2y agoThe big problem is that - memoization sometimes crucial for performance. - passing objects and functions around is common. - you cannot compare objects and functions for semantic equality If you wrote larger react apps you almost certainly had to useCallback at some point so that memoization worked, the compiler fixes that. Whenever you construct an object or function the react compiler memoizes on their free variables so pointer equality is sufficient. Though I do think the compiler caches too aggressively, even if there are no free variables and hoisting is sufficient or escape analysis shows it is unnecessary for semantics.
- svieira 2y ago> de-inlining (or whatever the proper word is) The phrase you are looking for is "loop-invariant code motion". https://en.wikipedia.org/wiki/Loop-invariant_code_motion https://en.wikipedia.org/wiki/Loop-invariant_code_motion