From 09c03d40c953b19194c51db954684de68a809990 Mon Sep 17 00:00:00 2001 From: Ammar Date: Mon, 8 Dec 2025 12:00:47 -0600 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20perf:=20fix=20shimmer=20animatio?= =?UTF-8?q?n=20frame=20drops=20during=20compaction?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use CSS transform animation (compositor thread) instead of background-position (main thread repaint) to avoid frame drops when compaction summary is streaming. The key insight: CSS transform animations run on the compositor thread, completely off the main thread. This is important during streaming when the main thread is busy with React updates and text parsing. Changes: - CompactionBackground: Use translateX transform instead of background-position - Add shimmer-slide keyframes to globals.css - Add StreamingCompaction story to visualize the effect - Add createCompactionRequestMessage helper to mockFactory _Generated with mux_ --- .../Messages/CompactionBackground.tsx | 22 +++++++--- src/browser/stories/App.chat.stories.tsx | 44 +++++++++++++++++++ src/browser/stories/mockFactory.ts | 23 ++++++++++ src/browser/styles/globals.css | 12 ++--- 4 files changed, 88 insertions(+), 13 deletions(-) diff --git a/src/browser/components/Messages/CompactionBackground.tsx b/src/browser/components/Messages/CompactionBackground.tsx index ae3050b03f..ff9153ca4d 100644 --- a/src/browser/components/Messages/CompactionBackground.tsx +++ b/src/browser/components/Messages/CompactionBackground.tsx @@ -1,27 +1,35 @@ import React from "react"; /** - * Animated background for compaction streaming - * Shimmer effect with moving gradient and particles for dynamic appearance + * Animated background for compaction streaming. + * Combines a subtle gradient with a GPU-accelerated shimmer effect. + * + * Uses CSS transform animation (compositor thread) instead of background-position + * (main thread repaint) to avoid frame drops during heavy streaming work. */ - export const CompactionBackground: React.FC = () => { return (
+ {/* Subtle gradient background */}
+ {/* Shimmer uses CSS transform animation - runs on compositor thread, not main thread */} + {/* Math: element is 300% wide, highlight at 50% = 150% from left edge. + marginLeft -180% puts highlight at -30% (off-screen left). + translateX 53.33% (of 300%) = 160%, moving highlight to 130% (off-screen right). */}
diff --git a/src/browser/stories/App.chat.stories.tsx b/src/browser/stories/App.chat.stories.tsx index 0ee0c8550a..b3fbfe402c 100644 --- a/src/browser/stories/App.chat.stories.tsx +++ b/src/browser/stories/App.chat.stories.tsx @@ -7,6 +7,7 @@ import { STABLE_TIMESTAMP, createUserMessage, createAssistantMessage, + createCompactionRequestMessage, createFileReadTool, createFileEditTool, createTerminalTool, @@ -325,3 +326,46 @@ export const GenericTool: AppStory = { }); }, }; + +/** Streaming compaction with shimmer effect - tests GPU-accelerated animation */ +export const StreamingCompaction: AppStory = { + render: () => ( + + setupStreamingChatStory({ + workspaceId: "ws-compaction", + messages: [ + createUserMessage("msg-1", "Help me refactor this codebase", { + historySequence: 1, + timestamp: STABLE_TIMESTAMP - 300000, + }), + createAssistantMessage( + "msg-2", + "I've analyzed the codebase and made several improvements to the architecture.", + { + historySequence: 2, + timestamp: STABLE_TIMESTAMP - 200000, + } + ), + createCompactionRequestMessage("msg-3", { + historySequence: 3, + timestamp: STABLE_TIMESTAMP - 3000, + }), + ], + streamingMessageId: "msg-4", + historySequence: 4, + streamText: + "## Conversation Summary\n\nThe user requested help refactoring the codebase. Key changes made:\n\n- Restructured component hierarchy for better separation of concerns\n- Extracted shared utilities into dedicated modules\n- Improved type safety across API boundaries", + }) + } + /> + ), + parameters: { + docs: { + description: { + story: + "Shows the compaction shimmer effect during streaming. The shimmer uses GPU-accelerated CSS transforms instead of background-position animations to prevent frame drops.", + }, + }, + }, +}; diff --git a/src/browser/stories/mockFactory.ts b/src/browser/stories/mockFactory.ts index 1a99141144..3c36c55b9c 100644 --- a/src/browser/stories/mockFactory.ts +++ b/src/browser/stories/mockFactory.ts @@ -171,6 +171,29 @@ export function createUserMessage( }; } +/** Create a compaction request user message (triggers shimmer effect on streaming response) */ +export function createCompactionRequestMessage( + id: string, + opts: { historySequence: number; timestamp?: number; rawCommand?: string } +): ChatMuxMessage { + const rawCommand = opts.rawCommand ?? "/compact"; + return { + type: "message", + id, + role: "user", + parts: [{ type: "text", text: rawCommand }], + metadata: { + historySequence: opts.historySequence, + timestamp: opts.timestamp ?? STABLE_TIMESTAMP, + muxMetadata: { + type: "compaction-request", + rawCommand, + parsed: {}, + }, + }, + }; +} + export function createAssistantMessage( id: string, text: string, diff --git a/src/browser/styles/globals.css b/src/browser/styles/globals.css index 710513b9b6..ed412722f6 100644 --- a/src/browser/styles/globals.css +++ b/src/browser/styles/globals.css @@ -1655,13 +1655,13 @@ pre code { box-shadow: var(--thumb-shadow, none); } -/* Custom animations for CompactionBackground */ -@keyframes shimmer { - 0% { - background-position: -1000px 0; +/* GPU-accelerated shimmer for CompactionBackground - runs on compositor thread */ +@keyframes shimmer-slide { + from { + transform: translateX(0); } - 100% { - background-position: 1000px 0; + to { + transform: translateX(53.33%); } }