Live data from Hacker News

We memo all the things (2020)

attardi.org

51–60 of 84 posts

Re: We memo all the things (2020)

#51

Earlier quoted context omitted.

What? Redux doesn't do any performance optimizations.

Not by itself, but most people who use React + Redux use the (unsurprisingly named) react-redux glue library, too. That does a lot of the "should component update" calculations for you as a function of the computed `map[State/Dispatch]ToProps` result. (There are still some gotchas with caching selectors and so on, but I personally find those a lot easier to implement post-fact than memoizing hook soup codebases once…

Oh, I never knew that. TIL

Re: We memo all the things (2020)

#52

Earlier quoted context omitted.

Have you ever dug through a complex heavily nested application trying to debug a performance issue, only to find a custom shouldComponentUpdate method within every individual component? It makes debugging an absolute nightmare.

I'm not sure why it would. The profiler will tell you exactly which component is the bottleneck, and you could then go inspect that one for the cause.

>The profiler will tell you exactly which component is the bottleneck, and you could then go inspect that one for the cause.

And then you have to understand the entire thought process and business logic that led to how the shouldComponentUpdate method for that class is implemented for every bottleneck, where one mistake or oversight can lead to an infinite re-render loop. This is the kind of stuff that should be handled at the framework level or with your state management library, not individual components.

Re: We memo all the things (2020)

#53
post #35

This is a great article and I agree with it fully. The argument that a lot of popular React voices have made, "React is fast and it's prematurely optimizing to worry about memoizing things until a profile shows you need it", has never rung true with me. First and foremost, there's a huge time cost to figuring out what those exact spots that need optimization are, and there's also an educational cost with teaching les…

It seems to me you're being pretty breezy about readability. At most places, developer time is by far the most expensive commodity, and the limiting factor in creating more user value. In particular, bad readability is one of the sources of a vicious circle where normalization of deviance [1] leads to a gradual worsening of the code and a gradual increase in developer willingness to write around problems rather than…

I don't disagree with you on readability being important or on the value of developer time. It's just that the marginal costs of `memo`, `useMemo`, and `useCallback` are quite low. They don't add cyclomatic complexity, they don't increase coupling, they can be added to code essentially mechanically and don't carry a large cognitive overhead to figure out how to use, etc.

The main downsides are that they take slightly longer to type and slightly decrease the succinctness of the code. And then there are a few React-specific complexities they add (maintaining the deps arrays and being sure not to use them conditionally) but these should be checked by lint rules to relieve developer cognitive load.

Of course I'd rather not have these downsides, but in the end, it's still much less developer overhead than having to constantly profile a large application to try and figure out the trouble spots and correctly test and fix them post-hoc. And it means users are much more likely to get an application that feels snappier, doesn't drain as much battery, and just provides a more pleasant experience overall, which is worth it imo.

Re: We memo all the things (2020)

#54

Earlier quoted context omitted.

I think it would be easy to create a rule to see if the default export is wrapped in memo, but you could also just have it as a coding standard

I wonder if this is the plugin they are using: https://github.com/steadicat/eslint-plugin-react-memo Does anyone know of any other eslint plugins that help enforce this?

The author of the article wrote the ESLint plugin: https://github.com/steadicat So they probably use(d) it.

Re: We memo all the things (2020)

#55
post #38

Earlier quoted context omitted.

the only time I find it to be required is when passing in callbacks to custom hooks with props that may change and you'll notice immediately because the callback will continuously run

If you're using React.useCallback to avoid triggering further hooks down the line, then you're using it wrong. Since React.useCallback is ostensibly just React.useMemo wrapped around a function, this note in the documentation is just as applicable: You may rely on useMemo as a performance optimization, not as a semantic guarantee. In the future, React may choose to “forget” some previously memoized values and recalcu…

If we have a component and inside profile page we use an effect to load from id and call handleOnLoad with the loaded profile data, then we need to put handleOnLoad in the useEffect dependencies. So we have to pass a callback wrapped in useCallback else the effect would fire every time ProfilePage rerenders.

Re: We memo all the things (2020)

#56
post #36

This was in 2020. I assume the team got made redundant in the last year or something. Coinbase has genuinely been the slowest performing website I've used in the past couple of years.

I asked the author on Twitter if this approach was still in place, but didn't get a reply :/

Re: We memo all the things (2020)

#57

Interesting, I mostly followed this approach which is to basically never use those constructs unless you are 100% certain you know what will happen. https://kentcdodds.com/blog/usememo-and-usecallback TLDR; > Specifically the cost for useCallback and useMemo are that you make the code more complex for your co-workers, you could make a mistake in the dependencies array, and you're potentially making performance worse…

The problem with avoiding useCallback is that another hook will bite you: useEffect. If you need to define functions that interact with your component's state, you have to memoize them with useCallback (or useRef) to avoid a useEffect infinite loop. What's even worse is that if functions passed as props are unstable, your useEffect will run every time the parent component renders — meaning that a component can't trus…

I wouldn't say useEffect is a footgun, it just requires realising that React is doing shallow comparisons.

Re: We memo all the things (2020)

#58
post #36

This was in 2020. I assume the team got made redundant in the last year or something. Coinbase has genuinely been the slowest performing website I've used in the past couple of years.

The team actually became part of a company-wide effort called Client Foundations! And no, we haven't changed our mind on this. (BTW we're hiring. :))

Re: We memo all the things (2020)

#59

Earlier quoted context omitted.

I wonder if this is the plugin they are using: https://github.com/steadicat/eslint-plugin-react-memo Does anyone know of any other eslint plugins that help enforce this?

The author of the article wrote the ESLint plugin: https://github.com/steadicat So they probably use(d) it.

That's great!

Re: We memo all the things (2020)

#60
post #15

This is a great article and I agree with it fully. The argument that a lot of popular React voices have made, "React is fast and it's prematurely optimizing to worry about memoizing things until a profile shows you need it", has never rung true with me. First and foremost, there's a huge time cost to figuring out what those exact spots that need optimization are, and there's also an educational cost with teaching les…

I've always thought of "premature optimisation" as optimising something that's not your "hot path". If there's no clear hot path, everything is the hot path, and small optimisation gains everywhere are the only thing you're going to get. So at this point, it's not premature. You could also rewrite your code so that there is a clear hot path, but in that case it seems to be React rendering, that's optimised by using m…

The death from a thousand papercuts.

I'm not terribly convinced with memoization though. You're using extra memory, so it's not free optimization. We have Redux memoized selectors everywhere. I can't help but wonder how much of that is actually a memory leak (i.e. it's never used more than once). Granted, components are a bit different.

I always do cringe when I see a lint rule forcing you to use a spread operator in an array reduce(). It's such a stupid self-inflicted way to turn an O(N) into an O(N^2) while adding GC memory pressure. All to serve some misguided dogma of immutability. I feel there is a need for a corollary to the "premature optimization is the root of all evil" rule.

Post reply on HN