frontend 성능 개선

This commit is contained in:
Macbook
2026-06-08 15:25:44 +09:00
parent a84a11e21c
commit 011059f5ed
14 changed files with 258 additions and 37 deletions
@@ -1,7 +1,7 @@
/**
* 매매 시그널 알림 목록 행 — 4칸이 목록 너비를 꽉 채움, 보조지표 2개↑ 시 우측 슬롯만 스크롤
*/
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import React, { useCallback, useEffect, useMemo, useRef, useState, memo } from 'react';
import type { Theme } from '../../types';
import type { TickerData } from '../../hooks/useMarketTicker';
import { useLiveReceiveFlash } from '../../hooks/useLiveReceiveFlash';
@@ -59,7 +59,8 @@ interface Props {
layoutMode?: TradeNotificationRowLayout;
chartsEnabled?: boolean;
chartLiveReceiveHighlight?: boolean;
tickers?: Map<string, TickerData>;
/** 해당 종목 시세 (전체 tickers Map 대신 행 단위 전달 — memo·리렌더 최소화) */
ticker?: TickerData;
onSelect: () => void;
onDelete: (e: React.MouseEvent) => void;
onDetail: () => void;
@@ -84,7 +85,7 @@ const TradeNotificationListRow: React.FC<Props> = ({
layoutMode = 'list',
chartsEnabled = true,
chartLiveReceiveHighlight = true,
tickers,
ticker,
onSelect,
onDelete,
onDetail,
@@ -185,7 +186,6 @@ const TradeNotificationListRow: React.FC<Props> = ({
const chartExpanded = isListLayout && expandedChartKey != null;
const chartActive = isListLayout && chartsEnabled && panelActive;
const signalCardEnabled = isListLayout && panelActive && !chartExpanded;
const ticker = tickers?.get(marketCode) ?? tickers?.get(item.market);
const expandedIndicator = indicatorCards.find(c => c.id === expandedChartKey);
const signalSnapshotEnabled = item.strategyId != null && (
@@ -488,4 +488,35 @@ const TradeNotificationListRow: React.FC<Props> = ({
);
};
export default TradeNotificationListRow;
function listRowPropsEqual(prev: Props, next: Props): boolean {
if (prev.item !== next.item) {
if (
prev.item.id !== next.item.id
|| prev.item.isRead !== next.item.isRead
|| prev.item.receivedAt !== next.item.receivedAt
|| prev.item.strategyId !== next.item.strategyId
|| prev.item.strategyName !== next.item.strategyName
) return false;
}
return (
prev.theme === next.theme
&& prev.isSelected === next.isSelected
&& prev.layoutMode === next.layoutMode
&& prev.chartsEnabled === next.chartsEnabled
&& prev.chartLiveReceiveHighlight === next.chartLiveReceiveHighlight
&& prev.reportLoading === next.reportLoading
&& prev.itemTag === next.itemTag
&& prev.prefetchedStrategies === next.prefetchedStrategies
&& prev.ticker?.tradePrice === next.ticker?.tradePrice
&& prev.ticker?.changeRate === next.ticker?.changeRate
&& prev.ticker?.accTradePrice24 === next.ticker?.accTradePrice24
&& prev.onSelect === next.onSelect
&& prev.onDelete === next.onDelete
&& prev.onDetail === next.onDetail
&& prev.onGoToChart === next.onGoToChart
&& prev.onTrade === next.onTrade
&& prev.onReport === next.onReport
);
}
export default memo(TradeNotificationListRow, listRowPropsEqual);