diff --git a/Yi.Ai.Vue3/index.html b/Yi.Ai.Vue3/index.html
index 2e2a4b17..048b0403 100644
--- a/Yi.Ai.Vue3/index.html
+++ b/Yi.Ai.Vue3/index.html
@@ -113,7 +113,7 @@
意心Ai 2.8
-
海外地址,仅首次访问预计加载约10秒
+
海外地址,仅首次访问预计加载约10秒,无需梯子
diff --git a/Yi.Ai.Vue3/src/vue-element-plus-y/components/XMarkdownAsync/index.vue b/Yi.Ai.Vue3/src/vue-element-plus-y/components/XMarkdownAsync/index.vue
deleted file mode 100644
index 1c4e97a4..00000000
--- a/Yi.Ai.Vue3/src/vue-element-plus-y/components/XMarkdownAsync/index.vue
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Yi.Ai.Vue3/src/vue-element-plus-y/components/XMarkdownCore/components/CodeBlock/index.vue b/Yi.Ai.Vue3/src/vue-element-plus-y/components/XMarkdownCore/components/CodeBlock/index.vue
index 96deb20a..68e347b3 100644
--- a/Yi.Ai.Vue3/src/vue-element-plus-y/components/XMarkdownCore/components/CodeBlock/index.vue
+++ b/Yi.Ai.Vue3/src/vue-element-plus-y/components/XMarkdownCore/components/CodeBlock/index.vue
@@ -11,7 +11,8 @@ import {
transformerNotationHighlight,
transformerNotationWordHighlight
} from '@shikijs/transformers';
-import { computed, h, reactive, ref, toValue, watch } from 'vue';
+import { computed, h, reactive, ref, toValue, watch, onUnmounted } from 'vue';
+import { debounce } from 'lodash-es';
import HighLightCode from '../../components/HighLightCode/index.vue';
import { SHIKI_SUPPORT_LANGS, shikiThemeDefault } from '../../shared';
import { useMarkdownContext } from '../MarkdownProvider';
@@ -88,16 +89,29 @@ async function generateHtml() {
}
}
+// 使用防抖优化代码块渲染,避免SSE流式更新时频繁高亮
+const debouncedGenerateHtml = debounce(generateHtml, 100, {
+ leading: false,
+ trailing: true,
+ maxWait: 200
+});
+
watch(
() => props.raw?.content,
async content => {
if (content) {
- await generateHtml();
+ debouncedGenerateHtml();
}
},
{ immediate: true }
);
+// 清理防抖定时器
+onUnmounted(() => {
+ debouncedGenerateHtml.cancel();
+});
+
+
const runCodeOptions = reactive
({
code: [],
content: '',
diff --git a/Yi.Ai.Vue3/src/vue-element-plus-y/components/XMarkdownCore/core/components.ts b/Yi.Ai.Vue3/src/vue-element-plus-y/components/XMarkdownCore/core/components.ts
index a9a04c2c..2c80cb3a 100644
--- a/Yi.Ai.Vue3/src/vue-element-plus-y/components/XMarkdownCore/core/components.ts
+++ b/Yi.Ai.Vue3/src/vue-element-plus-y/components/XMarkdownCore/core/components.ts
@@ -4,10 +4,11 @@ import type { PluggableList } from 'unified';
import type { PropType } from 'vue';
import type { CustomAttrs, SanitizeOptions, TVueMarkdown } from './types';
-import { defineComponent, shallowRef, toRefs, watch } from 'vue';
+import { defineComponent, shallowRef, toRefs, watch, onUnmounted } from 'vue';
// import { useMarkdownContext } from '../components/MarkdownProvider';
import { render } from './hast-to-vnode';
import { useMarkdownProcessor } from './useProcessor';
+import { debounce } from 'lodash-es';
export type { CustomAttrs, SanitizeOptions, TVueMarkdown };
@@ -93,12 +94,42 @@ const vueMarkdownAsyncImpl = defineComponent({
});
const hast = shallowRef(null);
+ const isProcessing = shallowRef(false);
+
const process = async (): Promise => {
- const mdast = processor.value.parse(markdown.value);
- hast.value = (await processor.value.run(mdast)) as Root;
+ // 避免重复处理
+ if (isProcessing.value) return;
+ isProcessing.value = true;
+
+ try {
+ const mdast = processor.value.parse(markdown.value);
+ hast.value = (await processor.value.run(mdast)) as Root;
+ } finally {
+ isProcessing.value = false;
+ }
};
- watch(() => [markdown.value, processor.value], process, { flush: 'sync' });
+ // 使用防抖优化SSE流式更新场景
+ // trailing: true 确保最后一次更新会执行
+ // leading: false 避免首次触发两次渲染
+ const debouncedProcess = debounce(process, 50, {
+ leading: false,
+ trailing: true,
+ maxWait: 200 // 最长等待200ms,避免延迟过大
+ });
+
+ watch(
+ () => [markdown.value, processor.value],
+ () => {
+ debouncedProcess();
+ },
+ { flush: 'post' } // 改为post,在DOM更新后执行,避免阻塞UI
+ );
+
+ // 清理防抖定时器
+ onUnmounted(() => {
+ debouncedProcess.cancel();
+ });
await process();