From f1fcba1da0ff04a6c27ad5ca7e19c59b13d875ab Mon Sep 17 00:00:00 2001 From: JOJO <1498581755@qq.com> Date: Mon, 27 Jul 2026 23:58:55 +0800 Subject: [PATCH] =?UTF-8?q?perf(chat):=20=E6=8A=98=E5=8F=A0=E5=9D=97?= =?UTF-8?q?=E8=B7=B3=E8=BF=87=E5=AD=90=E6=A0=91=E6=B8=B2=E6=9F=93=EF=BC=8C?= =?UTF-8?q?=E6=A0=B9=E6=B2=BB=E7=AA=97=E5=8F=A3=E6=8B=96=E6=8B=BD=E5=8D=A1?= =?UTF-8?q?=E9=A1=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 极简模式(0fr)与堆叠/思维链(max-height:0)折叠只裁视觉,DOM 仍全量 参与布局,几千节点的步骤组在窗口拖拽时逐帧重排导致卡顿; 折叠态改为 content-visibility:hidden + contain-intrinsic-size:0 跳过整个子树渲染 - 过渡列表加入 content-visibility + transition-behavior:allow-discrete, 隐藏翻转延迟到收起动画结束后生效,展开立即恢复;不支持的引擎 退化为立即跳过,动画本体不受影响 - 删除 .stacked-block .collapsible-content 冗余 transition 规则: 特异性更高且漏写 content-visibility,曾致收起时内容瞬间消失、 块高瞬间坍塌而外壳慢一拍 - 堆叠块收放改为纯容器裁切、不淡出,与极简模式一致 --- static/src/components/chat/MinimalBlocks.vue | 12 +++++++++ .../styles/components/chat/_chat-area.scss | 25 ++++++++++++++++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/static/src/components/chat/MinimalBlocks.vue b/static/src/components/chat/MinimalBlocks.vue index bf922368..d31bc0ab 100644 --- a/static/src/components/chat/MinimalBlocks.vue +++ b/static/src/components/chat/MinimalBlocks.vue @@ -1216,6 +1216,18 @@ onBeforeUnmount(() => { .steps-wrapper { overflow: hidden; min-height: 0; + /* content-visibility 进过渡列表:收起动画(grid 0.3s)播完才跳过子树渲染, + 展开时立即恢复渲染;不支持的引擎退化为收起时立即跳过 */ + transition: content-visibility 0.3s; + transition-behavior: allow-discrete; +} + +/* 折叠态跳过整个子树渲染:0fr 折叠只裁视觉,DOM 仍全量参与布局, + 几千节点的步骤组会在窗口拖拽时逐帧重排导致卡顿。 + 隐藏翻转由上方过渡延迟到收起动画结束后生效 */ +.steps-container:not(.show) .steps-wrapper { + content-visibility: hidden; + contain-intrinsic-size: 0; } .steps-wrapper.height-limited { diff --git a/static/src/styles/components/chat/_chat-area.scss b/static/src/styles/components/chat/_chat-area.scss index 3ad8647a..71c40260 100644 --- a/static/src/styles/components/chat/_chat-area.scss +++ b/static/src/styles/components/chat/_chat-area.scss @@ -1364,9 +1364,15 @@ body[data-theme='dark'] .collapsible-header:hover { max-height: 0; overflow: hidden; opacity: 0; + /* content-visibility 也进过渡列表:收起动画播完才跳过子树渲染, + 展开时立即恢复渲染(离散属性的方向性插值),收起动画得以完整呈现 */ transition: max-height 260ms cubic-bezier(0.4, 0, 0.2, 1), - opacity 220ms cubic-bezier(0.4, 0, 0.2, 1); + opacity 220ms cubic-bezier(0.4, 0, 0.2, 1), + content-visibility 260ms; + /* 让离散属性可过渡;不支持的引擎忽略此属性,退化为收起时立即跳过渲染, + max-height/opacity 动画本体不受影响 */ + transition-behavior: allow-discrete; /* 始终隐藏滚动条,避免堆叠模式展开时闪现 */ scrollbar-width: none; -ms-overflow-style: none; @@ -1377,6 +1383,15 @@ body[data-theme='dark'] .collapsible-header:hover { display: none; } +/* 折叠态跳过整个子树渲染:max-height:0 只裁视觉,DOM 仍全量参与布局, + 大步骤组/长思维链会在窗口拖拽时逐帧重排导致卡顿。 + 隐藏翻转由上方过渡延迟到收起动画结束后生效;展开时立即恢复渲染, + 由 rAF 测量强制同步布局取真实高度,不受影响。 */ +.collapsible-block:not(.expanded) .collapsible-content { + content-visibility: hidden; + contain-intrinsic-size: 0; +} + .collapsible-block.expanded .collapsible-content { max-height: var(--collapse-max, 600px); overflow-y: auto; @@ -1550,10 +1565,12 @@ body[data-theme='dark'] .more-icon { transition: transform 220ms cubic-bezier(0.4, 0, 0.2, 1); } +/* 堆叠块收起/展开不做淡出:内容保持不透明,由收缩的容器自然裁切(与极简模式一致)。 + 注意:不要再给 .stacked-block .collapsible-content 重声明 transition—— + 它会以更高特异性覆盖 .collapsible-content 基础规则(含 content-visibility 过渡), + 曾因漏写 content-visibility 导致收起时内容瞬间消失、块高瞬间坍塌。 */ .stacked-block .collapsible-content { - transition: - max-height 260ms cubic-bezier(0.4, 0, 0.2, 1), - opacity 220ms cubic-bezier(0.4, 0, 0.2, 1); + opacity: 1; } .progress-indicator {