- 실행 중 경량 라이브 진행 모드에서 메시지 진입 애니메이션과 진행 마커 펄스를 줄여 UI 스레드 부담을 더 낮춤 - AX Agent 라이브 카드의 등장·퇴장 애니메이션과 아이콘 opacity 펄스도 경량 모드에서는 생략하도록 조정함 - README와 DEVELOPMENT 문서를 2026-04-08 12:40 (KST) 기준으로 갱신함 - 검증: dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\ (경고 0, 오류 0)
This commit is contained in:
@@ -1511,3 +1511,8 @@ MIT License
|
|||||||
- `claw-code`의 가상화 메시지 리스트에 바로 가기 전 단계로, AX transcript에 `실행 중 렌더 윈도우 축소`를 적용했습니다. 코워크/코드 스트리밍 중에는 최근 항목 위주로 더 작은 타임라인만 렌더하고, 평상시에는 기존 범위를 유지합니다.
|
- `claw-code`의 가상화 메시지 리스트에 바로 가기 전 단계로, AX transcript에 `실행 중 렌더 윈도우 축소`를 적용했습니다. 코워크/코드 스트리밍 중에는 최근 항목 위주로 더 작은 타임라인만 렌더하고, 평상시에는 기존 범위를 유지합니다.
|
||||||
- [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)에 `GetActiveTimelineRenderLimit()`를 추가해, 일반 스트리밍은 96개, 경량 라이브 진행 모드는 60개만 렌더하도록 조정했습니다.
|
- [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)에 `GetActiveTimelineRenderLimit()`를 추가해, 일반 스트리밍은 96개, 경량 라이브 진행 모드는 60개만 렌더하도록 조정했습니다.
|
||||||
- `ScheduleExecutionHistoryRender`, `ScheduleAgentUiEvent`, `ScheduleTaskSummaryRefresh`, `ScheduleInputUiRefresh`도 경량 모드에서는 이미 타이머가 대기 중일 때 다시 stop/start 하지 않게 바꿔, 이벤트 폭주 시 dispatcher 예약 churn을 줄였습니다.
|
- `ScheduleExecutionHistoryRender`, `ScheduleAgentUiEvent`, `ScheduleTaskSummaryRefresh`, `ScheduleInputUiRefresh`도 경량 모드에서는 이미 타이머가 대기 중일 때 다시 stop/start 하지 않게 바꿔, 이벤트 폭주 시 dispatcher 예약 churn을 줄였습니다.
|
||||||
|
- 업데이트: 2026-04-08 12:40 (KST)
|
||||||
|
- 코워크/코드 경량 라이브 진행 모드에서는 메시지 진입 애니메이션과 진행 마커 펄스도 줄였습니다.
|
||||||
|
- [ChatWindow.MessageInteractions.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.MessageInteractions.cs)의 메시지 엔트리 애니메이션은 실행 중 경량 모드에서 즉시 표시로 바뀌어, 새 UI 요소가 들어올 때마다 opacity/translate 애니메이션이 누적되지 않게 했습니다.
|
||||||
|
- [ChatWindow.AgentEventRendering.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.AgentEventRendering.cs)의 진행 마커 펄스는 경량 모드에서 정적 점 상태로 간소화했습니다.
|
||||||
|
- [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)의 AX Agent 라이브 카드도 경량 모드에서는 등장/퇴장 애니메이션과 아이콘 opacity 펄스를 줄여, 실행 중 레이아웃/애니메이션 비용을 더 낮췄습니다.
|
||||||
|
|||||||
@@ -5465,3 +5465,16 @@ ow + toggle ?쒓컖 ?몄뼱濡??ㅼ떆 ?뺣젹?덈떎.
|
|||||||
- 코워크/코드 실행 중 transcript 재구성 대상 수 자체 감소
|
- 코워크/코드 실행 중 transcript 재구성 대상 수 자체 감소
|
||||||
- 高频 이벤트 환경에서 dispatcher timer 재예약 churn 감소
|
- 高频 이벤트 환경에서 dispatcher timer 재예약 churn 감소
|
||||||
- `claw-code`의 virtualized list 이전 단계로서 실행 중 체감 부하를 더 낮춤
|
- `claw-code`의 virtualized list 이전 단계로서 실행 중 체감 부하를 더 낮춤
|
||||||
|
|
||||||
|
## 2026-04-08 12:40 (KST)
|
||||||
|
|
||||||
|
- [ChatWindow.MessageInteractions.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.MessageInteractions.cs)
|
||||||
|
- `ApplyMessageEntryAnimation(...)`를 인스턴스 메서드로 전환하고, `스트리밍 + 경량 라이브 진행 모드`에서는 opacity/translate 애니메이션 없이 즉시 표시되도록 바꿨다.
|
||||||
|
- [ChatWindow.AgentEventRendering.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.AgentEventRendering.cs)
|
||||||
|
- `ApplyLiveWaitingPulseToMarker(...)`를 인스턴스 메서드로 바꾸고, 경량 모드에서는 펄스 애니메이션 대신 정적 마커만 남기도록 조정했다.
|
||||||
|
- [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)
|
||||||
|
- AX Agent 라이브 카드의 등장/퇴장 애니메이션과 헤더 아이콘 opacity 펄스를 경량 모드에서는 생략하도록 변경했다.
|
||||||
|
- 기대 효과
|
||||||
|
- 코워크/코드 실행 중 누적 애니메이션 수 감소
|
||||||
|
- 긴 세션에서 opacity/translate/scale animation이 UI 스레드에 주는 부담 완화
|
||||||
|
- 진행 카드는 유지하되 시각 효과 비용은 더 낮춘 상태로 동작
|
||||||
|
|||||||
@@ -568,8 +568,15 @@ public partial class ChatWindow
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ApplyLiveWaitingPulseToMarker(Border marker)
|
private void ApplyLiveWaitingPulseToMarker(Border marker)
|
||||||
{
|
{
|
||||||
|
if (_isStreaming && IsLightweightLiveProgressMode())
|
||||||
|
{
|
||||||
|
marker.Opacity = 0.92;
|
||||||
|
marker.RenderTransform = Transform.Identity;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
marker.RenderTransformOrigin = new Point(0.5, 0.5);
|
marker.RenderTransformOrigin = new Point(0.5, 0.5);
|
||||||
marker.RenderTransform = new ScaleTransform(1, 1);
|
marker.RenderTransform = new ScaleTransform(1, 1);
|
||||||
|
|
||||||
|
|||||||
@@ -272,8 +272,15 @@ public partial class ChatWindow
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ApplyMessageEntryAnimation(FrameworkElement element)
|
private void ApplyMessageEntryAnimation(FrameworkElement element)
|
||||||
{
|
{
|
||||||
|
if (_isStreaming && IsLightweightLiveProgressMode())
|
||||||
|
{
|
||||||
|
element.Opacity = 1;
|
||||||
|
element.RenderTransform = Transform.Identity;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
element.Opacity = 0;
|
element.Opacity = 0;
|
||||||
element.RenderTransform = new TranslateTransform(0, 16);
|
element.RenderTransform = new TranslateTransform(0, 16);
|
||||||
element.BeginAnimation(UIElement.OpacityProperty,
|
element.BeginAnimation(UIElement.OpacityProperty,
|
||||||
|
|||||||
@@ -7039,9 +7039,13 @@ public partial class ChatWindow : Window
|
|||||||
Width = msgMaxWidth,
|
Width = msgMaxWidth,
|
||||||
MaxWidth = msgMaxWidth,
|
MaxWidth = msgMaxWidth,
|
||||||
Margin = new Thickness(0, 4, 0, 6),
|
Margin = new Thickness(0, 4, 0, 6),
|
||||||
Opacity = 0,
|
Opacity = IsLightweightLiveProgressMode(runTab) ? 1 : 0,
|
||||||
RenderTransform = new TranslateTransform(0, 8),
|
RenderTransform = IsLightweightLiveProgressMode(runTab)
|
||||||
|
? Transform.Identity
|
||||||
|
: new TranslateTransform(0, 8),
|
||||||
};
|
};
|
||||||
|
if (!IsLightweightLiveProgressMode(runTab))
|
||||||
|
{
|
||||||
container.BeginAnimation(UIElement.OpacityProperty,
|
container.BeginAnimation(UIElement.OpacityProperty,
|
||||||
new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(260)));
|
new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(260)));
|
||||||
((TranslateTransform)container.RenderTransform).BeginAnimation(
|
((TranslateTransform)container.RenderTransform).BeginAnimation(
|
||||||
@@ -7049,6 +7053,7 @@ public partial class ChatWindow : Window
|
|||||||
new DoubleAnimation(8, 0, TimeSpan.FromMilliseconds(280))
|
new DoubleAnimation(8, 0, TimeSpan.FromMilliseconds(280))
|
||||||
{ EasingFunction = new System.Windows.Media.Animation.QuadraticEase
|
{ EasingFunction = new System.Windows.Media.Animation.QuadraticEase
|
||||||
{ EasingMode = System.Windows.Media.Animation.EasingMode.EaseOut } });
|
{ EasingMode = System.Windows.Media.Animation.EasingMode.EaseOut } });
|
||||||
|
}
|
||||||
|
|
||||||
// 헤더: 펄싱 아이콘 + 에이전트 이름 + 경과 시간
|
// 헤더: 펄싱 아이콘 + 에이전트 이름 + 경과 시간
|
||||||
var headerGrid = new Grid { Margin = new Thickness(2, 0, 0, 3) };
|
var headerGrid = new Grid { Margin = new Thickness(2, 0, 0, 3) };
|
||||||
@@ -7057,10 +7062,13 @@ public partial class ChatWindow : Window
|
|||||||
headerGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
|
headerGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
|
||||||
|
|
||||||
var liveIcon = CreateMiniLauncherIcon(pixelSize: 4.0);
|
var liveIcon = CreateMiniLauncherIcon(pixelSize: 4.0);
|
||||||
|
if (!IsLightweightLiveProgressMode(runTab))
|
||||||
|
{
|
||||||
liveIcon.BeginAnimation(UIElement.OpacityProperty,
|
liveIcon.BeginAnimation(UIElement.OpacityProperty,
|
||||||
new DoubleAnimation(1.0, 0.35, TimeSpan.FromMilliseconds(750))
|
new DoubleAnimation(1.0, 0.35, TimeSpan.FromMilliseconds(750))
|
||||||
{ AutoReverse = true, RepeatBehavior = System.Windows.Media.Animation.RepeatBehavior.Forever,
|
{ AutoReverse = true, RepeatBehavior = System.Windows.Media.Animation.RepeatBehavior.Forever,
|
||||||
EasingFunction = new System.Windows.Media.Animation.SineEase() });
|
EasingFunction = new System.Windows.Media.Animation.SineEase() });
|
||||||
|
}
|
||||||
Grid.SetColumn(liveIcon, 0);
|
Grid.SetColumn(liveIcon, 0);
|
||||||
headerGrid.Children.Add(liveIcon);
|
headerGrid.Children.Add(liveIcon);
|
||||||
|
|
||||||
@@ -7191,7 +7199,7 @@ public partial class ChatWindow : Window
|
|||||||
_agentLiveSubItemTexts.Clear();
|
_agentLiveSubItemTexts.Clear();
|
||||||
_agentLiveCurrentCategory = null;
|
_agentLiveCurrentCategory = null;
|
||||||
|
|
||||||
if (animated && MessagePanel != null && MessagePanel.Children.Contains(toRemove))
|
if (animated && MessagePanel != null && MessagePanel.Children.Contains(toRemove) && !IsLightweightLiveProgressMode())
|
||||||
{
|
{
|
||||||
var anim = new DoubleAnimation(toRemove.Opacity, 0, TimeSpan.FromMilliseconds(160));
|
var anim = new DoubleAnimation(toRemove.Opacity, 0, TimeSpan.FromMilliseconds(160));
|
||||||
anim.Completed += (_, _) => MessagePanel?.Children.Remove(toRemove);
|
anim.Completed += (_, _) => MessagePanel?.Children.Remove(toRemove);
|
||||||
|
|||||||
Reference in New Issue
Block a user