Skip to content

Commit 8c80cc0

Browse files
fix: enhance performance for codeblock (#347)
--------- Co-authored-by: Marcus Schiesser <[email protected]>
1 parent dfd4fd5 commit 8c80cc0

File tree

4 files changed

+25
-38
lines changed

4 files changed

+25
-38
lines changed

helpers/typescript.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -279,12 +279,7 @@ async function updatePackageJson({
279279
"remark-gfm": undefined,
280280
"remark-math": undefined,
281281
"react-markdown": undefined,
282-
"react-syntax-highlighter": undefined,
283-
};
284-
285-
packageJson.devDependencies = {
286-
...packageJson.devDependencies,
287-
"@types/react-syntax-highlighter": undefined,
282+
"highlight.js": undefined,
288283
};
289284
}
290285

templates/types/streaming/nextjs/app/components/ui/chat/chat-message/codeblock.tsx

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
11
"use client";
22

3+
import hljs from "highlight.js";
4+
// instead of atom-one-dark theme, there are a lot of others: https://highlightjs.org/demo
5+
import "highlight.js/styles/atom-one-dark-reasonable.css";
36
import { Check, Copy, Download } from "lucide-react";
4-
import { FC, memo } from "react";
5-
import { Prism, SyntaxHighlighterProps } from "react-syntax-highlighter";
6-
import { coldarkDark } from "react-syntax-highlighter/dist/cjs/styles/prism";
7-
7+
import { FC, memo, useEffect, useRef } from "react";
88
import { Button } from "../../button";
99
import { useCopyToClipboard } from "../hooks/use-copy-to-clipboard";
1010

11-
// TODO: Remove this when @type/react-syntax-highlighter is updated
12-
const SyntaxHighlighter = Prism as unknown as FC<SyntaxHighlighterProps>;
13-
1411
interface Props {
1512
language: string;
1613
value: string;
14+
className?: string;
1715
}
1816

1917
interface languageMap {
@@ -56,8 +54,15 @@ export const generateRandomString = (length: number, lowercase = false) => {
5654
return lowercase ? result.toLowerCase() : result;
5755
};
5856

59-
const CodeBlock: FC<Props> = memo(({ language, value }) => {
57+
const CodeBlock: FC<Props> = memo(({ language, value, className }) => {
6058
const { isCopied, copyToClipboard } = useCopyToClipboard({ timeout: 2000 });
59+
const codeRef = useRef<HTMLElement>(null);
60+
61+
useEffect(() => {
62+
if (codeRef.current && codeRef.current.dataset.highlighted !== "yes") {
63+
hljs.highlightElement(codeRef.current);
64+
}
65+
}, [language, value]);
6166

6267
const downloadAsFile = () => {
6368
if (typeof window === "undefined") {
@@ -93,7 +98,9 @@ const CodeBlock: FC<Props> = memo(({ language, value }) => {
9398
};
9499

95100
return (
96-
<div className="codeblock relative w-full bg-zinc-950 font-sans">
101+
<div
102+
className={`codeblock relative w-full bg-zinc-950 font-sans ${className}`}
103+
>
97104
<div className="flex w-full items-center justify-between bg-zinc-800 px-6 py-2 pr-4 text-zinc-100">
98105
<span className="text-xs lowercase">{language}</span>
99106
<div className="flex items-center space-x-1">
@@ -111,26 +118,11 @@ const CodeBlock: FC<Props> = memo(({ language, value }) => {
111118
</Button>
112119
</div>
113120
</div>
114-
<SyntaxHighlighter
115-
language={language}
116-
style={coldarkDark}
117-
PreTag="div"
118-
showLineNumbers
119-
customStyle={{
120-
width: "100%",
121-
background: "transparent",
122-
padding: "1.5rem 1rem",
123-
borderRadius: "0.5rem",
124-
}}
125-
codeTagProps={{
126-
style: {
127-
fontSize: "0.9rem",
128-
fontFamily: "var(--font-mono)",
129-
},
130-
}}
131-
>
132-
{value}
133-
</SyntaxHighlighter>
121+
<pre className="border border-zinc-700">
122+
<code ref={codeRef} className={`language-${language} font-mono`}>
123+
{value}
124+
</code>
125+
</pre>
134126
</div>
135127
);
136128
});

templates/types/streaming/nextjs/app/components/ui/chat/chat-message/markdown.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ export default function Markdown({
114114
key={Math.random()}
115115
language={(match && match[1]) || ""}
116116
value={String(children).replace(/\n$/, "")}
117+
className="mb-2"
117118
{...props}
118119
/>
119120
);

templates/types/streaming/nextjs/package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
"react": "^18.2.0",
3434
"react-dom": "^18.2.0",
3535
"react-markdown": "^8.0.7",
36-
"react-syntax-highlighter": "^15.5.0",
3736
"rehype-katex": "^7.0.0",
3837
"remark": "^14.0.3",
3938
"remark-code-import": "^1.2.0",
@@ -44,13 +43,13 @@
4443
"tiktoken": "^1.0.15",
4544
"uuid": "^9.0.1",
4645
"vaul": "^0.9.1",
47-
"marked": "^14.1.2"
46+
"marked": "^14.1.2",
47+
"highlight.js": "^11.10.0"
4848
},
4949
"devDependencies": {
5050
"@types/node": "^20.10.3",
5151
"@types/react": "^18.2.42",
5252
"@types/react-dom": "^18.2.17",
53-
"@types/react-syntax-highlighter": "^15.5.11",
5453
"@types/uuid": "^9.0.8",
5554
"autoprefixer": "^10.4.16",
5655
"cross-env": "^7.0.3",

0 commit comments

Comments
 (0)