Skip to content

Commit

Permalink
[lib] Drill allAtOnce from useChatMentionCandidatesObjAndUtils to use…
Browse files Browse the repository at this point in the history
…ENSNames

Summary:
This solves [ENG-5274](https://linear.app/comm/issue/ENG-5274/ens-resolution-for-chat-mentioning-causes-too-many-react-rerenders). Additional context about `allAtOnce` in D9515.

Depends on D9466

Test Plan:
I compared performance of the following two scenarios:

1. `master` + revert of D9465 + D9466
2. `master` + revert of D9465 + D9466 + this diff

While I did perceive a slight regression in TTI on the inbox by about a second, I think it's okay to land this stack (including @tomek's work) after this diff is accepted.

More details on next steps [here](https://linear.app/comm/issue/ENG-5274/ens-resolution-for-chat-mentioning-causes-too-many-react-rerenders#comment-a7405e2f).

Reviewers: tomek, atul

Reviewed By: atul

Subscribers: wyilio, tomek

Differential Revision: https://phab.comm.dev/D9523
  • Loading branch information
Ashoat committed Oct 19, 2023
1 parent 5011d6a commit d6e7e66
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 9 deletions.
11 changes: 10 additions & 1 deletion lib/components/chat-mention-provider.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,22 @@ function getChatMentionCandidates(threadInfos: {
};
}

// Without allAtOnce, useChatMentionCandidatesObjAndUtils is very expensive.
// useResolvedThreadInfosObj would trigger its recalculation for each ENS name
// as it streams in, but we would prefer to trigger its recaculation just once
// for every update of the underlying Redux data.
const useResolvedThreadInfosObjOptions = { allAtOnce: true };

function useChatMentionCandidatesObjAndUtils(): {
chatMentionCandidatesObj: ChatMentionCandidatesObj,
resolvedThreadInfos: ChatMentionCandidates,
communityThreadIDForGenesisThreads: { +[id: string]: string },
} {
const threadInfos = useSelector(threadInfoSelector);
const resolvedThreadInfos = useResolvedThreadInfosObj(threadInfos);
const resolvedThreadInfos = useResolvedThreadInfosObj(
threadInfos,
useResolvedThreadInfosObjOptions,
);
const { chatMentionCandidatesObj, communityThreadIDForGenesisThreads } =
React.useMemo(
() => getChatMentionCandidates(resolvedThreadInfos),
Expand Down
16 changes: 11 additions & 5 deletions lib/utils/entity-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,19 @@ import {
useENSNamesForEntityText,
entityTextToRawString,
} from './entity-text.js';
import type { UseENSNamesOptions } from '../hooks/ens-cache.js';
import type { ThreadInfo, ResolvedThreadInfo } from '../types/thread-types.js';
import { values } from '../utils/objects.js';

function useResolvedThreadInfos(
threadInfos: $ReadOnlyArray<ThreadInfo>,
options?: ?UseENSNamesOptions,
): $ReadOnlyArray<ResolvedThreadInfo> {
const entityText = React.useMemo(
() => threadInfos.map(threadInfo => threadInfo.uiName),
[threadInfos],
);
const withENSNames = useENSNamesForEntityText(entityText);
const withENSNames = useENSNamesForEntityText(entityText, options);
invariant(
withENSNames,
'useENSNamesForEntityText only returns falsey when passed falsey',
Expand Down Expand Up @@ -76,14 +78,18 @@ function useResolvedOptionalThreadInfos(
}, [threadInfos, withENSNames]);
}

function useResolvedThreadInfosObj(threadInfosObj: {
+[id: string]: ThreadInfo,
}): { +[id: string]: ResolvedThreadInfo } {
function useResolvedThreadInfosObj(
threadInfosObj: { +[id: string]: ThreadInfo },
options?: ?UseENSNamesOptions,
): { +[id: string]: ResolvedThreadInfo } {
const threadInfosArray = React.useMemo(
() => values(threadInfosObj),
[threadInfosObj],
);
const resolvedThreadInfosArray = useResolvedThreadInfos(threadInfosArray);
const resolvedThreadInfosArray = useResolvedThreadInfos(
threadInfosArray,
options,
);
return React.useMemo(() => {
const obj = {};
for (const resolvedThreadInfo of resolvedThreadInfosArray) {
Expand Down
9 changes: 6 additions & 3 deletions lib/utils/entity-text.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import t, { type TInterface, type TUnion } from 'tcomb';

import type { GetENSNames } from './ens-helpers.js';
import { tID, tShape, tString } from './validation-utils.js';
import { useENSNames } from '../hooks/ens-cache.js';
import { useENSNames, type UseENSNamesOptions } from '../hooks/ens-cache.js';
import { threadNoun } from '../shared/thread-utils.js';
import { stringForUser } from '../shared/user-utils.js';
import {
Expand Down Expand Up @@ -533,12 +533,15 @@ function entityTextFromObjects(
.filter(Boolean);
}

function useENSNamesForEntityText(entityText: ?EntityText): ?EntityText {
function useENSNamesForEntityText(
entityText: ?EntityText,
options?: ?UseENSNamesOptions,
): ?EntityText {
const allObjects = React.useMemo(
() => (entityText ? entityTextToObjects(entityText) : []),
[entityText],
);
const objectsWithENSNames = useENSNames(allObjects);
const objectsWithENSNames = useENSNames(allObjects, options);
return React.useMemo(
() =>
entityText ? entityTextFromObjects(objectsWithENSNames) : entityText,
Expand Down

0 comments on commit d6e7e66

Please sign in to comment.