Skip to content

useMemo detected as cheap - but subjectively still more expensive than dependency comparison #127

@ackvf

Description

@ackvf

I would like to better understand how the metric works and what is the threshold for it to consider it okay or unnecessary as only one of the two was deemed worthy. One is O(2n), the other is O(n), and both are O(2) after memoization.

Rule: react-doctor/no-usememo-simple-expression
Severity: warning
Category: Performance
Count: 1

useMemo wrapping a trivially cheap expression — memo overhead exceeds the computation

Suggestion: Remove useMemo — property access, math, and ternaries are already cheap without memoization

Files:
  src/components/users/index.tsx: 60

the code:

25: const currentUserId: number = // stable number, never changes
31: const users = // memoized data fetch result
51: const [isSelected, setIsSelected] = useState([])
// ...
55:  const selectableUserIds = React.useMemo( // never changes after initial fetch
56:    () =>
57:      users.filter((user) => user.id !== currentUserId).map((user) => user.id),
58:    [users, currentUserId],
59:  )
60:  const selectedDeletableCount = React.useMemo(
61:    () => selectableUserIds.filter((id) => isSelected.has(id)).length,
62:    [isSelected, selectableUserIds],
63:  )
  1. We filter users to remove the current user. The result is "selectable table rows" - user can't select themselves.
  2. This is the array that holds ids of users that have been selected. There is hundreds of users in the table, could be thousands.

My understanding is that whenever the component re-renders, it will call these two filters. To shave a bit off this not-so-expensive operation (but could be if the number of users grew a lot), it is memoized and the cost now is only in comparing the two dependencies isSelected and selectableUserIds. Even though it is Linear Growth O(n), which is considered efficient by many, it -in my opinion- still offers a significant reduction from O(n) to O(1).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions