Skip to content

Commit

Permalink
fix: get rid of performance issues when rendering loooong markdown me…
Browse files Browse the repository at this point in the history
…ssages
  • Loading branch information
breeg554 committed Oct 18, 2024
1 parent 70592ef commit bdc3624
Show file tree
Hide file tree
Showing 4 changed files with 651 additions and 90 deletions.
104 changes: 38 additions & 66 deletions apps/web-remix/app/components/chat/ChatMarkdown.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import type { AnchorHTMLAttributes } from 'react';
import React, { useEffect, useMemo, useRef } from 'react';
import type { Options } from 'react-markdown';
import Markdown from 'react-markdown';
import { Check, Copy } from 'lucide-react';
import Markdown from 'markdown-to-jsx';
import type { MarkdownToJSX } from 'markdown-to-jsx';
import mermaid from 'mermaid';
import rehypeRaw from 'rehype-raw';
import { z } from 'zod';

import { useCopyToClipboard } from '~/hooks/useCopyToClipboard';
Expand All @@ -12,7 +13,7 @@ import { cn } from '~/utils/cn';
interface ChatMarkdownProps {
[key: string]: any;
children: string;
options?: MarkdownToJSX.Options;
options?: Options;
}

export const ChatMarkdown: React.FC<ChatMarkdownProps> = ({
Expand All @@ -22,62 +23,27 @@ export const ChatMarkdown: React.FC<ChatMarkdownProps> = ({
}) => {
return (
<Markdown
options={{
overrides: {
style: {
component: Span,
},
script: {
component: Span,
},
p: {
component: Paragraph,
},
span: {
component: Span,
},
pre: {
component: Pre,
},
code: {
component: Code,
},
div: {
component: Div,
},
h6: {
component: H6,
},
h5: {
component: H5,
},
h4: {
component: H4,
},
h3: {
component: H3,
},
h2: {
component: H2,
},
h1: {
component: H1,
},

li: {
component: Li,
},
a: {
component: Link,
},
img: {
component: Image,
},
strong: {
component: Strong,
},
},
...options,
rehypePlugins={[rehypeRaw]}
{...options}
components={{
style: Span,
script: Span,
p: Paragraph,
span: Span,
pre: Pre,
code: Code,
div: Div,
h6: H6,
h5: H5,
h4: H4,
h3: H3,
h2: H2,
h1: H1,
li: Li,
a: Link,
img: Image,
strong: Strong,
...options?.components,
}}
{...rest}
>
Expand Down Expand Up @@ -345,9 +311,10 @@ function Code({
children,
className,
...rest
}: React.ParamHTMLAttributes<HTMLPreElement>) {
}: React.ParamHTMLAttributes<HTMLElement>) {
const codeRef = useRef<HTMLElement>(null);
const isMermaidCode = className?.includes('lang-mermaid');
const isMermaidCode = className?.includes('language-mermaid');

if (isMermaidCode) {
mermaid.initialize({
theme: 'default',
Expand All @@ -356,18 +323,23 @@ function Code({
nodes: [codeRef.current!],
});
}

if (className?.includes('lang-buildel_message_attachments')) {
try {
const attachments = MessageAttachments.parse(
JSON.parse((children || '').toString()),
);
return attachments.map((attachment) => {
return <div key={attachment.id}>{attachment.file_name}</div>;
});
return (
<>
{attachments.map((attachment) => {
return <div key={attachment.id}>{attachment.file_name}</div>;
})}
</>
);
} catch (e) {
console.error(e);
}
return 'Uploaded files';
return <>Uploaded files</>;
}

return (
Expand Down Expand Up @@ -462,7 +434,7 @@ function shouldBeTruncated(child: { props: Record<string, unknown> }) {
}

function getLanguage(className?: string) {
return className?.match(/lang-(\w+)/)?.[1];
return className?.match(/language-(\w+)/)?.[1];
}

function truncateString(str: string, maxLength: number) {
Expand Down
25 changes: 15 additions & 10 deletions apps/web-remix/app/components/chat/ChatMessages.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,20 @@ export function ChatMessages({
}
}, [messages, inView]);

const renderItem = useCallback(
(msg: IMessage) => {
const { message, links } = addReferenceToLinks(msg.message);
return (
<ChatMessage message={msg} size={size}>
<ChatMarkdown>{message}</ChatMarkdown>

<EmbedLinksList links={links} />
</ChatMessage>
);
},
[size],
);

return (
<ItemList
ref={listRef}
Expand All @@ -58,16 +72,7 @@ export function ChatMessages({
)}
itemClassName="w-full pl-3 pr-1"
items={reversed}
renderItem={(msg) => {
const { message, links } = addReferenceToLinks(msg.message);
return (
<ChatMessage message={msg} size={size}>
<ChatMarkdown>{message}</ChatMarkdown>

<EmbedLinksList links={links} />
</ChatMessage>
);
}}
renderItem={renderItem}
>
{children}

Expand Down
3 changes: 2 additions & 1 deletion apps/web-remix/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@
"lodash.throttle": "^4.1.1",
"lru-cache": "^10.2.0",
"lucide-react": "^0.408.0",
"markdown-to-jsx": "^7.4.1",
"mermaid": "^10.9.1",
"morgan": "^1.10.0",
"next-themes": "^0.3.0",
Expand All @@ -98,8 +97,10 @@
"react-datepicker": "^6.6.0",
"react-dom": "19.0.0-rc-eb3ad065-20240822",
"react-intersection-observer": "^9.5.3",
"react-markdown": "^9.0.1",
"react-tooltip": "^5.21.5",
"recharts": "2.13.0-alpha.4",
"rehype-raw": "^7.0.0",
"remix-utils": "^7.5.0",
"remix-validated-form": "^5.1.5",
"sonner": "^1.5.0",
Expand Down
Loading

0 comments on commit bdc3624

Please sign in to comment.