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
@@ -26,6 +26,8 @@ interface Props {
chartCandleAreaPriceLabels?: boolean;
chartSeriesPriceLabels?: boolean;
chartPaneSeparator?: import('../../types/chartPaneSeparator').ChartPaneSeparatorOptions;
/** false — 뷰포트 밖: STOMP·히스토리 중지 (기본 true) */
chartStreamEnabled?: boolean;
}
const noop = () => {};
@@ -46,6 +48,7 @@ const TrendSearchCardChart: React.FC<Props> = ({
chartCandleAreaPriceLabels = true,
chartSeriesPriceLabels = true,
chartPaneSeparator,
chartStreamEnabled = true,
}) => {
const chartTf = toChartTimeframe(timeframe);
const { getParams, getVisualConfig } = useIndicatorSettings();
@@ -90,6 +93,7 @@ const TrendSearchCardChart: React.FC<Props> = ({
const handleNewCandle = useCallback((bar: OHLCVBar) => applyRealtimeBar(bar, true), [applyRealtimeBar]);
const useUpbit = isUpbitMarket(market);
const streamActive = useUpbit && chartStreamEnabled;
const { bars, barsMarket, isLoading } = useChartRealtimeData(
market,
@@ -97,15 +101,15 @@ const TrendSearchCardChart: React.FC<Props> = ({
useMemo(() => ({
onTickUpdate: handleTickUpdate,
onNewCandle: handleNewCandle,
enabled: useUpbit,
enabled: streamActive,
source: chartRealtimeSource,
}), [handleTickUpdate, handleNewCandle, useUpbit, chartRealtimeSource]),
}), [handleTickUpdate, handleNewCandle, streamActive, chartRealtimeSource]),
);
const { isLoadingMore } = useHistoryLoader({
symbol: market,
timeframe: chartTf,
isUpbit: useUpbit,
isUpbit: streamActive,
managerRef,
});
@@ -151,9 +155,9 @@ const TrendSearchCardChart: React.FC<Props> = ({
}, [market, chartTf, bars.length]);
useEffect(() => {
if (!useUpbit) return;
if (!streamActive) return;
void pinCandleWatch(market, timeframeToCandleType(chartTf));
}, [market, chartTf, useUpbit]);
}, [market, chartTf, streamActive]);
return (
<div className="vtd-card-chart-panel vtd-card-chart-panel--fill">
@@ -170,6 +174,7 @@ const TrendSearchCardChart: React.FC<Props> = ({
)}
<TradingChart
key={`${market}-${chartTf}-${chartReloadTick}`}
chartVisible={chartStreamEnabled}
bars={bars}
barsMarket={barsMarket}
market={market}
@@ -5,6 +5,7 @@ import { tfLabelShort } from '../../utils/trendSearchMetrics';
import type { Theme } from '../../types';
import type { ChartRealtimeSource } from '../../hooks/useChartRealtimeData';
import type { TickerData } from '../../hooks/useMarketTicker';
import { useIntersectionVisible } from '../../hooks/useIntersectionVisible';
import VirtualTargetQuote from '../virtual/VirtualTargetQuote';
import VirtualLiveBadge from '../virtual/VirtualLiveBadge';
import TrendSearchCardSignalPanel from './TrendSearchCardSignalPanel';
@@ -75,6 +76,8 @@ const TrendSearchResultCard: React.FC<Props> = ({
const quoteTicker = ticker ?? resultToTicker(result);
const ko = quoteTicker.koreanName || getKoreanName(result.market) || en;
const isChart = displayMode === 'chart';
const { ref: cardRef, visible: cardInView } = useIntersectionVisible();
const chartStreamEnabled = isChart && cardInView;
const flashCls = useMemo(() => {
if (!flash) return '';
@@ -83,6 +86,7 @@ const TrendSearchResultCard: React.FC<Props> = ({
return (
<div
ref={cardRef}
className={[
'vtd-card',
'vtd-card--signal',
@@ -145,6 +149,7 @@ const TrendSearchResultCard: React.FC<Props> = ({
chartCandleAreaPriceLabels={chartCandleAreaPriceLabels}
chartSeriesPriceLabels={chartSeriesPriceLabels}
chartPaneSeparator={chartPaneSeparator}
chartStreamEnabled={chartStreamEnabled}
/>
) : (
<TrendSearchCardSignalPanel