From 183a8368c45a87d0ece18308b0582aacf21d9e7f Mon Sep 17 00:00:00 2001 From: Kamil Gabryjelski Date: Mon, 5 Aug 2024 17:19:06 +0200 Subject: [PATCH] perf: Lazy load rehype-raw and react-markdown (#29855) --- .../src/components/SafeMarkdown.tsx | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/superset-frontend/packages/superset-ui-core/src/components/SafeMarkdown.tsx b/superset-frontend/packages/superset-ui-core/src/components/SafeMarkdown.tsx index b5ed0d9941ffd..02db7dadbc63e 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/SafeMarkdown.tsx +++ b/superset-frontend/packages/superset-ui-core/src/components/SafeMarkdown.tsx @@ -16,10 +16,8 @@ * specific language governing permissions and limitations * under the License. */ -import { useMemo } from 'react'; -import ReactMarkdown from 'react-markdown'; +import { useEffect, useMemo, useState } from 'react'; import rehypeSanitize, { defaultSchema } from 'rehype-sanitize'; -import rehypeRaw from 'rehype-raw'; import remarkGfm from 'remark-gfm'; import { mergeWith, isArray } from 'lodash'; import { FeatureFlag, isFeatureEnabled } from '../utils'; @@ -45,11 +43,21 @@ function SafeMarkdown({ htmlSchemaOverrides = {}, }: SafeMarkdownProps) { const escapeHtml = isFeatureEnabled(FeatureFlag.EscapeMarkdownHtml); + const [rehypeRawPlugin, setRehypeRawPlugin] = useState(null); + const [ReactMarkdown, setReactMarkdown] = useState(null); + useEffect(() => { + Promise.all([import('rehype-raw'), import('react-markdown')]).then( + ([rehypeRaw, ReactMarkdown]) => { + setRehypeRawPlugin(() => rehypeRaw.default); + setReactMarkdown(() => ReactMarkdown.default); + }, + ); + }, []); const rehypePlugins = useMemo(() => { const rehypePlugins: any = []; - if (!escapeHtml) { - rehypePlugins.push(rehypeRaw); + if (!escapeHtml && rehypeRawPlugin) { + rehypePlugins.push(rehypeRawPlugin); if (htmlSanitization) { const schema = getOverrideHtmlSchema( defaultSchema, @@ -59,7 +67,11 @@ function SafeMarkdown({ } } return rehypePlugins; - }, [escapeHtml, htmlSanitization, htmlSchemaOverrides]); + }, [escapeHtml, htmlSanitization, htmlSchemaOverrides, rehypeRawPlugin]); + + if (!ReactMarkdown || !rehypeRawPlugin) { + return null; + } // React Markdown escapes HTML by default return (