perf(web): improve app workflow build performance. (#26310)

This commit is contained in:
Yadong (Adam) Zhang
2025-10-07 14:21:08 +08:00
committed by GitHub
parent 31e6ef77a6
commit 654d522b31
7 changed files with 120 additions and 94 deletions

View File

@@ -8,12 +8,14 @@ import {
import ActionButton from '@/app/components/base/action-button'
import CopyIcon from '@/app/components/base/copy-icon'
import SVGBtn from '@/app/components/base/svg'
import Flowchart from '@/app/components/base/mermaid'
import { Theme } from '@/types/app'
import useTheme from '@/hooks/use-theme'
import SVGRenderer from '../svg-gallery' // Assumes svg-gallery.tsx is in /base directory
import MarkdownMusic from '@/app/components/base/markdown-blocks/music'
import ErrorBoundary from '@/app/components/base/markdown/error-boundary'
import dynamic from 'next/dynamic'
const Flowchart = dynamic(() => import('@/app/components/base/mermaid'), { ssr: false })
// Available language https://github.com/react-syntax-highlighter/react-syntax-highlighter/blob/master/AVAILABLE_LANGUAGES_HLJS.MD
const capitalizationLanguageNameMap: Record<string, string> = {

View File

@@ -1,25 +1,11 @@
import ReactMarkdown from 'react-markdown'
import dynamic from 'next/dynamic'
import 'katex/dist/katex.min.css'
import RemarkMath from 'remark-math'
import RemarkBreaks from 'remark-breaks'
import RehypeKatex from 'rehype-katex'
import RemarkGfm from 'remark-gfm'
import RehypeRaw from 'rehype-raw'
import { flow } from 'lodash-es'
import cn from '@/utils/classnames'
import { customUrlTransform, preprocessLaTeX, preprocessThinkTag } from './markdown-utils'
import {
AudioBlock,
CodeBlock,
Img,
Link,
MarkdownButton,
MarkdownForm,
Paragraph,
ScriptBlock,
ThinkBlock,
VideoBlock,
} from '@/app/components/base/markdown-blocks'
import { preprocessLaTeX, preprocessThinkTag } from './markdown-utils'
import type { ReactMarkdownWrapperProps } from './react-markdown-wrapper'
const ReactMarkdown = dynamic(() => import('./react-markdown-wrapper').then(mod => mod.ReactMarkdownWrapper), { ssr: false })
/**
* @fileoverview Main Markdown rendering component.
@@ -31,9 +17,7 @@ import {
export type MarkdownProps = {
content: string
className?: string
customDisallowedElements?: string[]
customComponents?: Record<string, React.ComponentType<any>>
}
} & Pick<ReactMarkdownWrapperProps, 'customComponents' | 'customDisallowedElements'>
export const Markdown = (props: MarkdownProps) => {
const { customComponents = {} } = props
@@ -44,53 +28,7 @@ export const Markdown = (props: MarkdownProps) => {
return (
<div className={cn('markdown-body', '!text-text-primary', props.className)}>
<ReactMarkdown
remarkPlugins={[
RemarkGfm,
[RemarkMath, { singleDollarTextMath: false }],
RemarkBreaks,
]}
rehypePlugins={[
RehypeKatex,
RehypeRaw as any,
// The Rehype plug-in is used to remove the ref attribute of an element
() => {
return (tree: any) => {
const iterate = (node: any) => {
if (node.type === 'element' && node.properties?.ref)
delete node.properties.ref
if (node.type === 'element' && !/^[a-z][a-z0-9]*$/i.test(node.tagName)) {
node.type = 'text'
node.value = `<${node.tagName}`
}
if (node.children)
node.children.forEach(iterate)
}
tree.children.forEach(iterate)
}
},
]}
urlTransform={customUrlTransform}
disallowedElements={['iframe', 'head', 'html', 'meta', 'link', 'style', 'body', ...(props.customDisallowedElements || [])]}
components={{
code: CodeBlock,
img: Img,
video: VideoBlock,
audio: AudioBlock,
a: Link,
p: Paragraph,
button: MarkdownButton,
form: MarkdownForm,
script: ScriptBlock as any,
details: ThinkBlock,
...customComponents,
}}
>
{/* Markdown detect has problem. */}
{latexContent}
</ReactMarkdown>
<ReactMarkdown latexContent={latexContent} customComponents={customComponents} customDisallowedElements={props.customDisallowedElements} />
</div>
)
}

View File

@@ -0,0 +1,82 @@
import ReactMarkdown from 'react-markdown'
import RemarkMath from 'remark-math'
import RemarkBreaks from 'remark-breaks'
import RehypeKatex from 'rehype-katex'
import RemarkGfm from 'remark-gfm'
import RehypeRaw from 'rehype-raw'
import AudioBlock from '@/app/components/base/markdown-blocks/audio-block'
import Img from '@/app/components/base/markdown-blocks/img'
import Link from '@/app/components/base/markdown-blocks/link'
import MarkdownButton from '@/app/components/base/markdown-blocks/button'
import MarkdownForm from '@/app/components/base/markdown-blocks/form'
import Paragraph from '@/app/components/base/markdown-blocks/paragraph'
import ScriptBlock from '@/app/components/base/markdown-blocks/script-block'
import ThinkBlock from '@/app/components/base/markdown-blocks/think-block'
import VideoBlock from '@/app/components/base/markdown-blocks/video-block'
import { customUrlTransform } from './markdown-utils'
import type { FC } from 'react'
import dynamic from 'next/dynamic'
const CodeBlock = dynamic(() => import('@/app/components/base/markdown-blocks/code-block'), { ssr: false })
export type ReactMarkdownWrapperProps = {
latexContent: any
customDisallowedElements?: string[]
customComponents?: Record<string, React.ComponentType<any>>
}
export const ReactMarkdownWrapper: FC<ReactMarkdownWrapperProps> = (props) => {
const { customComponents, latexContent } = props
return (
<ReactMarkdown
remarkPlugins={[
RemarkGfm,
[RemarkMath, { singleDollarTextMath: false }],
RemarkBreaks,
]}
rehypePlugins={[
RehypeKatex,
RehypeRaw as any,
// The Rehype plug-in is used to remove the ref attribute of an element
() => {
return (tree: any) => {
const iterate = (node: any) => {
if (node.type === 'element' && node.properties?.ref)
delete node.properties.ref
if (node.type === 'element' && !/^[a-z][a-z0-9]*$/i.test(node.tagName)) {
node.type = 'text'
node.value = `<${node.tagName}`
}
if (node.children)
node.children.forEach(iterate)
}
tree.children.forEach(iterate)
}
},
]}
urlTransform={customUrlTransform}
disallowedElements={['iframe', 'head', 'html', 'meta', 'link', 'style', 'body', ...(props.customDisallowedElements || [])]}
components={{
code: CodeBlock,
img: Img,
video: VideoBlock,
audio: AudioBlock,
a: Link,
p: Paragraph,
button: MarkdownButton,
form: MarkdownForm,
script: ScriptBlock as any,
details: ThinkBlock,
...customComponents,
}}
>
{/* Markdown detect has problem. */}
{latexContent}
</ReactMarkdown>
)
}