Reza Safari Blog
Published on

The Hot Topic of Excessive Rerenders in Digikala and a Small Solution ProductCard Rerenders

The Hot Topic of Excessive Rerenders in Digikala and a Small Solution: ProductCard Rerenders

Recently, there's been a heated discussion about the issue of frequent rerenders on Digikala, which you've probably heard about. My personal take on this is that it might be premature to form strong opinions at this stage. Surely, the team working on this project is well aware of all these concerns, and they are likely addressing these issues gradually.

However, let's delve into a very tiny aspect within this context and talk about it – the unnecessary rerenders of product cards.

Imagine you have a page displaying 100 product cards, each equipped with a "Add To Wishlist" button.

Keep in mind that the initial data comes from the server, and we store it in Redux (or any state manager). For this discussion, let's consider Redux.

Naturally, what anyone might do is retrieve the data from Redux and display it:

const wishlistData = useSelector((store) => store.wishlist.data)

const isInWishlist = wishlistData.findIndex((p) => p.id === product.id) > -1

With this approach, we determine whether a product is in the wishlist or not.

However, there's a significant issue. If the button responsible for adding or removing a product from the wishlist triggers a rerender, all 100 cards will also rerender!

Could this be resolved with memo? To some extent, yes. But not entirely.

Since, in any case, the wishlistData is receiving new data and compelling the component to rerender. And because our store changes, all components dependent on it will also rerender.

The comprehensive solution involves memoizing the useSelector in a way that it only retrieves new data when the data relevant to that specific card changes, disregarding the data for other cards.

But how?

The Solution:

I can confidently assert that in all projects of medium to large size, you should employ reselect. The reasons why reselect is essential might be a bit extensive, but the most significant one is controlling rerenders for Redux. As we've learned from the discussion above, we need to limit the usage of useSelector and prevent unnecessary access to extra data.

As depicted, we've ingeniously created a new selector using reselect. We only selected the data relevant to our needs and then used it in useSelector. This straightforward method prevents an additional 100 rerenders. This technique can be applied to most components connected to Redux, significantly boosting performance.

Open Source Book Shop