diff --git a/lib/shared/markdown.js b/lib/shared/markdown.js
--- a/lib/shared/markdown.js
+++ b/lib/shared/markdown.js
@@ -197,15 +197,22 @@
   };
 }
 
-function matchUserMentions(
+function createMemberMapForUserMentions(
   members: $ReadOnlyArray<RelativeMemberInfo>,
+): $ReadOnlyMap<string, string> {
+  const membersMap = new Map<string, string>();
+  members.forEach(member => {
+    if (member.role && member.username) {
+      membersMap.set(member.username.toLowerCase(), member.id);
+    }
+  });
+
+  return membersMap;
+}
+
+function matchUserMentions(
+  membersMap: $ReadOnlyMap<string, string>,
 ): MatchFunction {
-  const memberSet = new Set(
-    members
-      .filter(({ role }) => role)
-      .map(({ username }) => username?.toLowerCase())
-      .filter(Boolean),
-  );
   const match = (source: string, state: State) => {
     if (!state.inline) {
       return null;
@@ -216,7 +223,7 @@
     }
     const username = result[2];
     invariant(username, 'markdownMentionRegex should match two capture groups');
-    if (!memberSet.has(username.toLowerCase())) {
+    if (!membersMap.has(username.toLowerCase())) {
       return null;
     }
     return result;
@@ -339,6 +346,7 @@
   jsonPrint,
   matchList,
   parseList,
+  createMemberMapForUserMentions,
   matchUserMentions,
   stripSpoilersFromNotifications,
   stripSpoilersFromMarkdownAST,
diff --git a/native/markdown/rules.react.js b/native/markdown/rules.react.js
--- a/native/markdown/rules.react.js
+++ b/native/markdown/rules.react.js
@@ -378,13 +378,15 @@
 ): MarkdownRules {
   const styles = getMarkdownStyles(useDarkStyle ? 'dark' : 'light');
   const baseRules = fullMarkdownRules(useDarkStyle);
+  const membersMap = SharedMarkdown.createMemberMapForUserMentions(members);
+
   return {
     ...baseRules,
     simpleMarkdownRules: {
       ...baseRules.simpleMarkdownRules,
       userMention: {
         ...SimpleMarkdown.defaultRules.strong,
-        match: SharedMarkdown.matchUserMentions(members),
+        match: SharedMarkdown.matchUserMentions(membersMap),
         parse: (capture: SharedMarkdown.Capture) => ({
           content: capture[0],
         }),
diff --git a/web/markdown/rules.react.js b/web/markdown/rules.react.js
--- a/web/markdown/rules.react.js
+++ b/web/markdown/rules.react.js
@@ -183,13 +183,15 @@
   useDarkStyle: boolean,
 ): MarkdownRules {
   const baseRules = markdownRules(useDarkStyle);
+  const membersMap = SharedMarkdown.createMemberMapForUserMentions(members);
+
   return {
     ...baseRules,
     simpleMarkdownRules: {
       ...baseRules.simpleMarkdownRules,
       userMention: {
         ...SimpleMarkdown.defaultRules.strong,
-        match: SharedMarkdown.matchUserMentions(members),
+        match: SharedMarkdown.matchUserMentions(membersMap),
         parse: (capture: SharedMarkdown.Capture) => ({
           content: capture[0],
         }),